~vcs-imports/xena/trunk

« back to all changes in this revision

Viewing changes to ext/src/xerces-2_9_1/src/org/apache/xerces/impl/dv/xs/XSSimpleTypeDecl.java

  • Committer: matthewoliver
  • Date: 2009-12-10 03:18:07 UTC
  • Revision ID: vcs-imports@canonical.com-20091210031807-l086qguzdlljtkl9
Merged Xena Testing into Xena Stable for the Xena 5 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
 
3
 * contributor license agreements.  See the NOTICE file distributed with
 
4
 * this work for additional information regarding copyright ownership.
 
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
6
 * (the "License"); you may not use this file except in compliance with
 
7
 * the License.  You may obtain a copy of the License at
 
8
 *
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
11
 * Unless required by applicable law or agreed to in writing, software
 
12
 * distributed under the License is distributed on an "AS IS" BASIS,
 
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
14
 * See the License for the specific language governing permissions and
 
15
 * limitations under the License.
 
16
 */
 
17
 
 
18
package org.apache.xerces.impl.dv.xs;
 
19
 
 
20
import java.util.StringTokenizer;
 
21
import java.util.Vector;
 
22
 
 
23
import org.apache.xerces.impl.Constants;
 
24
import org.apache.xerces.impl.dv.DatatypeException;
 
25
import org.apache.xerces.impl.dv.InvalidDatatypeFacetException;
 
26
import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
 
27
import org.apache.xerces.impl.dv.ValidatedInfo;
 
28
import org.apache.xerces.impl.dv.ValidationContext;
 
29
import org.apache.xerces.impl.dv.XSFacets;
 
30
import org.apache.xerces.impl.dv.XSSimpleType;
 
31
import org.apache.xerces.impl.xpath.regex.RegularExpression;
 
32
import org.apache.xerces.impl.xs.SchemaSymbols;
 
33
import org.apache.xerces.impl.xs.util.ShortListImpl;
 
34
import org.apache.xerces.impl.xs.util.StringListImpl;
 
35
import org.apache.xerces.impl.xs.util.XSObjectListImpl;
 
36
import org.apache.xerces.util.XMLChar;
 
37
import org.apache.xerces.xni.NamespaceContext;
 
38
import org.apache.xerces.xs.ShortList;
 
39
import org.apache.xerces.xs.StringList;
 
40
import org.apache.xerces.xs.XSAnnotation;
 
41
import org.apache.xerces.xs.XSConstants;
 
42
import org.apache.xerces.xs.XSFacet;
 
43
import org.apache.xerces.xs.XSMultiValueFacet;
 
44
import org.apache.xerces.xs.XSNamespaceItem;
 
45
import org.apache.xerces.xs.XSObjectList;
 
46
import org.apache.xerces.xs.XSSimpleTypeDefinition;
 
47
import org.apache.xerces.xs.XSTypeDefinition;
 
48
import org.apache.xerces.xs.datatypes.ObjectList;
 
49
import org.w3c.dom.TypeInfo;
 
50
 
 
51
/**
 
52
 * @xerces.internal
 
53
 *  
 
54
 * @author Sandy Gao, IBM
 
55
 * @author Neeraj Bajaj, Sun Microsystems, inc.
 
56
 *
 
57
 * @version $Id: XSSimpleTypeDecl.java,v 1.2 2009/12/10 03:18:21 matthewoliver Exp $
 
58
 */
 
59
public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo {
 
60
 
 
61
    static final short DV_STRING        = PRIMITIVE_STRING;
 
62
    static final short DV_BOOLEAN       = PRIMITIVE_BOOLEAN;
 
63
    static final short DV_DECIMAL       = PRIMITIVE_DECIMAL;
 
64
    static final short DV_FLOAT         = PRIMITIVE_FLOAT;
 
65
    static final short DV_DOUBLE        = PRIMITIVE_DOUBLE;
 
66
    static final short DV_DURATION      = PRIMITIVE_DURATION;
 
67
    static final short DV_DATETIME      = PRIMITIVE_DATETIME;
 
68
    static final short DV_TIME          = PRIMITIVE_TIME;
 
69
    static final short DV_DATE          = PRIMITIVE_DATE;
 
70
    static final short DV_GYEARMONTH    = PRIMITIVE_GYEARMONTH;
 
71
    static final short DV_GYEAR         = PRIMITIVE_GYEAR;
 
72
    static final short DV_GMONTHDAY     = PRIMITIVE_GMONTHDAY;
 
73
    static final short DV_GDAY          = PRIMITIVE_GDAY;
 
74
    static final short DV_GMONTH        = PRIMITIVE_GMONTH;
 
75
    static final short DV_HEXBINARY     = PRIMITIVE_HEXBINARY;
 
76
    static final short DV_BASE64BINARY  = PRIMITIVE_BASE64BINARY;
 
77
    static final short DV_ANYURI        = PRIMITIVE_ANYURI;
 
78
    static final short DV_QNAME         = PRIMITIVE_QNAME;
 
79
    static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL;
 
80
    static final short DV_NOTATION      = PRIMITIVE_NOTATION;
 
81
 
 
82
    static final short DV_ANYSIMPLETYPE = 0;
 
83
    static final short DV_ID            = DV_NOTATION + 1;
 
84
    static final short DV_IDREF         = DV_NOTATION + 2;
 
85
    static final short DV_ENTITY        = DV_NOTATION + 3;
 
86
    static final short DV_INTEGER       = DV_NOTATION + 4;
 
87
    static final short DV_LIST          = DV_NOTATION + 5;
 
88
    static final short DV_UNION         = DV_NOTATION + 6;
 
89
    static final short DV_YEARMONTHDURATION = DV_NOTATION + 7;
 
90
    static final short DV_DAYTIMEDURATION       = DV_NOTATION + 8;
 
91
    static final short DV_ANYATOMICTYPE = DV_NOTATION + 9;
 
92
 
 
93
    static final TypeValidator[] fDVs = {
 
94
        new AnySimpleDV(),
 
95
        new StringDV(),
 
96
        new BooleanDV(),
 
97
        new DecimalDV(),
 
98
        new FloatDV(),
 
99
        new DoubleDV(),
 
100
        new DurationDV(),
 
101
        new DateTimeDV(),
 
102
        new TimeDV(),
 
103
        new DateDV(),
 
104
        new YearMonthDV(),
 
105
        new YearDV(),
 
106
        new MonthDayDV(),
 
107
        new DayDV(),
 
108
        new MonthDV(),
 
109
        new HexBinaryDV(),
 
110
        new Base64BinaryDV(),
 
111
        new AnyURIDV(),
 
112
        new QNameDV(),
 
113
        new PrecisionDecimalDV(), // XML Schema 1.1 type
 
114
        new QNameDV(),   // notation use the same one as qname
 
115
        new IDDV(),
 
116
        new IDREFDV(),
 
117
        new EntityDV(),
 
118
        new IntegerDV(),
 
119
        new ListDV(),
 
120
        new UnionDV(),
 
121
        new YearMonthDurationDV(), // XML Schema 1.1 type
 
122
        new DayTimeDurationDV(), // XML Schema 1.1 type
 
123
        new AnyAtomicDV() // XML Schema 1.1 type
 
124
    };
 
125
 
 
126
    static final short NORMALIZE_NONE = 0;
 
127
    static final short NORMALIZE_TRIM = 1;
 
128
    static final short NORMALIZE_FULL = 2;
 
129
    static final short[] fDVNormalizeType = {
 
130
        NORMALIZE_NONE, //AnySimpleDV(),
 
131
        NORMALIZE_FULL, //StringDV(),
 
132
        NORMALIZE_TRIM, //BooleanDV(),
 
133
        NORMALIZE_TRIM, //DecimalDV(),
 
134
        NORMALIZE_TRIM, //FloatDV(),
 
135
        NORMALIZE_TRIM, //DoubleDV(),
 
136
        NORMALIZE_TRIM, //DurationDV(),
 
137
        NORMALIZE_TRIM, //DateTimeDV(),
 
138
        NORMALIZE_TRIM, //TimeDV(),
 
139
        NORMALIZE_TRIM, //DateDV(),
 
140
        NORMALIZE_TRIM, //YearMonthDV(),
 
141
        NORMALIZE_TRIM, //YearDV(),
 
142
        NORMALIZE_TRIM, //MonthDayDV(),
 
143
        NORMALIZE_TRIM, //DayDV(),
 
144
        NORMALIZE_TRIM, //MonthDV(),
 
145
        NORMALIZE_TRIM, //HexBinaryDV(),
 
146
        NORMALIZE_NONE, //Base64BinaryDV(),  // Base64 know how to deal with spaces
 
147
        NORMALIZE_TRIM, //AnyURIDV(),
 
148
        NORMALIZE_TRIM, //QNameDV(),
 
149
        NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1)
 
150
        NORMALIZE_TRIM, //QNameDV(),   // notation
 
151
        NORMALIZE_TRIM, //IDDV(),
 
152
        NORMALIZE_TRIM, //IDREFDV(),
 
153
        NORMALIZE_TRIM, //EntityDV(),
 
154
        NORMALIZE_TRIM, //IntegerDV(),
 
155
        NORMALIZE_FULL, //ListDV(),
 
156
        NORMALIZE_NONE, //UnionDV(),
 
157
        NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1)
 
158
        NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1)
 
159
        NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1)
 
160
    };
 
161
 
 
162
    static final short SPECIAL_PATTERN_NONE     = 0;
 
163
    static final short SPECIAL_PATTERN_NMTOKEN  = 1;
 
164
    static final short SPECIAL_PATTERN_NAME     = 2;
 
165
    static final short SPECIAL_PATTERN_NCNAME   = 3;
 
166
 
 
167
    static final String[] SPECIAL_PATTERN_STRING   = {
 
168
        "NONE", "NMTOKEN", "Name", "NCName"
 
169
    };
 
170
 
 
171
    static final String[] WS_FACET_STRING = {
 
172
        "preserve", "replace", "collapse"
 
173
    };
 
174
 
 
175
    static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema";
 
176
    static final String ANY_TYPE = "anyType";
 
177
 
 
178
    // XML Schema 1.1 type constants
 
179
    public static final short YEARMONTHDURATION_DT      = 46;
 
180
    public static final short DAYTIMEDURATION_DT        = 47;   
 
181
    public static final short PRECISIONDECIMAL_DT       = 48;
 
182
    public static final short ANYATOMICTYPE_DT          = 49;
 
183
 
 
184
    // DOM Level 3 TypeInfo Derivation Method constants
 
185
    static final int DERIVATION_ANY = 0;
 
186
    static final int DERIVATION_RESTRICTION = 1;
 
187
    static final int DERIVATION_EXTENSION = 2;
 
188
    static final int DERIVATION_UNION = 4;
 
189
    static final int DERIVATION_LIST = 8;
 
190
 
 
191
    static final ValidationContext fEmptyContext = new ValidationContext() {
 
192
        public boolean needFacetChecking() {
 
193
            return true;
 
194
        }
 
195
        public boolean needExtraChecking() {
 
196
            return false;
 
197
        }
 
198
        public boolean needToNormalize() {
 
199
            return true;
 
200
        }
 
201
        public boolean useNamespaces () {
 
202
            return true;
 
203
        }
 
204
        public boolean isEntityDeclared (String name) {
 
205
            return false;
 
206
        }
 
207
        public boolean isEntityUnparsed (String name) {
 
208
            return false;
 
209
        }
 
210
        public boolean isIdDeclared (String name) {
 
211
            return false;
 
212
        }
 
213
        public void addId(String name) {
 
214
        }
 
215
        public void addIdRef(String name) {
 
216
        }
 
217
        public String getSymbol (String symbol) {
 
218
            return symbol.intern();
 
219
        }
 
220
        public String getURI(String prefix) {
 
221
            return null;
 
222
        }
 
223
    };
 
224
 
 
225
    // this will be true if this is a static XSSimpleTypeDecl
 
226
    // and hence must remain immutable (i.e., applyFacets
 
227
    // may not be permitted to have any effect).
 
228
    private boolean fIsImmutable = false;
 
229
 
 
230
    private XSSimpleTypeDecl fItemType;
 
231
    private XSSimpleTypeDecl[] fMemberTypes;
 
232
    // The most specific built-in type kind.
 
233
    private short fBuiltInKind;
 
234
 
 
235
    private String fTypeName;
 
236
    private String fTargetNamespace;
 
237
    private short fFinalSet = 0;
 
238
    private XSSimpleTypeDecl fBase;
 
239
    private short fVariety = -1;
 
240
    private short fValidationDV = -1;
 
241
 
 
242
    private short fFacetsDefined = 0;
 
243
    private short fFixedFacet = 0;
 
244
 
 
245
    //for constraining facets
 
246
    private short fWhiteSpace = 0;
 
247
    private int fLength = -1;
 
248
    private int fMinLength = -1;
 
249
    private int fMaxLength = -1;
 
250
    private int fTotalDigits = -1;
 
251
    private int fFractionDigits = -1;
 
252
    private Vector fPattern;
 
253
    private Vector fPatternStr;
 
254
    private Vector fEnumeration;
 
255
    private short[] fEnumerationType;
 
256
    private ShortList[] fEnumerationItemType;   // used in case fenumerationType value is LIST or LISTOFUNION 
 
257
    private ShortList fEnumerationTypeList;
 
258
    private ObjectList fEnumerationItemTypeList;
 
259
    private StringList fLexicalPattern;
 
260
    private StringList fLexicalEnumeration;
 
261
    private ObjectList fActualEnumeration;
 
262
    private Object fMaxInclusive;
 
263
    private Object fMaxExclusive;
 
264
    private Object fMinExclusive;
 
265
    private Object fMinInclusive;
 
266
 
 
267
    // annotations for constraining facets
 
268
    public XSAnnotation lengthAnnotation;
 
269
    public XSAnnotation minLengthAnnotation;
 
270
    public XSAnnotation maxLengthAnnotation;
 
271
    public XSAnnotation whiteSpaceAnnotation;
 
272
    public XSAnnotation totalDigitsAnnotation;
 
273
    public XSAnnotation fractionDigitsAnnotation;
 
274
    public XSObjectListImpl patternAnnotations;
 
275
    public XSObjectList enumerationAnnotations;
 
276
    public XSAnnotation maxInclusiveAnnotation;
 
277
    public XSAnnotation maxExclusiveAnnotation;
 
278
    public XSAnnotation minInclusiveAnnotation;
 
279
    public XSAnnotation minExclusiveAnnotation;
 
280
 
 
281
    // facets as objects
 
282
    private XSObjectListImpl fFacets;
 
283
 
 
284
    // enumeration and pattern facets
 
285
    private XSObjectListImpl fMultiValueFacets;
 
286
 
 
287
    // simpleType annotations
 
288
    private XSObjectList fAnnotations = null;
 
289
 
 
290
    private short fPatternType = SPECIAL_PATTERN_NONE;
 
291
 
 
292
    // for fundamental facets
 
293
    private short fOrdered;
 
294
    private boolean fFinite;
 
295
    private boolean fBounded;
 
296
    private boolean fNumeric;
 
297
 
 
298
    // default constructor
 
299
    public XSSimpleTypeDecl(){}
 
300
 
 
301
    //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration)
 
302
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, short validateDV,
 
303
            short ordered, boolean bounded, boolean finite,
 
304
            boolean numeric, boolean isImmutable, short builtInKind) {
 
305
        fIsImmutable = isImmutable;
 
306
        fBase = base;
 
307
        fTypeName = name;
 
308
        fTargetNamespace = URI_SCHEMAFORSCHEMA;
 
309
        // To simplify the code for anySimpleType, we treat it as an atomic type
 
310
        fVariety = VARIETY_ATOMIC;
 
311
        fValidationDV = validateDV;
 
312
        fFacetsDefined = FACET_WHITESPACE;
 
313
        if (validateDV == DV_STRING) {
 
314
            fWhiteSpace = WS_PRESERVE;
 
315
        } else {
 
316
            fWhiteSpace = WS_COLLAPSE;
 
317
            fFixedFacet = FACET_WHITESPACE;
 
318
        }
 
319
        this.fOrdered = ordered;
 
320
        this.fBounded = bounded;
 
321
        this.fFinite = finite;
 
322
        this.fNumeric = numeric;
 
323
        fAnnotations = null;
 
324
 
 
325
        // Specify the build in kind for this primitive type
 
326
        fBuiltInKind = builtInKind;
 
327
    }
 
328
 
 
329
    //Create a new simple type for restriction for built-in types
 
330
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
 
331
            XSObjectList annotations, short builtInKind) {
 
332
        this(base, name, uri, finalSet, isImmutable, annotations);
 
333
        // Specify the build in kind for this built-in type
 
334
        fBuiltInKind = builtInKind;
 
335
    }
 
336
 
 
337
    //Create a new simple type for restriction.
 
338
    protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable,
 
339
            XSObjectList annotations) {
 
340
        fBase = base;
 
341
        fTypeName = name;
 
342
        fTargetNamespace = uri;
 
343
        fFinalSet = finalSet;
 
344
        fAnnotations = annotations;
 
345
 
 
346
        fVariety = fBase.fVariety;
 
347
        fValidationDV = fBase.fValidationDV;
 
348
        switch (fVariety) {
 
349
            case VARIETY_ATOMIC:
 
350
                break;
 
351
            case VARIETY_LIST:
 
352
                fItemType = fBase.fItemType;
 
353
                break;
 
354
            case VARIETY_UNION:
 
355
                fMemberTypes = fBase.fMemberTypes;
 
356
                break;
 
357
        }
 
358
 
 
359
        // always inherit facets from the base.
 
360
        // in case a type is created, but applyFacets is not called
 
361
        fLength = fBase.fLength;
 
362
        fMinLength = fBase.fMinLength;
 
363
        fMaxLength = fBase.fMaxLength;
 
364
        fPattern = fBase.fPattern;
 
365
        fPatternStr = fBase.fPatternStr;
 
366
        fEnumeration = fBase.fEnumeration;
 
367
        fEnumerationType = fBase.fEnumerationType;
 
368
        fEnumerationItemType = fBase.fEnumerationItemType;
 
369
        fWhiteSpace = fBase.fWhiteSpace;
 
370
        fMaxExclusive = fBase.fMaxExclusive;
 
371
        fMaxInclusive = fBase.fMaxInclusive;
 
372
        fMinExclusive = fBase.fMinExclusive;
 
373
        fMinInclusive = fBase.fMinInclusive;
 
374
        fTotalDigits = fBase.fTotalDigits;
 
375
        fFractionDigits = fBase.fFractionDigits;
 
376
        fPatternType = fBase.fPatternType;
 
377
        fFixedFacet = fBase.fFixedFacet;
 
378
        fFacetsDefined = fBase.fFacetsDefined;
 
379
 
 
380
        // always inherit facet annotations in case applyFacets is not called.
 
381
        lengthAnnotation = fBase.lengthAnnotation;
 
382
        minLengthAnnotation = fBase.minLengthAnnotation;
 
383
        maxLengthAnnotation = fBase.maxLengthAnnotation;
 
384
        patternAnnotations = fBase.patternAnnotations;
 
385
        enumerationAnnotations = fBase.enumerationAnnotations;
 
386
        whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
 
387
        maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
 
388
        maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
 
389
        minExclusiveAnnotation = fBase.minExclusiveAnnotation;
 
390
        minInclusiveAnnotation = fBase.minInclusiveAnnotation;
 
391
        totalDigitsAnnotation = fBase.totalDigitsAnnotation;
 
392
        fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
 
393
 
 
394
        //we also set fundamental facets information in case applyFacets is not called.
 
395
        calcFundamentalFacets();
 
396
        fIsImmutable = isImmutable;
 
397
 
 
398
        // Inherit from the base type
 
399
        fBuiltInKind = base.fBuiltInKind;
 
400
    }
 
401
 
 
402
    //Create a new simple type for list.
 
403
    protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable,
 
404
            XSObjectList annotations) {
 
405
        fBase = fAnySimpleType;
 
406
        fTypeName = name;
 
407
        fTargetNamespace = uri;
 
408
        fFinalSet = finalSet;
 
409
        fAnnotations = annotations;
 
410
 
 
411
        fVariety = VARIETY_LIST;
 
412
        fItemType = (XSSimpleTypeDecl)itemType;
 
413
        fValidationDV = DV_LIST;
 
414
        fFacetsDefined = FACET_WHITESPACE;
 
415
        fFixedFacet = FACET_WHITESPACE;
 
416
        fWhiteSpace = WS_COLLAPSE;
 
417
 
 
418
        //setting fundamental facets
 
419
        calcFundamentalFacets();
 
420
        fIsImmutable = isImmutable;
 
421
 
 
422
        // Values of this type are lists
 
423
        fBuiltInKind = XSConstants.LIST_DT;
 
424
    }
 
425
 
 
426
    //Create a new simple type for union.
 
427
    protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
 
428
            XSObjectList annotations) {
 
429
        fBase = fAnySimpleType;
 
430
        fTypeName = name;
 
431
        fTargetNamespace = uri;
 
432
        fFinalSet = finalSet;
 
433
        fAnnotations = annotations;
 
434
 
 
435
        fVariety = VARIETY_UNION;
 
436
        fMemberTypes = memberTypes;
 
437
        fValidationDV = DV_UNION;
 
438
        // even for union, we set whitespace to something
 
439
        // this will never be used, but we can use fFacetsDefined to check
 
440
        // whether applyFacets() is allwwed: it's not allowed
 
441
        // if fFacetsDefined != 0
 
442
        fFacetsDefined = FACET_WHITESPACE;
 
443
        fWhiteSpace = WS_COLLAPSE;
 
444
 
 
445
        //setting fundamental facets
 
446
        calcFundamentalFacets();
 
447
        // none of the schema-defined types are unions, so just set
 
448
        // fIsImmutable to false.
 
449
        fIsImmutable = false;
 
450
 
 
451
        // No value can be of this type, so it's unavailable.
 
452
        fBuiltInKind = XSConstants.UNAVAILABLE_DT;
 
453
    }
 
454
 
 
455
    //set values for restriction.
 
456
    protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String name, String uri, short finalSet,
 
457
            XSObjectList annotations) {
 
458
        //decline to do anything if the object is immutable.
 
459
        if(fIsImmutable) return null;
 
460
        fBase = base;
 
461
        fTypeName = name;
 
462
        fTargetNamespace = uri;
 
463
        fFinalSet = finalSet;
 
464
        fAnnotations = annotations;
 
465
 
 
466
        fVariety = fBase.fVariety;
 
467
        fValidationDV = fBase.fValidationDV;
 
468
        switch (fVariety) {
 
469
            case VARIETY_ATOMIC:
 
470
                break;
 
471
            case VARIETY_LIST:
 
472
                fItemType = fBase.fItemType;
 
473
                break;
 
474
            case VARIETY_UNION:
 
475
                fMemberTypes = fBase.fMemberTypes;
 
476
                break;
 
477
        }
 
478
 
 
479
        // always inherit facets from the base.
 
480
        // in case a type is created, but applyFacets is not called
 
481
        fLength = fBase.fLength;
 
482
        fMinLength = fBase.fMinLength;
 
483
        fMaxLength = fBase.fMaxLength;
 
484
        fPattern = fBase.fPattern;
 
485
        fPatternStr = fBase.fPatternStr;
 
486
        fEnumeration = fBase.fEnumeration;
 
487
        fEnumerationType = fBase.fEnumerationType;
 
488
        fEnumerationItemType = fBase.fEnumerationItemType;
 
489
        fWhiteSpace = fBase.fWhiteSpace;
 
490
        fMaxExclusive = fBase.fMaxExclusive;
 
491
        fMaxInclusive = fBase.fMaxInclusive;
 
492
        fMinExclusive = fBase.fMinExclusive;
 
493
        fMinInclusive = fBase.fMinInclusive;
 
494
        fTotalDigits = fBase.fTotalDigits;
 
495
        fFractionDigits = fBase.fFractionDigits;
 
496
        fPatternType = fBase.fPatternType;
 
497
        fFixedFacet = fBase.fFixedFacet;
 
498
        fFacetsDefined = fBase.fFacetsDefined;
 
499
 
 
500
        //we also set fundamental facets information in case applyFacets is not called.
 
501
        calcFundamentalFacets();
 
502
 
 
503
        // Inherit from the base type
 
504
        fBuiltInKind = base.fBuiltInKind;
 
505
 
 
506
        return this;
 
507
    }
 
508
 
 
509
    //set values for list.
 
510
    protected XSSimpleTypeDecl setListValues(String name, String uri, short finalSet, XSSimpleTypeDecl itemType,
 
511
            XSObjectList annotations) {
 
512
        //decline to do anything if the object is immutable.
 
513
        if(fIsImmutable) return null;
 
514
        fBase = fAnySimpleType;
 
515
        fTypeName = name;
 
516
        fTargetNamespace = uri;
 
517
        fFinalSet = finalSet;
 
518
        fAnnotations = annotations;
 
519
 
 
520
        fVariety = VARIETY_LIST;
 
521
        fItemType = (XSSimpleTypeDecl)itemType;
 
522
        fValidationDV = DV_LIST;
 
523
        fFacetsDefined = FACET_WHITESPACE;
 
524
        fFixedFacet = FACET_WHITESPACE;
 
525
        fWhiteSpace = WS_COLLAPSE;
 
526
 
 
527
        //setting fundamental facets
 
528
        calcFundamentalFacets();
 
529
 
 
530
        // Values of this type are lists
 
531
        fBuiltInKind = XSConstants.LIST_DT;
 
532
 
 
533
        return this;
 
534
    }
 
535
 
 
536
    //set values for union.
 
537
    protected XSSimpleTypeDecl setUnionValues(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes,
 
538
            XSObjectList annotations) {
 
539
        //decline to do anything if the object is immutable.
 
540
        if(fIsImmutable) return null;
 
541
        fBase = fAnySimpleType;
 
542
        fTypeName = name;
 
543
        fTargetNamespace = uri;
 
544
        fFinalSet = finalSet;
 
545
        fAnnotations = annotations;
 
546
 
 
547
        fVariety = VARIETY_UNION;
 
548
        fMemberTypes = memberTypes;
 
549
        fValidationDV = DV_UNION;
 
550
        // even for union, we set whitespace to something
 
551
        // this will never be used, but we can use fFacetsDefined to check
 
552
        // whether applyFacets() is allwwed: it's not allowed
 
553
        // if fFacetsDefined != 0
 
554
        fFacetsDefined = FACET_WHITESPACE;
 
555
        fWhiteSpace = WS_COLLAPSE;
 
556
 
 
557
        //setting fundamental facets
 
558
        calcFundamentalFacets();
 
559
 
 
560
        // No value can be of this type, so it's unavailable.
 
561
        fBuiltInKind = XSConstants.UNAVAILABLE_DT;
 
562
 
 
563
        return this;
 
564
    }
 
565
 
 
566
    public short getType () {
 
567
        return XSConstants.TYPE_DEFINITION;
 
568
    }
 
569
 
 
570
    public short getTypeCategory () {
 
571
        return SIMPLE_TYPE;
 
572
    }
 
573
 
 
574
    public String getName() {
 
575
        return getAnonymous()?null:fTypeName;
 
576
    }
 
577
 
 
578
    public String getTypeName() {
 
579
        return fTypeName;
 
580
    }
 
581
 
 
582
    public String getNamespace() {
 
583
        return fTargetNamespace;
 
584
    }
 
585
 
 
586
    public short getFinal(){
 
587
        return fFinalSet;
 
588
    }
 
589
 
 
590
    public boolean isFinal(short derivation) {
 
591
        return (fFinalSet & derivation) != 0;
 
592
    }
 
593
 
 
594
    public XSTypeDefinition getBaseType(){
 
595
        return fBase;
 
596
    }
 
597
 
 
598
    public boolean getAnonymous() {
 
599
        return fAnonymous || (fTypeName == null);
 
600
    }
 
601
 
 
602
    public short getVariety(){
 
603
        // for anySimpleType, return absent variaty
 
604
        return fValidationDV == DV_ANYSIMPLETYPE ? VARIETY_ABSENT : fVariety;
 
605
    }
 
606
 
 
607
    public boolean isIDType(){
 
608
        switch (fVariety) {
 
609
            case VARIETY_ATOMIC:
 
610
                return fValidationDV == DV_ID;
 
611
            case VARIETY_LIST:
 
612
                return fItemType.isIDType();
 
613
            case VARIETY_UNION:
 
614
                for (int i = 0; i < fMemberTypes.length; i++) {
 
615
                    if (fMemberTypes[i].isIDType())
 
616
                        return true;
 
617
                }
 
618
        }
 
619
        return false;
 
620
    }
 
621
 
 
622
    public short getWhitespace() throws DatatypeException{
 
623
        if (fVariety == VARIETY_UNION) {
 
624
            throw new DatatypeException("dt-whitespace", new Object[]{fTypeName});
 
625
        }
 
626
        return fWhiteSpace;
 
627
    }
 
628
 
 
629
    public short getPrimitiveKind() {
 
630
        if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
 
631
            if (fValidationDV == DV_ID || fValidationDV == DV_IDREF || fValidationDV == DV_ENTITY) {
 
632
                return DV_STRING;
 
633
            }
 
634
            else if (fValidationDV == DV_INTEGER) {
 
635
                return DV_DECIMAL;
 
636
            }
 
637
            else if (Constants.SCHEMA_1_1_SUPPORT && (fValidationDV == DV_YEARMONTHDURATION || fValidationDV == DV_DAYTIMEDURATION)) {
 
638
                return DV_DURATION;
 
639
            }
 
640
            else {
 
641
                return fValidationDV;
 
642
            }
 
643
        }
 
644
        else {
 
645
            // REVISIT: error situation. runtime exception?
 
646
            return (short)0;
 
647
        }
 
648
    }
 
649
 
 
650
    /**
 
651
     * Returns the closest built-in type category this type represents or
 
652
     * derived from. For example, if this simple type is a built-in derived
 
653
     * type integer the <code>INTEGER_DV</code> is returned.
 
654
     */
 
655
    public short getBuiltInKind() {
 
656
        return this.fBuiltInKind;
 
657
    }
 
658
 
 
659
    /**
 
660
     * If variety is <code>atomic</code> the primitive type definition (a
 
661
     * built-in primitive datatype definition or the simple ur-type
 
662
     * definition) is available, otherwise <code>null</code>.
 
663
     */
 
664
    public XSSimpleTypeDefinition getPrimitiveType() {
 
665
        if (fVariety == VARIETY_ATOMIC && fValidationDV != DV_ANYSIMPLETYPE) {
 
666
            XSSimpleTypeDecl pri = this;
 
667
            // recursively get base, until we reach anySimpleType
 
668
            while (pri.fBase != fAnySimpleType)
 
669
                pri = pri.fBase;
 
670
            return pri;
 
671
        }
 
672
        else {
 
673
            // REVISIT: error situation. runtime exception?
 
674
            return null;
 
675
        }
 
676
    }
 
677
 
 
678
    /**
 
679
     * If variety is <code>list</code> the item type definition (an atomic or
 
680
     * union simple type definition) is available, otherwise
 
681
     * <code>null</code>.
 
682
     */
 
683
    public XSSimpleTypeDefinition getItemType() {
 
684
        if (fVariety == VARIETY_LIST) {
 
685
            return fItemType;
 
686
        }
 
687
        else {
 
688
            // REVISIT: error situation. runtime exception?
 
689
            return null;
 
690
        }
 
691
    }
 
692
 
 
693
    /**
 
694
     * If variety is <code>union</code> the list of member type definitions (a
 
695
     * non-empty sequence of simple type definitions) is available,
 
696
     * otherwise an empty <code>XSObjectList</code>.
 
697
     */
 
698
    public XSObjectList getMemberTypes() {
 
699
        if (fVariety == VARIETY_UNION) {
 
700
            return new XSObjectListImpl(fMemberTypes, fMemberTypes.length);
 
701
        }
 
702
        else {
 
703
            return XSObjectListImpl.EMPTY_LIST;
 
704
        }
 
705
    }
 
706
 
 
707
    /**
 
708
     * If <restriction> is chosen
 
709
     */
 
710
    public void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, ValidationContext context)
 
711
    throws InvalidDatatypeFacetException {
 
712
        applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, context);
 
713
    }
 
714
 
 
715
    /**
 
716
     * built-in derived types by restriction
 
717
     */
 
718
    void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet) {
 
719
 
 
720
        try {
 
721
            applyFacets(facets, presentFacet, fixedFacet, SPECIAL_PATTERN_NONE, fDummyContext);
 
722
        } catch (InvalidDatatypeFacetException e) {
 
723
            // should never gets here, internel error
 
724
            throw new RuntimeException("internal error");
 
725
        }
 
726
        // we've now applied facets; so lock this object:
 
727
        fIsImmutable = true;
 
728
    }
 
729
 
 
730
    /**
 
731
     * built-in derived types by restriction
 
732
     */
 
733
    void applyFacets1(XSFacets facets, short presentFacet, short fixedFacet, short patternType) {
 
734
 
 
735
        try {
 
736
            applyFacets(facets, presentFacet, fixedFacet, patternType, fDummyContext);
 
737
        } catch (InvalidDatatypeFacetException e) {
 
738
            // should never gets here, internel error
 
739
            throw new RuntimeException("internal error");
 
740
        }
 
741
        // we've now applied facets; so lock this object:
 
742
        fIsImmutable = true;
 
743
    }
 
744
 
 
745
    /**
 
746
     * If <restriction> is chosen, or built-in derived types by restriction
 
747
     */
 
748
    void applyFacets(XSFacets facets, short presentFacet, short fixedFacet, short patternType, ValidationContext context)
 
749
    throws InvalidDatatypeFacetException {
 
750
 
 
751
        // if the object is immutable, should not apply facets...
 
752
        if(fIsImmutable) return;
 
753
        ValidatedInfo tempInfo = new ValidatedInfo();
 
754
 
 
755
        // clear facets. because we always inherit facets in the constructor
 
756
        // REVISIT: in fact, we don't need to clear them.
 
757
        // we can convert 5 string values (4 bounds + 1 enum) to actual values,
 
758
        // store them somewhere, then do facet checking at once, instead of
 
759
        // going through the following steps. (lots of checking are redundant:
 
760
        // for example, ((presentFacet & FACET_XXX) != 0))
 
761
 
 
762
        fFacetsDefined = 0;
 
763
        fFixedFacet = 0;
 
764
 
 
765
        int result = 0 ;
 
766
 
 
767
        // step 1: parse present facets
 
768
        short allowedFacet = fDVs[fValidationDV].getAllowedFacets();
 
769
 
 
770
        // length
 
771
        if ((presentFacet & FACET_LENGTH) != 0) {
 
772
            if ((allowedFacet & FACET_LENGTH) == 0) {
 
773
                reportError("cos-applicable-facets", new Object[]{"length", fTypeName});
 
774
            } else {
 
775
                fLength = facets.length;
 
776
                lengthAnnotation = facets.lengthAnnotation;
 
777
                fFacetsDefined |= FACET_LENGTH;
 
778
                if ((fixedFacet & FACET_LENGTH) != 0)
 
779
                    fFixedFacet |= FACET_LENGTH;
 
780
            }
 
781
        }
 
782
        // minLength
 
783
        if ((presentFacet & FACET_MINLENGTH) != 0) {
 
784
            if ((allowedFacet & FACET_MINLENGTH) == 0) {
 
785
                reportError("cos-applicable-facets", new Object[]{"minLength", fTypeName});
 
786
            } else {
 
787
                fMinLength = facets.minLength;
 
788
                minLengthAnnotation = facets.minLengthAnnotation;
 
789
                fFacetsDefined |= FACET_MINLENGTH;
 
790
                if ((fixedFacet & FACET_MINLENGTH) != 0)
 
791
                    fFixedFacet |= FACET_MINLENGTH;
 
792
            }
 
793
        }
 
794
        // maxLength
 
795
        if ((presentFacet & FACET_MAXLENGTH) != 0) {
 
796
            if ((allowedFacet & FACET_MAXLENGTH) == 0) {
 
797
                reportError("cos-applicable-facets", new Object[]{"maxLength", fTypeName});
 
798
            } else {
 
799
                fMaxLength = facets.maxLength;
 
800
                maxLengthAnnotation = facets.maxLengthAnnotation;
 
801
                fFacetsDefined |= FACET_MAXLENGTH;
 
802
                if ((fixedFacet & FACET_MAXLENGTH) != 0)
 
803
                    fFixedFacet |= FACET_MAXLENGTH;
 
804
            }
 
805
        }
 
806
        // pattern
 
807
        if ((presentFacet & FACET_PATTERN) != 0) {
 
808
            if ((allowedFacet & FACET_PATTERN) == 0) {
 
809
                reportError("cos-applicable-facets", new Object[]{"pattern", fTypeName});
 
810
            } else {
 
811
                patternAnnotations = facets.patternAnnotations;
 
812
                RegularExpression regex = null;
 
813
                try {
 
814
                    regex = new RegularExpression(facets.pattern, "X");
 
815
                } catch (Exception e) {
 
816
                    reportError("InvalidRegex", new Object[]{facets.pattern, e.getLocalizedMessage()});
 
817
                }
 
818
                if (regex != null) {
 
819
                    fPattern = new Vector();
 
820
                    fPattern.addElement(regex);
 
821
                    fPatternStr = new Vector();
 
822
                    fPatternStr.addElement(facets.pattern);
 
823
                    fFacetsDefined |= FACET_PATTERN;
 
824
                    if ((fixedFacet & FACET_PATTERN) != 0)
 
825
                        fFixedFacet |= FACET_PATTERN;
 
826
                }
 
827
            }
 
828
        }
 
829
 
 
830
        // enumeration
 
831
        if ((presentFacet & FACET_ENUMERATION) != 0) {
 
832
            if ((allowedFacet & FACET_ENUMERATION) == 0) {
 
833
                reportError("cos-applicable-facets", new Object[]{"enumeration", fTypeName});
 
834
            } else {
 
835
                fEnumeration = new Vector();
 
836
                Vector enumVals = facets.enumeration;
 
837
                fEnumerationType = new short[enumVals.size()];
 
838
                fEnumerationItemType = new ShortList[enumVals.size()];
 
839
                Vector enumNSDecls = facets.enumNSDecls;
 
840
                ValidationContextImpl ctx = new ValidationContextImpl(context);
 
841
                enumerationAnnotations = facets.enumAnnotations;
 
842
                for (int i = 0; i < enumVals.size(); i++) {
 
843
                    if (enumNSDecls != null)
 
844
                        ctx.setNSContext((NamespaceContext)enumNSDecls.elementAt(i));
 
845
                    try {
 
846
                        ValidatedInfo info = this.fBase.validateWithInfo((String)enumVals.elementAt(i), ctx, tempInfo);
 
847
                        // check 4.3.5.c0 must: enumeration values from the value space of base
 
848
                        fEnumeration.addElement(info.actualValue);
 
849
                        fEnumerationType[i] = info.actualValueType;
 
850
                        fEnumerationItemType[i] = info.itemValueTypes;
 
851
                    } catch (InvalidDatatypeValueException ide) {
 
852
                        reportError("enumeration-valid-restriction", new Object[]{enumVals.elementAt(i), this.getBaseType().getName()});
 
853
                    }
 
854
                }
 
855
                fFacetsDefined |= FACET_ENUMERATION;
 
856
                if ((fixedFacet & FACET_ENUMERATION) != 0)
 
857
                    fFixedFacet |= FACET_ENUMERATION;
 
858
            }
 
859
        }
 
860
        // whiteSpace
 
861
        if ((presentFacet & FACET_WHITESPACE) != 0) {
 
862
            if ((allowedFacet & FACET_WHITESPACE) == 0) {
 
863
                reportError("cos-applicable-facets", new Object[]{"whiteSpace", fTypeName});
 
864
            } else {
 
865
                fWhiteSpace = facets.whiteSpace;
 
866
                whiteSpaceAnnotation = facets.whiteSpaceAnnotation;
 
867
                fFacetsDefined |= FACET_WHITESPACE;
 
868
                if ((fixedFacet & FACET_WHITESPACE) != 0)
 
869
                    fFixedFacet |= FACET_WHITESPACE;
 
870
            }
 
871
        }
 
872
 
 
873
        // maxInclusive
 
874
        if ((presentFacet & FACET_MAXINCLUSIVE) != 0) {
 
875
            if ((allowedFacet & FACET_MAXINCLUSIVE) == 0) {
 
876
                reportError("cos-applicable-facets", new Object[]{"maxInclusive", fTypeName});
 
877
            } else {
 
878
                maxInclusiveAnnotation = facets.maxInclusiveAnnotation;
 
879
                try {
 
880
                    fMaxInclusive = fBase.getActualValue(facets.maxInclusive, context, tempInfo, true);
 
881
                    fFacetsDefined |= FACET_MAXINCLUSIVE;
 
882
                    if ((fixedFacet & FACET_MAXINCLUSIVE) != 0)
 
883
                        fFixedFacet |= FACET_MAXINCLUSIVE;
 
884
                } catch (InvalidDatatypeValueException ide) {
 
885
                    reportError(ide.getKey(), ide.getArgs());
 
886
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
 
887
                            "maxInclusive", fBase.getName()});
 
888
                }
 
889
 
 
890
                // check against fixed value in base
 
891
                if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
892
                    if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0) {
 
893
                        if (fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive) != 0)
 
894
                            reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
 
895
                    }
 
896
                }
 
897
                // maxInclusive from base
 
898
                try {
 
899
                    fBase.validate(context, tempInfo);
 
900
                } catch (InvalidDatatypeValueException ide) {
 
901
                    reportError(ide.getKey(), ide.getArgs());
 
902
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxInclusive,
 
903
                            "maxInclusive", fBase.getName()});
 
904
                }
 
905
            }
 
906
        }
 
907
 
 
908
        // maxExclusive
 
909
        boolean needCheckBase = true;
 
910
        if ((presentFacet & FACET_MAXEXCLUSIVE) != 0) {
 
911
            if ((allowedFacet & FACET_MAXEXCLUSIVE) == 0) {
 
912
                reportError("cos-applicable-facets", new Object[]{"maxExclusive", fTypeName});
 
913
            } else {
 
914
                maxExclusiveAnnotation = facets.maxExclusiveAnnotation;
 
915
                try {
 
916
                    fMaxExclusive = fBase.getActualValue(facets.maxExclusive, context, tempInfo, true);
 
917
                    fFacetsDefined |= FACET_MAXEXCLUSIVE;
 
918
                    if ((fixedFacet & FACET_MAXEXCLUSIVE) != 0)
 
919
                        fFixedFacet |= FACET_MAXEXCLUSIVE;
 
920
                } catch (InvalidDatatypeValueException ide) {
 
921
                    reportError(ide.getKey(), ide.getArgs());
 
922
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
 
923
                            "maxExclusive", fBase.getName()});
 
924
                }
 
925
 
 
926
                // check against fixed value in base
 
927
                if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
 
928
                    result = fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
 
929
                    if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 && result != 0) {
 
930
                        reportError( "FixedFacetValue", new Object[]{"maxExclusive", facets.maxExclusive, fBase.fMaxExclusive, fTypeName});
 
931
                    }
 
932
                    if (result == 0) {
 
933
                        needCheckBase = false;
 
934
                    }
 
935
                }
 
936
                // maxExclusive from base
 
937
                if (needCheckBase) {
 
938
                    try {
 
939
                        fBase.validate(context, tempInfo);
 
940
                    } catch (InvalidDatatypeValueException ide) {
 
941
                        reportError(ide.getKey(), ide.getArgs());
 
942
                        reportError("FacetValueFromBase", new Object[]{fTypeName, facets.maxExclusive,
 
943
                                "maxExclusive", fBase.getName()});
 
944
                    }
 
945
                }
 
946
                // If maxExclusive == base.maxExclusive, then we only need to check
 
947
                // maxExclusive <= base.maxInclusive
 
948
                else if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
949
                    if (fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive) > 0) {
 
950
                        reportError( "maxExclusive-valid-restriction.2", new Object[]{facets.maxExclusive, fBase.fMaxInclusive});
 
951
                    }
 
952
                }
 
953
            }
 
954
        }
 
955
        // minExclusive
 
956
        needCheckBase = true;
 
957
        if ((presentFacet & FACET_MINEXCLUSIVE) != 0) {
 
958
            if ((allowedFacet & FACET_MINEXCLUSIVE) == 0) {
 
959
                reportError("cos-applicable-facets", new Object[]{"minExclusive", fTypeName});
 
960
            } else {
 
961
                minExclusiveAnnotation = facets.minExclusiveAnnotation;
 
962
                try {
 
963
                    fMinExclusive = fBase.getActualValue(facets.minExclusive, context, tempInfo, true);
 
964
                    fFacetsDefined |= FACET_MINEXCLUSIVE;
 
965
                    if ((fixedFacet & FACET_MINEXCLUSIVE) != 0)
 
966
                        fFixedFacet |= FACET_MINEXCLUSIVE;
 
967
                } catch (InvalidDatatypeValueException ide) {
 
968
                    reportError(ide.getKey(), ide.getArgs());
 
969
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
 
970
                            "minExclusive", fBase.getName()});
 
971
                }
 
972
 
 
973
                // check against fixed value in base
 
974
                if (((fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
 
975
                    result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
 
976
                    if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
 
977
                        reportError( "FixedFacetValue", new Object[]{"minExclusive", facets.minExclusive, fBase.fMinExclusive, fTypeName});
 
978
                    }
 
979
                    if (result == 0) {
 
980
                        needCheckBase = false;
 
981
                    }
 
982
                }
 
983
                // minExclusive from base
 
984
                if (needCheckBase) {
 
985
                    try {
 
986
                        fBase.validate(context, tempInfo);
 
987
                    } catch (InvalidDatatypeValueException ide) {
 
988
                        reportError(ide.getKey(), ide.getArgs());
 
989
                        reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minExclusive,
 
990
                                "minExclusive", fBase.getName()});
 
991
                    }
 
992
                }
 
993
                // If minExclusive == base.minExclusive, then we only need to check
 
994
                // minExclusive >= base.minInclusive
 
995
                else if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
996
                    if (fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive) < 0) {
 
997
                        reportError( "minExclusive-valid-restriction.3", new Object[]{facets.minExclusive, fBase.fMinInclusive});
 
998
                    }
 
999
                }
 
1000
            }
 
1001
        }
 
1002
        // minInclusive
 
1003
        if ((presentFacet & FACET_MININCLUSIVE) != 0) {
 
1004
            if ((allowedFacet & FACET_MININCLUSIVE) == 0) {
 
1005
                reportError("cos-applicable-facets", new Object[]{"minInclusive", fTypeName});
 
1006
            } else {
 
1007
                minInclusiveAnnotation = facets.minInclusiveAnnotation;
 
1008
                try {
 
1009
                    fMinInclusive = fBase.getActualValue(facets.minInclusive, context, tempInfo, true);
 
1010
                    fFacetsDefined |= FACET_MININCLUSIVE;
 
1011
                    if ((fixedFacet & FACET_MININCLUSIVE) != 0)
 
1012
                        fFixedFacet |= FACET_MININCLUSIVE;
 
1013
                } catch (InvalidDatatypeValueException ide) {
 
1014
                    reportError(ide.getKey(), ide.getArgs());
 
1015
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
 
1016
                            "minInclusive", fBase.getName()});
 
1017
                }
 
1018
 
 
1019
                // check against fixed value in base
 
1020
                if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1021
                    if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0) {
 
1022
                        if (fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive) != 0)
 
1023
                            reportError( "FixedFacetValue", new Object[]{"minInclusive", facets.minInclusive, fBase.fMinInclusive, fTypeName});
 
1024
                    }
 
1025
                }
 
1026
                // minInclusive from base
 
1027
                try {
 
1028
                    fBase.validate(context, tempInfo);
 
1029
                } catch (InvalidDatatypeValueException ide) {
 
1030
                    reportError(ide.getKey(), ide.getArgs());
 
1031
                    reportError("FacetValueFromBase", new Object[]{fTypeName, facets.minInclusive,
 
1032
                            "minInclusive", fBase.getName()});
 
1033
                }
 
1034
            }
 
1035
        }
 
1036
 
 
1037
        // totalDigits
 
1038
        if ((presentFacet & FACET_TOTALDIGITS) != 0) {
 
1039
            if ((allowedFacet & FACET_TOTALDIGITS) == 0) {
 
1040
                reportError("cos-applicable-facets", new Object[]{"totalDigits", fTypeName});
 
1041
            } else {
 
1042
                totalDigitsAnnotation = facets.totalDigitsAnnotation;
 
1043
                fTotalDigits = facets.totalDigits;
 
1044
                fFacetsDefined |= FACET_TOTALDIGITS;
 
1045
                if ((fixedFacet & FACET_TOTALDIGITS) != 0)
 
1046
                    fFixedFacet |= FACET_TOTALDIGITS;
 
1047
            }
 
1048
        }
 
1049
        // fractionDigits
 
1050
        if ((presentFacet & FACET_FRACTIONDIGITS) != 0) {
 
1051
            if ((allowedFacet & FACET_FRACTIONDIGITS) == 0) {
 
1052
                reportError("cos-applicable-facets", new Object[]{"fractionDigits", fTypeName});
 
1053
            } else {
 
1054
                fFractionDigits = facets.fractionDigits;
 
1055
                fractionDigitsAnnotation = facets.fractionDigitsAnnotation;
 
1056
                fFacetsDefined |= FACET_FRACTIONDIGITS;
 
1057
                if ((fixedFacet & FACET_FRACTIONDIGITS) != 0)
 
1058
                    fFixedFacet |= FACET_FRACTIONDIGITS;
 
1059
            }
 
1060
        }
 
1061
 
 
1062
        // token type: internal use, so do less checking
 
1063
        if (patternType != SPECIAL_PATTERN_NONE) {
 
1064
            fPatternType = patternType;
 
1065
        }
 
1066
 
 
1067
        // step 2: check facets against each other: length, bounds
 
1068
        if(fFacetsDefined != 0) {
 
1069
 
 
1070
            // check 4.3.2.c1 must: minLength <= maxLength
 
1071
            if(((fFacetsDefined & FACET_MINLENGTH ) != 0 ) && ((fFacetsDefined & FACET_MAXLENGTH) != 0))
 
1072
            {
 
1073
                if(fMinLength > fMaxLength)
 
1074
                    reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fMaxLength), fTypeName});
 
1075
            }
 
1076
 
 
1077
            // check 4.3.8.c1 error: maxInclusive + maxExclusive
 
1078
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1079
                reportError( "maxInclusive-maxExclusive", new Object[]{fMaxInclusive, fMaxExclusive, fTypeName});
 
1080
            }
 
1081
 
 
1082
            // check 4.3.9.c1 error: minInclusive + minExclusive
 
1083
            if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1084
                reportError("minInclusive-minExclusive", new Object[]{fMinInclusive, fMinExclusive, fTypeName});
 
1085
            }
 
1086
 
 
1087
            // check 4.3.7.c1 must: minInclusive <= maxInclusive
 
1088
            if (((fFacetsDefined &  FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1089
                result = fDVs[fValidationDV].compare(fMinInclusive, fMaxInclusive);
 
1090
                if (result != -1 && result != 0)
 
1091
                    reportError("minInclusive-less-than-equal-to-maxInclusive", new Object[]{fMinInclusive, fMaxInclusive, fTypeName});
 
1092
            }
 
1093
 
 
1094
            // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive
 
1095
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
 
1096
                result = fDVs[fValidationDV].compare(fMinExclusive, fMaxExclusive);
 
1097
                if (result != -1 && result != 0)
 
1098
                    reportError( "minExclusive-less-than-equal-to-maxExclusive", new Object[]{fMinExclusive, fMaxExclusive, fTypeName});
 
1099
            }
 
1100
 
 
1101
            // check 4.3.9.c2 must: minExclusive < maxInclusive
 
1102
            if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0) && ((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
 
1103
                if (fDVs[fValidationDV].compare(fMinExclusive, fMaxInclusive) != -1)
 
1104
                    reportError( "minExclusive-less-than-maxInclusive", new Object[]{fMinExclusive, fMaxInclusive, fTypeName});
 
1105
            }
 
1106
 
 
1107
            // check 4.3.10.c1 must: minInclusive < maxExclusive
 
1108
            if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && ((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1109
                if (fDVs[fValidationDV].compare(fMinInclusive, fMaxExclusive) != -1)
 
1110
                    reportError( "minInclusive-less-than-maxExclusive", new Object[]{fMinInclusive, fMaxExclusive, fTypeName});
 
1111
            }
 
1112
 
 
1113
            // check 4.3.12.c1 must: fractionDigits <= totalDigits
 
1114
            if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) &&
 
1115
                    ((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
 
1116
                if (fFractionDigits > fTotalDigits)
 
1117
                    reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
 
1118
            }
 
1119
 
 
1120
            // step 3: check facets against base
 
1121
            // check 4.3.1.c1 error: length & (fBase.maxLength | fBase.minLength)
 
1122
            if((fFacetsDefined & FACET_LENGTH) != 0 ){
 
1123
                if ((fBase.fFacetsDefined & FACET_MINLENGTH) != 0 &&
 
1124
                        fLength < fBase.fMinLength) {
 
1125
                    // length, fBase.minLength and fBase.maxLength defined
 
1126
                    reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMinLength)});
 
1127
                }
 
1128
                if ((fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 &&
 
1129
                        fLength > fBase.fMaxLength) {
 
1130
                    // length and fBase.maxLength defined
 
1131
                    reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fLength), Integer.toString(fBase.fMaxLength)});
 
1132
                }
 
1133
                if ( (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
 
1134
                    // check 4.3.1.c2 error: length != fBase.length
 
1135
                    if ( fLength != fBase.fLength )
 
1136
                        reportError( "length-valid-restriction", new Object[]{Integer.toString(fLength), Integer.toString(fBase.fLength), fTypeName});
 
1137
                }
 
1138
            }
 
1139
 
 
1140
            // check 4.3.1.c1 error: fBase.length & (maxLength | minLength)
 
1141
            if((fBase.fFacetsDefined & FACET_LENGTH) != 0 || (fFacetsDefined & FACET_LENGTH) != 0){
 
1142
                if ((fFacetsDefined & FACET_MINLENGTH) != 0){
 
1143
                    if (fBase.fLength < fMinLength) {
 
1144
                        // fBase.length, minLength and maxLength defined
 
1145
                        reportError("length-minLength-maxLength.1.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMinLength)});
 
1146
                    }
 
1147
                    if ((fBase.fFacetsDefined & FACET_MINLENGTH) == 0){ 
 
1148
                        reportError("length-minLength-maxLength.1.2.a", new Object[]{fTypeName});  
 
1149
                    }
 
1150
                    if (fMinLength != fBase.fMinLength){
 
1151
                        reportError("length-minLength-maxLength.1.2.b", new Object[]{fTypeName, Integer.toString(fMinLength), Integer.toString(fBase.fMinLength)}); 
 
1152
                    }
 
1153
                }
 
1154
                if ((fFacetsDefined & FACET_MAXLENGTH) != 0){
 
1155
                    if (fBase.fLength > fMaxLength) {
 
1156
                        // fBase.length, minLength and maxLength defined
 
1157
                        reportError("length-minLength-maxLength.2.1", new Object[]{fTypeName, Integer.toString(fBase.fLength), Integer.toString(fMaxLength)});
 
1158
                    }
 
1159
                    if ((fBase.fFacetsDefined & FACET_MAXLENGTH) == 0){ 
 
1160
                        reportError("length-minLength-maxLength.2.2.a", new Object[]{fTypeName});  
 
1161
                    }
 
1162
                    if (fMaxLength != fBase.fMaxLength){
 
1163
                        reportError("length-minLength-maxLength.2.2.b", new Object[]{fTypeName, Integer.toString(fMaxLength), Integer.toString(fBase.fBase.fMaxLength)}); 
 
1164
                    }
 
1165
                }
 
1166
            }
 
1167
 
 
1168
            // check 4.3.2.c1 must: minLength <= fBase.maxLength
 
1169
            if ( ((fFacetsDefined & FACET_MINLENGTH ) != 0 ) ) {
 
1170
                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH ) != 0 ) {
 
1171
                    if ( fMinLength > fBase.fMaxLength ) {
 
1172
                        reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMaxLength), fTypeName});
 
1173
                    }
 
1174
                }
 
1175
                else if ( (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
 
1176
                    if ( (fBase.fFixedFacet & FACET_MINLENGTH) != 0 && fMinLength != fBase.fMinLength ) {
 
1177
                        reportError( "FixedFacetValue", new Object[]{"minLength", Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
 
1178
                    }
 
1179
 
 
1180
                    // check 4.3.2.c2 error: minLength < fBase.minLength
 
1181
                    if ( fMinLength < fBase.fMinLength ) {
 
1182
                        reportError( "minLength-valid-restriction", new Object[]{Integer.toString(fMinLength), Integer.toString(fBase.fMinLength), fTypeName});
 
1183
                    }
 
1184
                }
 
1185
            }
 
1186
 
 
1187
 
 
1188
            // check 4.3.2.c1 must: maxLength < fBase.minLength
 
1189
            if ( ((fFacetsDefined & FACET_MAXLENGTH ) != 0 ) && ((fBase.fFacetsDefined & FACET_MINLENGTH ) != 0 )) {
 
1190
                if ( fMaxLength < fBase.fMinLength) {
 
1191
                    reportError("minLength-less-than-equal-to-maxLength", new Object[]{Integer.toString(fBase.fMinLength), Integer.toString(fMaxLength)});
 
1192
                }
 
1193
            }
 
1194
 
 
1195
            // check 4.3.3.c1 error: maxLength > fBase.maxLength
 
1196
            if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
 
1197
                if ( (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ){
 
1198
                    if(( (fBase.fFixedFacet & FACET_MAXLENGTH) != 0 )&& fMaxLength != fBase.fMaxLength ) {
 
1199
                        reportError( "FixedFacetValue", new Object[]{"maxLength", Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
 
1200
                    }
 
1201
                    if ( fMaxLength > fBase.fMaxLength ) {
 
1202
                        reportError( "maxLength-valid-restriction", new Object[]{Integer.toString(fMaxLength), Integer.toString(fBase.fMaxLength), fTypeName});
 
1203
                    }
 
1204
                }
 
1205
            }
 
1206
 
 
1207
            /*          // check 4.3.7.c2 error:
 
1208
                         // maxInclusive > fBase.maxInclusive
 
1209
                          // maxInclusive >= fBase.maxExclusive
 
1210
                           // maxInclusive < fBase.minInclusive
 
1211
                            // maxInclusive <= fBase.minExclusive
 
1212
 
 
1213
                             if (((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1214
                             if (((fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1215
                             result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxInclusive);
 
1216
                             if ((fBase.fFixedFacet & FACET_MAXINCLUSIVE) != 0 && result != 0) {
 
1217
                             reportError( "FixedFacetValue", new Object[]{"maxInclusive", fMaxInclusive, fBase.fMaxInclusive, fTypeName});
 
1218
                             }
 
1219
                             if (result != -1 && result != 0) {
 
1220
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxInclusive, fTypeName});
 
1221
                             }
 
1222
                             }
 
1223
                             if (((fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
 
1224
                             fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMaxExclusive) != -1){
 
1225
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMaxExclusive, fTypeName});
 
1226
                             }
 
1227
 
 
1228
                             if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1229
                             result = fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinInclusive);
 
1230
                             if (result != 1 && result != 0) {
 
1231
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinInclusive, fTypeName});
 
1232
                             }
 
1233
                             }
 
1234
 
 
1235
                             if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
 
1236
                             fDVs[fValidationDV].compare(fMaxInclusive, fBase.fMinExclusive ) != 1)
 
1237
                             reportError( "maxInclusive-valid-restriction.1", new Object[]{fMaxInclusive, fBase.fMinExclusive, fTypeName});
 
1238
                             }
 
1239
 
 
1240
                             // check 4.3.8.c3 error:
 
1241
                              // maxExclusive > fBase.maxExclusive
 
1242
                               // maxExclusive > fBase.maxInclusive
 
1243
                                // maxExclusive <= fBase.minInclusive
 
1244
                                 // maxExclusive <= fBase.minExclusive
 
1245
                                  if (((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
 
1246
                                  if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) {
 
1247
                                  result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxExclusive);
 
1248
                                  if ((fBase.fFixedFacet & FACET_MAXEXCLUSIVE) != 0 &&  result != 0) {
 
1249
                                  reportError( "FixedFacetValue", new Object[]{"maxExclusive", fMaxExclusive, fBase.fMaxExclusive, fTypeName});
 
1250
                                  }
 
1251
                                  if (result != -1 && result != 0) {
 
1252
                                  reportError( "maxExclusive-valid-restriction.1", new Object[]{fMaxExclusive, fBase.fMaxExclusive, fTypeName});
 
1253
                                  }
 
1254
                                  }
 
1255
 
 
1256
                                  if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1257
                                  result= fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMaxInclusive);
 
1258
                                  if (result != -1 && result != 0) {
 
1259
                                  reportError( "maxExclusive-valid-restriction.2", new Object[]{fMaxExclusive, fBase.fMaxInclusive, fTypeName});
 
1260
                                  }
 
1261
                                  }
 
1262
 
 
1263
                                  if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
 
1264
                                  fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinExclusive ) != 1)
 
1265
                                  reportError( "maxExclusive-valid-restriction.3", new Object[]{fMaxExclusive, fBase.fMinExclusive, fTypeName});
 
1266
 
 
1267
                                  if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
 
1268
                                  fDVs[fValidationDV].compare(fMaxExclusive, fBase.fMinInclusive) != 1)
 
1269
                                  reportError( "maxExclusive-valid-restriction.4", new Object[]{fMaxExclusive, fBase.fMinInclusive, fTypeName});
 
1270
                                  }
 
1271
 
 
1272
                                  // check 4.3.9.c3 error:
 
1273
                                   // minExclusive < fBase.minExclusive
 
1274
                                    // minExclusive > fBase.maxInclusive
 
1275
                                     // minExclusive < fBase.minInclusive
 
1276
                                      // minExclusive >= fBase.maxExclusive
 
1277
                                       if (((fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
 
1278
                                       if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) {
 
1279
                                       result= fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinExclusive);
 
1280
                                       if ((fBase.fFixedFacet & FACET_MINEXCLUSIVE) != 0 && result != 0) {
 
1281
                                       reportError( "FixedFacetValue", new Object[]{"minExclusive", fMinExclusive, fBase.fMinExclusive, fTypeName});
 
1282
                                       }
 
1283
                                       if (result != 1 && result != 0) {
 
1284
                                       reportError( "minExclusive-valid-restriction.1", new Object[]{fMinExclusive, fBase.fMinExclusive, fTypeName});
 
1285
                                       }
 
1286
                                       }
 
1287
 
 
1288
                                       if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1289
                                       result=fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxInclusive);
 
1290
 
 
1291
                                       if (result != -1 && result != 0) {
 
1292
                                       reportError( "minExclusive-valid-restriction.2", new Object[]{fMinExclusive, fBase.fMaxInclusive, fTypeName});
 
1293
                                       }
 
1294
                                       }
 
1295
 
 
1296
                                       if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1297
                                       result = fDVs[fValidationDV].compare(fMinExclusive, fBase.fMinInclusive);
 
1298
 
 
1299
                                       if (result != 1 && result != 0) {
 
1300
                                       reportError( "minExclusive-valid-restriction.3", new Object[]{fMinExclusive, fBase.fMinInclusive, fTypeName});
 
1301
                                       }
 
1302
                                       }
 
1303
 
 
1304
                                       if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
 
1305
                                       fDVs[fValidationDV].compare(fMinExclusive, fBase.fMaxExclusive) != -1)
 
1306
                                       reportError( "minExclusive-valid-restriction.4", new Object[]{fMinExclusive, fBase.fMaxExclusive, fTypeName});
 
1307
                                       }
 
1308
 
 
1309
                                       // check 4.3.10.c2 error:
 
1310
                                        // minInclusive < fBase.minInclusive
 
1311
                                         // minInclusive > fBase.maxInclusive
 
1312
                                          // minInclusive <= fBase.minExclusive
 
1313
                                           // minInclusive >= fBase.maxExclusive
 
1314
                                            if (((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1315
                                            if (((fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1316
                                            result = fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinInclusive);
 
1317
 
 
1318
                                            if ((fBase.fFixedFacet & FACET_MININCLUSIVE) != 0 && result != 0) {
 
1319
                                            reportError( "FixedFacetValue", new Object[]{"minInclusive", fMinInclusive, fBase.fMinInclusive, fTypeName});
 
1320
                                            }
 
1321
                                            if (result != 1 && result != 0) {
 
1322
                                            reportError( "minInclusive-valid-restriction.1", new Object[]{fMinInclusive, fBase.fMinInclusive, fTypeName});
 
1323
                                            }
 
1324
                                            }
 
1325
                                            if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1326
                                            result=fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxInclusive);
 
1327
                                            if (result != -1 && result != 0) {
 
1328
                                            reportError( "minInclusive-valid-restriction.2", new Object[]{fMinInclusive, fBase.fMaxInclusive, fTypeName});
 
1329
                                            }
 
1330
                                            }
 
1331
                                            if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
 
1332
                                            fDVs[fValidationDV].compare(fMinInclusive, fBase.fMinExclusive ) != 1)
 
1333
                                            reportError( "minInclusive-valid-restriction.3", new Object[]{fMinInclusive, fBase.fMinExclusive, fTypeName});
 
1334
                                            if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
 
1335
                                            fDVs[fValidationDV].compare(fMinInclusive, fBase.fMaxExclusive) != -1)
 
1336
                                            reportError( "minInclusive-valid-restriction.4", new Object[]{fMinInclusive, fBase.fMaxExclusive, fTypeName});
 
1337
                                            }
 
1338
             */
 
1339
            // check 4.3.11.c1 error: totalDigits > fBase.totalDigits
 
1340
            if (((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
 
1341
                if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
 
1342
                    if ((fBase.fFixedFacet & FACET_TOTALDIGITS) != 0 && fTotalDigits != fBase.fTotalDigits) {
 
1343
                        reportError("FixedFacetValue", new Object[]{"totalDigits", Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
 
1344
                    }
 
1345
                    if (fTotalDigits > fBase.fTotalDigits) {
 
1346
                        reportError( "totalDigits-valid-restriction", new Object[]{Integer.toString(fTotalDigits), Integer.toString(fBase.fTotalDigits), fTypeName});
 
1347
                    }
 
1348
                }
 
1349
            }
 
1350
 
 
1351
            // check 4.3.12.c1 must: fractionDigits <= base.totalDigits
 
1352
            if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
 
1353
                if ((fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) {
 
1354
                    if (fFractionDigits > fBase.fTotalDigits)
 
1355
                        reportError( "fractionDigits-totalDigits", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fTotalDigits), fTypeName});
 
1356
                }
 
1357
            }
 
1358
 
 
1359
            // check 4.3.12.c2 error: fractionDigits > fBase.fractionDigits
 
1360
            // check fixed value for fractionDigits
 
1361
            if (((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
 
1362
                if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
 
1363
                    if (((fBase.fFixedFacet & FACET_FRACTIONDIGITS) != 0 && fFractionDigits != fBase.fFractionDigits) ||
 
1364
                            (fValidationDV == DV_INTEGER && fFractionDigits != 0)) {
 
1365
                        reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
 
1366
                    }
 
1367
                    if (fFractionDigits > fBase.fFractionDigits) {
 
1368
                        reportError( "fractionDigits-valid-restriction", new Object[]{Integer.toString(fFractionDigits), Integer.toString(fBase.fFractionDigits), fTypeName});
 
1369
                    }
 
1370
                }
 
1371
                else if (fValidationDV == DV_INTEGER && fFractionDigits != 0) {
 
1372
                    reportError("FixedFacetValue", new Object[]{"fractionDigits", Integer.toString(fFractionDigits), "0", fTypeName});
 
1373
                }
 
1374
            }
 
1375
 
 
1376
            // check 4.3.6.c1 error:
 
1377
            // (whiteSpace = preserve || whiteSpace = replace) && fBase.whiteSpace = collapese or
 
1378
            // whiteSpace = preserve && fBase.whiteSpace = replace
 
1379
 
 
1380
            if ( (fFacetsDefined & FACET_WHITESPACE) != 0 && (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ){
 
1381
                if ( (fBase.fFixedFacet & FACET_WHITESPACE) != 0 &&  fWhiteSpace != fBase.fWhiteSpace ) {
 
1382
                    reportError( "FixedFacetValue", new Object[]{"whiteSpace", whiteSpaceValue(fWhiteSpace), whiteSpaceValue(fBase.fWhiteSpace), fTypeName});
 
1383
                }
 
1384
 
 
1385
                if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
 
1386
                    reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "preserve"});
 
1387
                }
 
1388
                if ( fWhiteSpace == WS_REPLACE &&  fBase.fWhiteSpace == WS_COLLAPSE ){
 
1389
                    reportError( "whiteSpace-valid-restriction.1", new Object[]{fTypeName, "replace"});
 
1390
                }
 
1391
                if ( fWhiteSpace == WS_PRESERVE &&  fBase.fWhiteSpace == WS_REPLACE ){
 
1392
                    reportError( "whiteSpace-valid-restriction.2", new Object[]{fTypeName});
 
1393
                }
 
1394
            }
 
1395
        }//fFacetsDefined != null
 
1396
 
 
1397
        // step 4: inherit other facets from base (including fTokeyType)
 
1398
 
 
1399
        // inherit length
 
1400
        if ( (fFacetsDefined & FACET_LENGTH) == 0  && (fBase.fFacetsDefined & FACET_LENGTH) != 0 ) {
 
1401
            fFacetsDefined |= FACET_LENGTH;
 
1402
            fLength = fBase.fLength;
 
1403
            lengthAnnotation = fBase.lengthAnnotation;
 
1404
        }
 
1405
        // inherit minLength
 
1406
        if ( (fFacetsDefined & FACET_MINLENGTH) == 0 && (fBase.fFacetsDefined & FACET_MINLENGTH) != 0 ) {
 
1407
            fFacetsDefined |= FACET_MINLENGTH;
 
1408
            fMinLength = fBase.fMinLength;
 
1409
            minLengthAnnotation = fBase.minLengthAnnotation;
 
1410
        }
 
1411
        // inherit maxLength
 
1412
        if ((fFacetsDefined & FACET_MAXLENGTH) == 0 &&  (fBase.fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
 
1413
            fFacetsDefined |= FACET_MAXLENGTH;
 
1414
            fMaxLength = fBase.fMaxLength;
 
1415
            maxLengthAnnotation = fBase.maxLengthAnnotation;
 
1416
        }
 
1417
        // inherit pattern
 
1418
        if ( (fBase.fFacetsDefined & FACET_PATTERN) != 0 ) {
 
1419
            if ((fFacetsDefined & FACET_PATTERN) == 0) {
 
1420
                fFacetsDefined |= FACET_PATTERN;
 
1421
                fPattern = fBase.fPattern;
 
1422
                fPatternStr = fBase.fPatternStr;
 
1423
                patternAnnotations = fBase.patternAnnotations;
 
1424
            }
 
1425
            else {
 
1426
                for (int i = fBase.fPattern.size()-1; i >= 0; --i) {
 
1427
                    fPattern.addElement(fBase.fPattern.elementAt(i));
 
1428
                    fPatternStr.addElement(fBase.fPatternStr.elementAt(i));
 
1429
                }
 
1430
                if (fBase.patternAnnotations != null) {
 
1431
                    if (patternAnnotations != null) {
 
1432
                        for (int i = fBase.patternAnnotations.getLength()-1; i >= 0; --i) {
 
1433
                            patternAnnotations.add(fBase.patternAnnotations.item(i));
 
1434
                        }
 
1435
                    }
 
1436
                    else {
 
1437
                        patternAnnotations = fBase.patternAnnotations;
 
1438
                    }
 
1439
                }
 
1440
            }
 
1441
        }
 
1442
        // inherit whiteSpace
 
1443
        if ( (fFacetsDefined & FACET_WHITESPACE) == 0 &&  (fBase.fFacetsDefined & FACET_WHITESPACE) != 0 ) {
 
1444
            fFacetsDefined |= FACET_WHITESPACE;
 
1445
            fWhiteSpace = fBase.fWhiteSpace;
 
1446
            whiteSpaceAnnotation = fBase.whiteSpaceAnnotation;
 
1447
        }
 
1448
        // inherit enumeration
 
1449
        if ((fFacetsDefined & FACET_ENUMERATION) == 0 && (fBase.fFacetsDefined & FACET_ENUMERATION) != 0) {
 
1450
            fFacetsDefined |= FACET_ENUMERATION;
 
1451
            fEnumeration = fBase.fEnumeration;
 
1452
            enumerationAnnotations = fBase.enumerationAnnotations;
 
1453
        }
 
1454
        // inherit maxExclusive
 
1455
        if ((( fBase.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) &&
 
1456
                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1457
            fFacetsDefined |= FACET_MAXEXCLUSIVE;
 
1458
            fMaxExclusive = fBase.fMaxExclusive;
 
1459
            maxExclusiveAnnotation = fBase.maxExclusiveAnnotation;
 
1460
        }
 
1461
        // inherit maxInclusive
 
1462
        if ((( fBase.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) &&
 
1463
                !((fFacetsDefined & FACET_MAXEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MAXINCLUSIVE) != 0)) {
 
1464
            fFacetsDefined |= FACET_MAXINCLUSIVE;
 
1465
            fMaxInclusive = fBase.fMaxInclusive;
 
1466
            maxInclusiveAnnotation = fBase.maxInclusiveAnnotation;
 
1467
        }
 
1468
        // inherit minExclusive
 
1469
        if ((( fBase.fFacetsDefined & FACET_MINEXCLUSIVE) != 0) &&
 
1470
                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1471
            fFacetsDefined |= FACET_MINEXCLUSIVE;
 
1472
            fMinExclusive = fBase.fMinExclusive;
 
1473
            minExclusiveAnnotation = fBase.minExclusiveAnnotation;
 
1474
        }
 
1475
        // inherit minExclusive
 
1476
        if ((( fBase.fFacetsDefined & FACET_MININCLUSIVE) != 0) &&
 
1477
                !((fFacetsDefined & FACET_MINEXCLUSIVE) != 0) && !((fFacetsDefined & FACET_MININCLUSIVE) != 0)) {
 
1478
            fFacetsDefined |= FACET_MININCLUSIVE;
 
1479
            fMinInclusive = fBase.fMinInclusive;
 
1480
            minInclusiveAnnotation = fBase.minInclusiveAnnotation;
 
1481
        }
 
1482
        // inherit totalDigits
 
1483
        if ((( fBase.fFacetsDefined & FACET_TOTALDIGITS) != 0) &&
 
1484
                !((fFacetsDefined & FACET_TOTALDIGITS) != 0)) {
 
1485
            fFacetsDefined |= FACET_TOTALDIGITS;
 
1486
            fTotalDigits = fBase.fTotalDigits;
 
1487
            totalDigitsAnnotation = fBase.totalDigitsAnnotation;
 
1488
        }
 
1489
        // inherit fractionDigits
 
1490
        if ((( fBase.fFacetsDefined & FACET_FRACTIONDIGITS) != 0)
 
1491
                && !((fFacetsDefined & FACET_FRACTIONDIGITS) != 0)) {
 
1492
            fFacetsDefined |= FACET_FRACTIONDIGITS;
 
1493
            fFractionDigits = fBase.fFractionDigits;
 
1494
            fractionDigitsAnnotation = fBase.fractionDigitsAnnotation;
 
1495
        }
 
1496
        //inherit tokeytype
 
1497
        if ((fPatternType == SPECIAL_PATTERN_NONE ) && (fBase.fPatternType != SPECIAL_PATTERN_NONE)) {
 
1498
            fPatternType = fBase.fPatternType ;
 
1499
        }
 
1500
 
 
1501
        // step 5: mark fixed values
 
1502
        fFixedFacet |= fBase.fFixedFacet;
 
1503
 
 
1504
        //step 6: setting fundamental facets
 
1505
        calcFundamentalFacets();
 
1506
 
 
1507
    } //applyFacets()
 
1508
 
 
1509
    /**
 
1510
     * validate a value, and return the compiled form
 
1511
     */
 
1512
    public Object validate(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
 
1513
 
 
1514
        if (context == null)
 
1515
            context = fEmptyContext;
 
1516
 
 
1517
        if (validatedInfo == null)
 
1518
            validatedInfo = new ValidatedInfo();
 
1519
        else
 
1520
            validatedInfo.memberType = null;
 
1521
 
 
1522
        // first normalize string value, and convert it to actual value
 
1523
        boolean needNormalize = context==null||context.needToNormalize();
 
1524
        Object ob = getActualValue(content, context, validatedInfo, needNormalize);
 
1525
 
 
1526
        validate(context, validatedInfo);
 
1527
 
 
1528
        return ob;
 
1529
 
 
1530
    }
 
1531
 
 
1532
    /**
 
1533
     * validate a value, and return the compiled form
 
1534
     */
 
1535
    public ValidatedInfo validateWithInfo(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
 
1536
 
 
1537
        if (context == null)
 
1538
            context = fEmptyContext;
 
1539
 
 
1540
        if (validatedInfo == null)
 
1541
            validatedInfo = new ValidatedInfo();
 
1542
        else
 
1543
            validatedInfo.memberType = null;
 
1544
 
 
1545
        // first normalize string value, and convert it to actual value
 
1546
        boolean needNormalize = context==null||context.needToNormalize();
 
1547
        getActualValue(content, context, validatedInfo, needNormalize);
 
1548
 
 
1549
        validate(context, validatedInfo);
 
1550
 
 
1551
        return validatedInfo;
 
1552
 
 
1553
    }
 
1554
 
 
1555
    /**
 
1556
     * validate a value, and return the compiled form
 
1557
     */
 
1558
    public Object validate(Object content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
 
1559
 
 
1560
        if (context == null)
 
1561
            context = fEmptyContext;
 
1562
 
 
1563
        if (validatedInfo == null)
 
1564
            validatedInfo = new ValidatedInfo();
 
1565
        else
 
1566
            validatedInfo.memberType = null;
 
1567
 
 
1568
        // first normalize string value, and convert it to actual value
 
1569
        boolean needNormalize = context==null||context.needToNormalize();
 
1570
        Object ob = getActualValue(content, context, validatedInfo, needNormalize);
 
1571
 
 
1572
        validate(context, validatedInfo);
 
1573
 
 
1574
        return ob;
 
1575
 
 
1576
    }
 
1577
 
 
1578
    /**
 
1579
     * validate an actual value against this DV
 
1580
     *
 
1581
     * @param context       the validation context
 
1582
     * @param validatedInfo used to provide the actual value and member types
 
1583
     */
 
1584
    public void validate(ValidationContext context, ValidatedInfo validatedInfo)
 
1585
        throws InvalidDatatypeValueException {
 
1586
 
 
1587
        if (context == null)
 
1588
            context = fEmptyContext;
 
1589
 
 
1590
        // then validate the actual value against the facets
 
1591
        if (context.needFacetChecking() &&
 
1592
                (fFacetsDefined != 0 && fFacetsDefined != FACET_WHITESPACE)) {
 
1593
            checkFacets(validatedInfo);
 
1594
        }
 
1595
 
 
1596
        // now check extra rules: for ID/IDREF/ENTITY
 
1597
        if (context.needExtraChecking()) {
 
1598
            checkExtraRules(context, validatedInfo);
 
1599
        }
 
1600
 
 
1601
    }
 
1602
 
 
1603
    private void checkFacets(ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
 
1604
 
 
1605
        Object ob = validatedInfo.actualValue;
 
1606
        String content = validatedInfo.normalizedValue;
 
1607
        short type = validatedInfo.actualValueType;
 
1608
        ShortList itemType = validatedInfo.itemValueTypes;
 
1609
 
 
1610
        // For QName and NOTATION types, we don't check length facets
 
1611
        if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) {
 
1612
            int length = fDVs[fValidationDV].getDataLength(ob);
 
1613
 
 
1614
            // maxLength
 
1615
            if ( (fFacetsDefined & FACET_MAXLENGTH) != 0 ) {
 
1616
                if ( length > fMaxLength ) {
 
1617
                    throw new InvalidDatatypeValueException("cvc-maxLength-valid",
 
1618
                            new Object[]{content, Integer.toString(length), Integer.toString(fMaxLength), fTypeName});
 
1619
                }
 
1620
            }
 
1621
 
 
1622
            //minLength
 
1623
            if ( (fFacetsDefined & FACET_MINLENGTH) != 0 ) {
 
1624
                if ( length < fMinLength ) {
 
1625
                    throw new InvalidDatatypeValueException("cvc-minLength-valid",
 
1626
                            new Object[]{content, Integer.toString(length), Integer.toString(fMinLength), fTypeName});
 
1627
                }
 
1628
            }
 
1629
 
 
1630
            //length
 
1631
            if ( (fFacetsDefined & FACET_LENGTH) != 0 ) {
 
1632
                if ( length != fLength ) {
 
1633
                    throw new InvalidDatatypeValueException("cvc-length-valid",
 
1634
                            new Object[]{content, Integer.toString(length), Integer.toString(fLength), fTypeName});
 
1635
                }
 
1636
            }
 
1637
        }
 
1638
 
 
1639
        //enumeration
 
1640
        if ( ((fFacetsDefined & FACET_ENUMERATION) != 0 ) ) {
 
1641
            boolean present = false;
 
1642
            final int enumSize = fEnumeration.size();
 
1643
            final short primitiveType1 = convertToPrimitiveKind(type);
 
1644
            for (int i = 0; i < enumSize; i++) {
 
1645
                final short primitiveType2 = convertToPrimitiveKind(fEnumerationType[i]);
 
1646
                if ((primitiveType1 == primitiveType2 ||
 
1647
                        primitiveType1 == XSConstants.ANYSIMPLETYPE_DT && primitiveType2 == XSConstants.STRING_DT ||
 
1648
                        primitiveType1 == XSConstants.STRING_DT && primitiveType2 == XSConstants.ANYSIMPLETYPE_DT)
 
1649
                        && fEnumeration.elementAt(i).equals(ob)) {
 
1650
                    if (primitiveType1 == XSConstants.LIST_DT || primitiveType1 == XSConstants.LISTOFUNION_DT) {
 
1651
                        ShortList enumItemType = fEnumerationItemType[i];
 
1652
                        final int typeList1Length = itemType != null ? itemType.getLength() : 0;
 
1653
                        final int typeList2Length = enumItemType != null ? enumItemType.getLength() : 0;
 
1654
                        if (typeList1Length == typeList2Length) {
 
1655
                            int j;
 
1656
                            for (j = 0; j < typeList1Length; ++j) {
 
1657
                                final short primitiveItem1 = convertToPrimitiveKind(itemType.item(j));
 
1658
                                final short primitiveItem2 = convertToPrimitiveKind(enumItemType.item(j));
 
1659
                                if (primitiveItem1 != primitiveItem2) {
 
1660
                                    if (primitiveItem1 == XSConstants.ANYSIMPLETYPE_DT && primitiveItem2 == XSConstants.STRING_DT ||
 
1661
                                            primitiveItem1 == XSConstants.STRING_DT && primitiveItem2 == XSConstants.ANYSIMPLETYPE_DT) {
 
1662
                                        continue;
 
1663
                                    }
 
1664
                                    break;
 
1665
                                }
 
1666
                            }
 
1667
                            if (j == typeList1Length) {
 
1668
                                present = true;
 
1669
                                break;
 
1670
                            }
 
1671
                        }
 
1672
                    }
 
1673
                    else {
 
1674
                        present = true;
 
1675
                        break;
 
1676
                    }
 
1677
                }
 
1678
            }
 
1679
            if(!present){
 
1680
                throw new InvalidDatatypeValueException("cvc-enumeration-valid",
 
1681
                        new Object [] {content, fEnumeration.toString()});
 
1682
            }
 
1683
        }
 
1684
 
 
1685
        //fractionDigits
 
1686
        if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) {
 
1687
            int scale = fDVs[fValidationDV].getFractionDigits(ob);
 
1688
            if (scale > fFractionDigits) {
 
1689
                throw new InvalidDatatypeValueException("cvc-fractionDigits-valid",
 
1690
                        new Object[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)});
 
1691
            }
 
1692
        }
 
1693
 
 
1694
        //totalDigits
 
1695
        if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) {
 
1696
            int totalDigits = fDVs[fValidationDV].getTotalDigits(ob);
 
1697
            if (totalDigits > fTotalDigits) {
 
1698
                throw new InvalidDatatypeValueException("cvc-totalDigits-valid",
 
1699
                        new Object[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)});
 
1700
            }
 
1701
        }
 
1702
 
 
1703
        int compare;
 
1704
 
 
1705
        //maxinclusive
 
1706
        if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) {
 
1707
            compare = fDVs[fValidationDV].compare(ob, fMaxInclusive);
 
1708
            if (compare != -1 && compare != 0) {
 
1709
                throw new InvalidDatatypeValueException("cvc-maxInclusive-valid",
 
1710
                        new Object[] {content, fMaxInclusive, fTypeName});
 
1711
            }
 
1712
        }
 
1713
 
 
1714
        //maxExclusive
 
1715
        if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) {
 
1716
            compare = fDVs[fValidationDV].compare(ob, fMaxExclusive );
 
1717
            if (compare != -1) {
 
1718
                throw new InvalidDatatypeValueException("cvc-maxExclusive-valid",
 
1719
                        new Object[] {content, fMaxExclusive, fTypeName});
 
1720
            }
 
1721
        }
 
1722
 
 
1723
        //minInclusive
 
1724
        if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) {
 
1725
            compare = fDVs[fValidationDV].compare(ob, fMinInclusive);
 
1726
            if (compare != 1 && compare != 0) {
 
1727
                throw new InvalidDatatypeValueException("cvc-minInclusive-valid",
 
1728
                        new Object[] {content, fMinInclusive, fTypeName});
 
1729
            }
 
1730
        }
 
1731
 
 
1732
        //minExclusive
 
1733
        if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) {
 
1734
            compare = fDVs[fValidationDV].compare(ob, fMinExclusive);
 
1735
            if (compare != 1) {
 
1736
                throw new InvalidDatatypeValueException("cvc-minExclusive-valid",
 
1737
                        new Object[] {content, fMinExclusive, fTypeName});
 
1738
            }
 
1739
        }
 
1740
 
 
1741
    }
 
1742
 
 
1743
    private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException {
 
1744
 
 
1745
        Object ob = validatedInfo.actualValue;
 
1746
 
 
1747
        if (fVariety == VARIETY_ATOMIC) {
 
1748
 
 
1749
            fDVs[fValidationDV].checkExtraRules(ob, context);
 
1750
 
 
1751
        } else if (fVariety == VARIETY_LIST) {
 
1752
 
 
1753
            ListDV.ListData values = (ListDV.ListData)ob;
 
1754
            int len = values.getLength();
 
1755
            if (fItemType.fVariety == VARIETY_UNION) {
 
1756
                XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes;
 
1757
                XSSimpleType memberType = validatedInfo.memberType;
 
1758
                for (int i = len-1; i >= 0; i--) {
 
1759
                    validatedInfo.actualValue = values.item(i);
 
1760
                    validatedInfo.memberType = memberTypes[i];
 
1761
                    fItemType.checkExtraRules(context, validatedInfo);
 
1762
                }
 
1763
                validatedInfo.memberType = memberType;
 
1764
            } else { // (fVariety == VARIETY_ATOMIC)
 
1765
                for (int i = len-1; i >= 0; i--) {
 
1766
                    validatedInfo.actualValue = values.item(i);
 
1767
                    fItemType.checkExtraRules(context, validatedInfo);
 
1768
                }
 
1769
            }
 
1770
            validatedInfo.actualValue = values;
 
1771
 
 
1772
        } else { // (fVariety == VARIETY_UNION)
 
1773
 
 
1774
            ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo);
 
1775
 
 
1776
        }
 
1777
 
 
1778
    }// checkExtraRules()
 
1779
 
 
1780
    //we can still return object for internal use.
 
1781
    private Object getActualValue(Object content, ValidationContext context,
 
1782
            ValidatedInfo validatedInfo, boolean needNormalize)
 
1783
    throws InvalidDatatypeValueException{
 
1784
 
 
1785
        String nvalue;
 
1786
        if (needNormalize) {
 
1787
            nvalue = normalize(content, fWhiteSpace);
 
1788
        } else {
 
1789
            nvalue = content.toString();
 
1790
        }
 
1791
        if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) {
 
1792
            RegularExpression regex;
 
1793
            for (int idx = fPattern.size()-1; idx >= 0; idx--) {
 
1794
                regex = (RegularExpression)fPattern.elementAt(idx);
 
1795
                if (!regex.matches(nvalue)){
 
1796
                    throw new InvalidDatatypeValueException("cvc-pattern-valid",
 
1797
                            new Object[]{content,
 
1798
                            fPatternStr.elementAt(idx),
 
1799
 
 
1800
                            fTypeName});
 
1801
                }
 
1802
            }
 
1803
        }
 
1804
 
 
1805
        if (fVariety == VARIETY_ATOMIC) {
 
1806
 
 
1807
            // validate special kinds of token, in place of old pattern matching
 
1808
            if (fPatternType != SPECIAL_PATTERN_NONE) {
 
1809
 
 
1810
                boolean seenErr = false;
 
1811
                if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
 
1812
                    // PATTERN "\\c+"
 
1813
                    seenErr = !XMLChar.isValidNmtoken(nvalue);
 
1814
                }
 
1815
                else if (fPatternType == SPECIAL_PATTERN_NAME) {
 
1816
                    // PATTERN "\\i\\c*"
 
1817
                    seenErr = !XMLChar.isValidName(nvalue);
 
1818
                }
 
1819
                else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
 
1820
                    // PATTERN "[\\i-[:]][\\c-[:]]*"
 
1821
                    seenErr = !XMLChar.isValidNCName(nvalue);
 
1822
                }
 
1823
                if (seenErr) {
 
1824
                    throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1",
 
1825
                            new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]});
 
1826
                }
 
1827
            }
 
1828
 
 
1829
            validatedInfo.normalizedValue = nvalue;
 
1830
            Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context);
 
1831
            validatedInfo.actualValue = avalue;
 
1832
            validatedInfo.actualValueType = fBuiltInKind;
 
1833
 
 
1834
            return avalue;
 
1835
 
 
1836
        } else if (fVariety == VARIETY_LIST) {
 
1837
 
 
1838
            StringTokenizer parsedList = new StringTokenizer(nvalue, " ");
 
1839
            int countOfTokens = parsedList.countTokens() ;
 
1840
            Object[] avalue = new Object[countOfTokens];
 
1841
            boolean isUnion = fItemType.getVariety() == VARIETY_UNION;
 
1842
            short[] itemTypes = new short[isUnion ? countOfTokens : 1];
 
1843
            if (!isUnion)
 
1844
                itemTypes[0] = fItemType.fBuiltInKind;
 
1845
            XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
 
1846
            for(int i = 0 ; i < countOfTokens ; i ++){
 
1847
                // we can't call fItemType.validate(), otherwise checkExtraRules()
 
1848
                // will be called twice: once in fItemType.validate, once in
 
1849
                // validate method of this type.
 
1850
                // so we take two steps to get the actual value:
 
1851
                // 1. fItemType.getActualValue()
 
1852
                // 2. fItemType.chekcFacets()
 
1853
                avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false);
 
1854
                if (context.needFacetChecking() &&
 
1855
                        (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) {
 
1856
                    fItemType.checkFacets(validatedInfo);
 
1857
                }
 
1858
                memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType;
 
1859
                if (isUnion)
 
1860
                    itemTypes[i] = memberTypes[i].fBuiltInKind;
 
1861
            }
 
1862
 
 
1863
            ListDV.ListData v = new ListDV.ListData(avalue);
 
1864
            validatedInfo.actualValue = v;
 
1865
            validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT;
 
1866
            validatedInfo.memberType = null;
 
1867
            validatedInfo.memberTypes = memberTypes;
 
1868
            validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length);
 
1869
            validatedInfo.normalizedValue = nvalue;
 
1870
 
 
1871
            return v;
 
1872
 
 
1873
        } else { // (fVariety == VARIETY_UNION)
 
1874
            for(int i = 0 ; i < fMemberTypes.length; i++) {
 
1875
                try {
 
1876
                    // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
 
1877
                    // will be called twice: once in fMemberType[i].validate, once in
 
1878
                    // validate method of this type.
 
1879
                    // so we take two steps to get the actual value:
 
1880
                    // 1. fMemberType[i].getActualValue()
 
1881
                    // 2. fMemberType[i].chekcFacets()
 
1882
                    Object aValue = fMemberTypes[i].getActualValue(content, context, validatedInfo, true);
 
1883
                    if (context.needFacetChecking() &&
 
1884
                            (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) {
 
1885
                        fMemberTypes[i].checkFacets(validatedInfo);
 
1886
                    }
 
1887
                    validatedInfo.memberType = fMemberTypes[i];
 
1888
                    return aValue;
 
1889
                } catch(InvalidDatatypeValueException invalidValue) {
 
1890
                }
 
1891
            }
 
1892
            StringBuffer typesBuffer = new StringBuffer();
 
1893
            XSSimpleTypeDecl decl;
 
1894
            for(int i = 0;i < fMemberTypes.length; i++) {
 
1895
                if(i != 0)
 
1896
                    typesBuffer.append(" | ");
 
1897
                decl = fMemberTypes[i];
 
1898
                if(decl.fTargetNamespace != null) {
 
1899
                    typesBuffer.append('{');
 
1900
                    typesBuffer.append(decl.fTargetNamespace);
 
1901
                    typesBuffer.append('}');
 
1902
                }
 
1903
                typesBuffer.append(decl.fTypeName);
 
1904
                if(decl.fEnumeration != null) {
 
1905
                    Vector v = decl.fEnumeration;
 
1906
                    typesBuffer.append(" : [");
 
1907
                    for(int j = 0;j < v.size(); j++) {
 
1908
                        if(j != 0)
 
1909
                            typesBuffer.append(',');
 
1910
                        typesBuffer.append(v.elementAt(j));
 
1911
                    }
 
1912
                    typesBuffer.append(']');
 
1913
                }             
 
1914
            }
 
1915
            throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3",
 
1916
                    new Object[]{content, fTypeName, typesBuffer.toString()});
 
1917
        }
 
1918
 
 
1919
    }//getActualValue()
 
1920
 
 
1921
    public boolean isEqual(Object value1, Object value2) {
 
1922
        if (value1 == null) {
 
1923
            return false;
 
1924
        }
 
1925
        return value1.equals(value2);
 
1926
    }//isEqual()
 
1927
 
 
1928
    // determine whether the two values are identical
 
1929
    public boolean isIdentical (Object value1, Object value2) {
 
1930
        if (value1 == null) {
 
1931
            return false;
 
1932
        }
 
1933
        return fDVs[fValidationDV].isIdentical(value1, value2);
 
1934
    }//isIdentical()
 
1935
 
 
1936
    // normalize the string according to the whiteSpace facet
 
1937
    public static String normalize(String content, short ws) {
 
1938
        int len = content == null ? 0 : content.length();
 
1939
        if (len == 0 || ws == WS_PRESERVE)
 
1940
            return content;
 
1941
 
 
1942
        StringBuffer sb = new StringBuffer();
 
1943
        if (ws == WS_REPLACE) {
 
1944
            char ch;
 
1945
            // when it's replace, just replace #x9, #xa, #xd by #x20
 
1946
            for (int i = 0; i < len; i++) {
 
1947
                ch = content.charAt(i);
 
1948
                if (ch != 0x9 && ch != 0xa && ch != 0xd)
 
1949
                    sb.append(ch);
 
1950
                else
 
1951
                    sb.append((char)0x20);
 
1952
            }
 
1953
        } else {
 
1954
            char ch;
 
1955
            int i;
 
1956
            boolean isLeading = true;
 
1957
            // when it's collapse
 
1958
            for (i = 0; i < len; i++) {
 
1959
                ch = content.charAt(i);
 
1960
                // append real characters, so we passed leading ws
 
1961
                if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
 
1962
                    sb.append(ch);
 
1963
                    isLeading = false;
 
1964
                }
 
1965
                else {
 
1966
                    // for whitespaces, we skip all following ws
 
1967
                    for (; i < len-1; i++) {
 
1968
                        ch = content.charAt(i+1);
 
1969
                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
 
1970
                            break;
 
1971
                    }
 
1972
                    // if it's not a leading or tailing ws, then append a space
 
1973
                    if (i < len - 1 && !isLeading)
 
1974
                        sb.append((char)0x20);
 
1975
                }
 
1976
            }
 
1977
        }
 
1978
 
 
1979
        return sb.toString();
 
1980
    }
 
1981
 
 
1982
    // normalize the string according to the whiteSpace facet
 
1983
    protected String normalize(Object content, short ws) {
 
1984
        if (content == null)
 
1985
            return null;
 
1986
 
 
1987
        // If pattern is not defined, we can skip some of the normalization.
 
1988
        // Otherwise we have to normalize the data for correct result of
 
1989
        // pattern validation.
 
1990
        if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) {
 
1991
            short norm_type = fDVNormalizeType[fValidationDV];
 
1992
            if (norm_type == NORMALIZE_NONE) {
 
1993
                return content.toString();
 
1994
            }
 
1995
            else if (norm_type == NORMALIZE_TRIM) {
 
1996
                return XMLChar.trim(content.toString());
 
1997
            }
 
1998
        }
 
1999
 
 
2000
        if (!(content instanceof StringBuffer)) {
 
2001
            String strContent = content.toString();
 
2002
            return normalize(strContent, ws);
 
2003
        }
 
2004
 
 
2005
        StringBuffer sb = (StringBuffer)content;
 
2006
        int len = sb.length();
 
2007
        if (len == 0)
 
2008
            return "";
 
2009
        if (ws == WS_PRESERVE)
 
2010
            return sb.toString();
 
2011
 
 
2012
        if (ws == WS_REPLACE) {
 
2013
            char ch;
 
2014
            // when it's replace, just replace #x9, #xa, #xd by #x20
 
2015
            for (int i = 0; i < len; i++) {
 
2016
                ch = sb.charAt(i);
 
2017
                if (ch == 0x9 || ch == 0xa || ch == 0xd)
 
2018
                    sb.setCharAt(i, (char)0x20);
 
2019
            }
 
2020
        } else {
 
2021
            char ch;
 
2022
            int i, j = 0;
 
2023
            boolean isLeading = true;
 
2024
            // when it's collapse
 
2025
            for (i = 0; i < len; i++) {
 
2026
                ch = sb.charAt(i);
 
2027
                // append real characters, so we passed leading ws
 
2028
                if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) {
 
2029
                    sb.setCharAt(j++, ch);
 
2030
                    isLeading = false;
 
2031
                }
 
2032
                else {
 
2033
                    // for whitespaces, we skip all following ws
 
2034
                    for (; i < len-1; i++) {
 
2035
                        ch = sb.charAt(i+1);
 
2036
                        if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20)
 
2037
                            break;
 
2038
                    }
 
2039
                    // if it's not a leading or tailing ws, then append a space
 
2040
                    if (i < len - 1 && !isLeading)
 
2041
                        sb.setCharAt(j++, (char)0x20);
 
2042
                }
 
2043
            }
 
2044
            sb.setLength(j);
 
2045
        }
 
2046
 
 
2047
        return sb.toString();
 
2048
    }
 
2049
 
 
2050
    void reportError(String key, Object[] args) throws InvalidDatatypeFacetException {
 
2051
        throw new InvalidDatatypeFacetException(key, args);
 
2052
    }
 
2053
 
 
2054
 
 
2055
    private String whiteSpaceValue(short ws){
 
2056
        return WS_FACET_STRING[ws];
 
2057
    }
 
2058
 
 
2059
    /**
 
2060
     *  Fundamental Facet: ordered.
 
2061
     */
 
2062
    public short getOrdered() {
 
2063
        return fOrdered;
 
2064
    }
 
2065
 
 
2066
    /**
 
2067
     * Fundamental Facet: bounded.
 
2068
     */
 
2069
    public boolean getBounded(){
 
2070
        return fBounded;
 
2071
    }
 
2072
 
 
2073
    /**
 
2074
     * Fundamental Facet: cardinality.
 
2075
     */
 
2076
    public boolean getFinite(){
 
2077
        return fFinite;
 
2078
    }
 
2079
 
 
2080
    /**
 
2081
     * Fundamental Facet: numeric.
 
2082
     */
 
2083
    public boolean getNumeric(){
 
2084
        return fNumeric;
 
2085
    }
 
2086
 
 
2087
    /**
 
2088
     * Convenience method. [Facets]: check whether a facet is defined on this
 
2089
     * type.
 
2090
     * @param facetName  The name of the facet.
 
2091
     * @return  True if the facet is defined, false otherwise.
 
2092
     */
 
2093
    public boolean isDefinedFacet(short facetName) {
 
2094
        if ((fFacetsDefined & facetName) != 0)
 
2095
            return true;
 
2096
        if (fPatternType != SPECIAL_PATTERN_NONE)
 
2097
            return facetName == FACET_PATTERN;
 
2098
        if (fValidationDV == DV_INTEGER)
 
2099
            return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS;
 
2100
        return false;
 
2101
    }
 
2102
 
 
2103
    /**
 
2104
     * [facets]: all facets defined on this type. The value is a bit
 
2105
     * combination of FACET_XXX constants of all defined facets.
 
2106
     */
 
2107
    public short getDefinedFacets() {
 
2108
        if (fPatternType != SPECIAL_PATTERN_NONE)
 
2109
            return (short)(fFacetsDefined | FACET_PATTERN);
 
2110
        if (fValidationDV == DV_INTEGER)
 
2111
            return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS);
 
2112
        return fFacetsDefined;
 
2113
    }
 
2114
 
 
2115
    /**
 
2116
     * Convenience method. [Facets]: check whether a facet is defined and
 
2117
     * fixed on this type.
 
2118
     * @param facetName  The name of the facet.
 
2119
     * @return  True if the facet is fixed, false otherwise.
 
2120
     */
 
2121
    public boolean isFixedFacet(short facetName) {
 
2122
        if ((fFixedFacet & facetName) != 0)
 
2123
            return true;
 
2124
        if (fValidationDV == DV_INTEGER)
 
2125
            return facetName == FACET_FRACTIONDIGITS;
 
2126
        return false;
 
2127
    }
 
2128
 
 
2129
    /**
 
2130
     * [facets]: all defined facets for this type which are fixed.
 
2131
     */
 
2132
    public short getFixedFacets() {
 
2133
        if (fValidationDV == DV_INTEGER)
 
2134
            return (short)(fFixedFacet | FACET_FRACTIONDIGITS);
 
2135
        return fFixedFacet;
 
2136
    }
 
2137
 
 
2138
    /**
 
2139
     * Convenience method. Returns a value of a single constraining facet for
 
2140
     * this simple type definition. This method must not be used to retrieve
 
2141
     * values for <code>enumeration</code> and <code>pattern</code> facets.
 
2142
     * @param facetName The name of the facet, i.e.
 
2143
     *   <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see
 
2144
     *   <code>XSConstants</code>). To retrieve the value for a pattern or
 
2145
     *   an enumeration, see <code>enumeration</code> and
 
2146
     *   <code>pattern</code>.
 
2147
     * @return A value of the facet specified in <code>facetName</code> for
 
2148
     *   this simple type definition or <code>null</code>.
 
2149
     */
 
2150
    public String getLexicalFacetValue(short facetName) {
 
2151
        switch (facetName) {
 
2152
            case FACET_LENGTH:
 
2153
                return (fLength == -1)?null:Integer.toString(fLength);
 
2154
            case FACET_MINLENGTH:
 
2155
                return (fMinLength == -1)?null:Integer.toString(fMinLength);
 
2156
            case FACET_MAXLENGTH:
 
2157
                return (fMaxLength == -1)?null:Integer.toString(fMaxLength);
 
2158
            case FACET_WHITESPACE:
 
2159
                return WS_FACET_STRING[fWhiteSpace];
 
2160
            case FACET_MAXINCLUSIVE:
 
2161
                return (fMaxInclusive == null)?null:fMaxInclusive.toString();
 
2162
            case FACET_MAXEXCLUSIVE:
 
2163
                return (fMaxExclusive == null)?null:fMaxExclusive.toString();
 
2164
            case FACET_MINEXCLUSIVE:
 
2165
                return (fMinExclusive == null)?null:fMinExclusive.toString();
 
2166
            case FACET_MININCLUSIVE:
 
2167
                return (fMinInclusive == null)?null:fMinInclusive.toString();
 
2168
            case FACET_TOTALDIGITS:
 
2169
                return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits);
 
2170
            case FACET_FRACTIONDIGITS:
 
2171
                if (fValidationDV == DV_INTEGER) {
 
2172
                    return "0";
 
2173
                }
 
2174
                return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits);
 
2175
        }
 
2176
        return null;
 
2177
    }
 
2178
 
 
2179
    /**
 
2180
     * A list of enumeration values if it exists, otherwise an empty
 
2181
     * <code>StringList</code>.
 
2182
     */
 
2183
    public StringList getLexicalEnumeration() {
 
2184
        if (fLexicalEnumeration == null){
 
2185
            if (fEnumeration == null)
 
2186
                return StringListImpl.EMPTY_LIST;
 
2187
            int size = fEnumeration.size();
 
2188
            String[] strs = new String[size];
 
2189
            for (int i = 0; i < size; i++)
 
2190
                strs[i] = fEnumeration.elementAt(i).toString();
 
2191
            fLexicalEnumeration = new StringListImpl(strs, size);
 
2192
        }
 
2193
        return fLexicalEnumeration;
 
2194
    }
 
2195
 
 
2196
    /**
 
2197
     * A list of actual enumeration values if it exists, otherwise an empty
 
2198
     * <code>ObjectList</code>.
 
2199
     */
 
2200
    public ObjectList getActualEnumeration() {
 
2201
        if (fActualEnumeration == null) {
 
2202
            fActualEnumeration = new ObjectList () {
 
2203
                public int getLength() {
 
2204
                    return (fEnumeration != null) ? fEnumeration.size() : 0;
 
2205
                }
 
2206
                public boolean contains(Object item) {
 
2207
                    return (fEnumeration != null && fEnumeration.contains(item));
 
2208
                }
 
2209
                public Object item(int index) {
 
2210
                    if (index < 0 || index >= getLength()) {
 
2211
                        return null;
 
2212
                    }
 
2213
                    return fEnumeration.elementAt(index);
 
2214
                }
 
2215
            };
 
2216
        }
 
2217
        return fActualEnumeration;
 
2218
    }
 
2219
 
 
2220
    /**
 
2221
     * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns
 
2222
     * null
 
2223
     */
 
2224
    public ObjectList getEnumerationItemTypeList() {
 
2225
        if (fEnumerationItemTypeList == null) {
 
2226
            if(fEnumerationItemType == null)
 
2227
                return null;
 
2228
            fEnumerationItemTypeList = new ObjectList () {
 
2229
                public int getLength() {
 
2230
                    return (fEnumerationItemType != null) ? fEnumerationItemType.length : 0;
 
2231
                }
 
2232
                public boolean contains(Object item) {
 
2233
                    if(fEnumerationItemType == null || !(item instanceof ShortList))
 
2234
                        return false;
 
2235
                    for(int i = 0;i < fEnumerationItemType.length; i++)
 
2236
                        if(fEnumerationItemType[i] == item)
 
2237
                            return true;
 
2238
                    return false;
 
2239
                }
 
2240
                public Object item(int index) {
 
2241
                    if (index < 0 || index >= getLength()) {
 
2242
                        return null;
 
2243
                    }
 
2244
                    return fEnumerationItemType[index];
 
2245
                }
 
2246
            };
 
2247
        }
 
2248
        return fEnumerationItemTypeList;
 
2249
    }
 
2250
 
 
2251
    public ShortList getEnumerationTypeList() {
 
2252
        if (fEnumerationTypeList == null) {
 
2253
            if (fEnumerationType == null) {
 
2254
                return ShortListImpl.EMPTY_LIST;
 
2255
            }
 
2256
            fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length);
 
2257
        }
 
2258
        return fEnumerationTypeList;
 
2259
    }
 
2260
 
 
2261
    /**
 
2262
     * A list of pattern values if it exists, otherwise an empty
 
2263
     * <code>StringList</code>.
 
2264
     */
 
2265
    public StringList getLexicalPattern() {
 
2266
        if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null)
 
2267
            return StringListImpl.EMPTY_LIST;
 
2268
        if (fLexicalPattern == null){
 
2269
            int size = fPatternStr == null ? 0 : fPatternStr.size();
 
2270
            String[] strs;
 
2271
            if (fPatternType == SPECIAL_PATTERN_NMTOKEN) {
 
2272
                strs = new String[size+1];
 
2273
                strs[size] = "\\c+";
 
2274
            }
 
2275
            else if (fPatternType == SPECIAL_PATTERN_NAME) {
 
2276
                strs = new String[size+1];
 
2277
                strs[size] = "\\i\\c*";
 
2278
            }
 
2279
            else if (fPatternType == SPECIAL_PATTERN_NCNAME) {
 
2280
                strs = new String[size+2];
 
2281
                strs[size] = "\\i\\c*";
 
2282
                strs[size+1] = "[\\i-[:]][\\c-[:]]*";
 
2283
            }
 
2284
            else if (fValidationDV == DV_INTEGER) {
 
2285
                strs = new String[size+1];
 
2286
                strs[size] = "[\\-+]?[0-9]+";
 
2287
            }
 
2288
            else {
 
2289
                strs = new String[size];
 
2290
            }
 
2291
            for (int i = 0; i < size; i++)
 
2292
                strs[i] = (String)fPatternStr.elementAt(i);
 
2293
            fLexicalPattern = new StringListImpl(strs, strs.length);
 
2294
        }
 
2295
        return fLexicalPattern;
 
2296
    }
 
2297
 
 
2298
    /**
 
2299
     * [annotations]: a set of annotations for this simple type component if
 
2300
     * it exists, otherwise an empty <code>XSObjectList</code>.
 
2301
     */
 
2302
    public XSObjectList getAnnotations() {
 
2303
        return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
 
2304
    }
 
2305
 
 
2306
    private void calcFundamentalFacets() {
 
2307
        setOrdered();
 
2308
        setNumeric();
 
2309
        setBounded();
 
2310
        setCardinality();
 
2311
    }
 
2312
 
 
2313
    private void setOrdered(){
 
2314
 
 
2315
        // 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).
 
2316
        if(fVariety == VARIETY_ATOMIC){
 
2317
            this.fOrdered = fBase.fOrdered;
 
2318
        }
 
2319
 
 
2320
        // When {variety} is list, {value} is false.
 
2321
        else if(fVariety == VARIETY_LIST){
 
2322
            this.fOrdered = ORDERED_FALSE;
 
2323
        }
 
2324
 
 
2325
        // When {variety} is union, the {value} is partial unless one of the following:
 
2326
        // 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.
 
2327
        // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false.
 
2328
        else if(fVariety == VARIETY_UNION){
 
2329
            int length = fMemberTypes.length;
 
2330
            // REVISIT: is the length possible to be 0?
 
2331
            if (length == 0) {
 
2332
                this.fOrdered = ORDERED_PARTIAL;
 
2333
                return;
 
2334
            }
 
2335
            // we need to process the first member type before entering the loop
 
2336
            short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV);
 
2337
            boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE;
 
2338
            boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE;
 
2339
            // for the other member types, check whether the value is false
 
2340
            // and whether they have the same ancestor as the first one
 
2341
            for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) {
 
2342
                if (commonAnc)
 
2343
                    commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV);
 
2344
                if (allFalse)
 
2345
                    allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE;
 
2346
            }
 
2347
            if (commonAnc) {
 
2348
                // REVISIT: all member types should have the same ordered value
 
2349
                //          just use the first one. Can we assume this?
 
2350
                this.fOrdered = fMemberTypes[0].fOrdered;
 
2351
            } else if (allFalse) {
 
2352
                this.fOrdered = ORDERED_FALSE;
 
2353
            } else {
 
2354
                this.fOrdered = ORDERED_PARTIAL;
 
2355
            }
 
2356
        }
 
2357
 
 
2358
    }//setOrdered
 
2359
 
 
2360
    private void setNumeric(){
 
2361
        if(fVariety == VARIETY_ATOMIC){
 
2362
            this.fNumeric = fBase.fNumeric;
 
2363
        }
 
2364
        else if(fVariety == VARIETY_LIST){
 
2365
            this.fNumeric = false;
 
2366
        }
 
2367
        else if(fVariety == VARIETY_UNION){
 
2368
            XSSimpleType[] memberTypes = fMemberTypes;
 
2369
            for(int i = 0 ; i < memberTypes.length ; i++){
 
2370
                if(!memberTypes[i].getNumeric() ){
 
2371
                    this.fNumeric = false;
 
2372
                    return;
 
2373
                }
 
2374
            }
 
2375
            this.fNumeric = true;
 
2376
        }
 
2377
 
 
2378
    }//setNumeric
 
2379
 
 
2380
    private void setBounded(){
 
2381
        if(fVariety == VARIETY_ATOMIC){
 
2382
            if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0))
 
2383
                    &&  (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0)  || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){
 
2384
                this.fBounded = true;
 
2385
            }
 
2386
            else{
 
2387
                this.fBounded = false;
 
2388
            }
 
2389
        }
 
2390
        else if(fVariety == VARIETY_LIST){
 
2391
            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
 
2392
                    &&  ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
 
2393
                this.fBounded = true;
 
2394
            }
 
2395
            else{
 
2396
                this.fBounded = false;
 
2397
            }
 
2398
 
 
2399
        }
 
2400
        else if(fVariety == VARIETY_UNION){
 
2401
 
 
2402
            XSSimpleTypeDecl [] memberTypes = this.fMemberTypes;
 
2403
            short ancestorId = 0 ;
 
2404
 
 
2405
            if(memberTypes.length > 0){
 
2406
                ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV);
 
2407
            }
 
2408
 
 
2409
            for(int i = 0 ; i < memberTypes.length ; i++){
 
2410
                if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){
 
2411
                    this.fBounded = false;
 
2412
                    return;
 
2413
                }
 
2414
            }
 
2415
            this.fBounded = true;
 
2416
        }
 
2417
 
 
2418
    }//setBounded
 
2419
 
 
2420
    private boolean specialCardinalityCheck(){
 
2421
        if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH)
 
2422
                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY)
 
2423
                || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){
 
2424
            return true;
 
2425
        }
 
2426
        return false;
 
2427
 
 
2428
    } //specialCardinalityCheck()
 
2429
 
 
2430
    private void setCardinality(){
 
2431
        if(fVariety == VARIETY_ATOMIC){
 
2432
            if(fBase.fFinite){
 
2433
                this.fFinite = true;
 
2434
            }
 
2435
            else {// (!fBase.fFinite)
 
2436
                if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )
 
2437
                        || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){
 
2438
                    this.fFinite = true;
 
2439
                }
 
2440
                else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ))
 
2441
                        && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){
 
2442
                    if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){
 
2443
                        this.fFinite = true;
 
2444
                    }
 
2445
                    else{
 
2446
                        this.fFinite = false;
 
2447
                    }
 
2448
                }
 
2449
                else{
 
2450
                    this.fFinite = false;
 
2451
                }
 
2452
            }
 
2453
        }
 
2454
        else if(fVariety == VARIETY_LIST){
 
2455
            if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 )
 
2456
                    && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){
 
2457
                this.fFinite = true;
 
2458
            }
 
2459
            else{
 
2460
                this.fFinite = false;
 
2461
            }
 
2462
 
 
2463
        }
 
2464
        else if(fVariety == VARIETY_UNION){
 
2465
            XSSimpleType [] memberTypes = fMemberTypes;
 
2466
            for(int i = 0 ; i < memberTypes.length ; i++){
 
2467
                if(!(memberTypes[i].getFinite()) ){
 
2468
                    this.fFinite = false;
 
2469
                    return;
 
2470
                }
 
2471
            }
 
2472
            this.fFinite = true;
 
2473
        }
 
2474
 
 
2475
    }//setCardinality
 
2476
 
 
2477
    private short getPrimitiveDV(short validationDV){
 
2478
 
 
2479
        if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){
 
2480
            return DV_STRING;
 
2481
        }
 
2482
        else if (validationDV == DV_INTEGER) {
 
2483
            return DV_DECIMAL;
 
2484
        }
 
2485
        else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) {
 
2486
            return DV_DURATION;
 
2487
        }
 
2488
        else {
 
2489
            return validationDV;
 
2490
        }
 
2491
 
 
2492
    }//getPrimitiveDV()
 
2493
 
 
2494
    public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) {
 
2495
        // REVISIT: implement according to derivation
 
2496
 
 
2497
        // ancestor is null, retur false
 
2498
        if (ancestor == null)
 
2499
            return false;
 
2500
        // ancestor is anyType, return true
 
2501
        // anyType is the only type whose base type is itself
 
2502
        if (ancestor.getBaseType() == ancestor)
 
2503
            return true;
 
2504
        // recursively get base, and compare it with ancestor
 
2505
        XSTypeDefinition type = this;
 
2506
        while (type != ancestor &&                      // compare with ancestor
 
2507
                type != fAnySimpleType) {  // reached anySimpleType
 
2508
            type = type.getBaseType();
 
2509
        }
 
2510
 
 
2511
        return type == ancestor;
 
2512
    }
 
2513
 
 
2514
    public boolean derivedFrom(String ancestorNS, String ancestorName, short derivation) {
 
2515
        // REVISIT: implement according to derivation
 
2516
 
 
2517
        // ancestor is null, retur false
 
2518
        if (ancestorName == null)
 
2519
            return false;
 
2520
        // ancestor is anyType, return true
 
2521
        if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) &&
 
2522
                ANY_TYPE.equals(ancestorName)) {
 
2523
            return true;
 
2524
        }
 
2525
 
 
2526
        // recursively get base, and compare it with ancestor
 
2527
        XSTypeDefinition type = this;
 
2528
        while (!(ancestorName.equals(type.getName()) &&
 
2529
                ((ancestorNS == null && type.getNamespace() == null) ||
 
2530
                        (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) &&   // compare with ancestor
 
2531
                        type != fAnySimpleType) {  // reached anySimpleType
 
2532
            type = (XSTypeDefinition)type.getBaseType();
 
2533
        }
 
2534
 
 
2535
        return type != fAnySimpleType;
 
2536
    }
 
2537
 
 
2538
    /**
 
2539
     * Checks if a type is derived from another by restriction, given the name
 
2540
     * and namespace. See:
 
2541
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 
2542
     * 
 
2543
     * @param ancestorNS
 
2544
     *            The namspace of the ancestor type declaration
 
2545
     * @param ancestorName
 
2546
     *            The name of the ancestor type declaration
 
2547
     * @param derivationMethod
 
2548
     *            The derivation method
 
2549
     * 
 
2550
     * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method. 
 
2551
     */
 
2552
    public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName, int derivationMethod) {
 
2553
 
 
2554
        // ancestor is null, return false
 
2555
        if (ancestorName == null)
 
2556
            return false;
 
2557
 
 
2558
        // ancestor is anyType, return true
 
2559
        if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS)
 
2560
                && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName)
 
2561
                && (((derivationMethod  & DERIVATION_RESTRICTION) != 0) 
 
2562
                        || (derivationMethod  == DERIVATION_ANY))) {
 
2563
            return true;
 
2564
        }
 
2565
 
 
2566
        // restriction
 
2567
        if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
 
2568
            if (isDerivedByRestriction(ancestorNS, ancestorName, this)) {
 
2569
                return true;
 
2570
            }
 
2571
        }
 
2572
 
 
2573
        // list
 
2574
        if ((derivationMethod & DERIVATION_LIST) != 0) {
 
2575
            if (isDerivedByList(ancestorNS, ancestorName, this)) {
 
2576
                return true;
 
2577
            }
 
2578
        }
 
2579
 
 
2580
        // union
 
2581
        if ((derivationMethod & DERIVATION_UNION) != 0) {
 
2582
            if (isDerivedByUnion(ancestorNS, ancestorName, this)) {
 
2583
                return true;
 
2584
            }
 
2585
        }
 
2586
 
 
2587
        // extension
 
2588
        if (((derivationMethod & DERIVATION_EXTENSION) != 0)
 
2589
                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
 
2590
                        && ((derivationMethod & DERIVATION_LIST) == 0) 
 
2591
                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
 
2592
            return false;
 
2593
        }
 
2594
 
 
2595
        // If the value of the parameter is 0 i.e. no bit (corresponding to
 
2596
        // restriction, list, extension or union) is set to 1 for the 
 
2597
        // derivationMethod parameter.   
 
2598
        if (((derivationMethod & DERIVATION_EXTENSION) == 0)
 
2599
                && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
 
2600
                        && ((derivationMethod & DERIVATION_LIST) == 0) 
 
2601
                        && ((derivationMethod & DERIVATION_UNION) == 0))) {
 
2602
            return isDerivedByAny(ancestorNS, ancestorName, this);
 
2603
        }
 
2604
 
 
2605
        return false;
 
2606
    }
 
2607
 
 
2608
 
 
2609
    /**
 
2610
     * Checks if a type is derived from another by any combination of restriction, list ir union. See:
 
2611
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 
2612
     * 
 
2613
     * @param ancestorNS
 
2614
     *            The namspace of the ancestor type declaration
 
2615
     * @param ancestorName
 
2616
     *            The name of the ancestor type declaration
 
2617
     * @param type
 
2618
     *            The reference type definition
 
2619
     * 
 
2620
     * @return boolean True if the type is derived by restriciton for the reference type
 
2621
     */
 
2622
    private boolean isDerivedByAny(String ancestorNS, String ancestorName,
 
2623
            XSTypeDefinition type) {
 
2624
 
 
2625
        boolean derivedFrom = false;
 
2626
        XSTypeDefinition oldType = null;
 
2627
        // for each base, item or member type
 
2628
        while (type != null && type != oldType)  {
 
2629
 
 
2630
            // If the ancestor type is reached or is the same as this type.
 
2631
            if ((ancestorName.equals(type.getName()))
 
2632
                    && ((ancestorNS == null && type.getNamespace() == null) 
 
2633
                            || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
 
2634
                derivedFrom = true;
 
2635
                break;
 
2636
            }
 
2637
 
 
2638
            // check if derived by restriction or list or union
 
2639
            if (isDerivedByRestriction(ancestorNS, ancestorName, type)) {
 
2640
                return true;
 
2641
            } else if (isDerivedByList(ancestorNS, ancestorName, type)) {
 
2642
                return true;
 
2643
            } else  if (isDerivedByUnion(ancestorNS, ancestorName, type)) {
 
2644
                return true;
 
2645
            }
 
2646
            oldType = type;
 
2647
            // get the base, item or member type depending on the variety
 
2648
            if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT
 
2649
                    || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) {
 
2650
                type = type.getBaseType();
 
2651
            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) {
 
2652
                for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) {
 
2653
                    return isDerivedByAny(ancestorNS, ancestorName,
 
2654
                            (XSTypeDefinition) ((XSSimpleTypeDecl) type)
 
2655
                            .getMemberTypes().item(i));
 
2656
                }
 
2657
            } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) {
 
2658
                type = ((XSSimpleTypeDecl) type).getItemType();
 
2659
            }
 
2660
        }
 
2661
 
 
2662
        return derivedFrom;
 
2663
    }
 
2664
 
 
2665
    /**
 
2666
     * DOM Level 3 
 
2667
     * Checks if a type is derived from another by restriction. See:
 
2668
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 
2669
     * 
 
2670
     * @param ancestorNS
 
2671
     *            The namspace of the ancestor type declaration
 
2672
     * @param ancestorName
 
2673
     *            The name of the ancestor type declaration
 
2674
     * @param type
 
2675
     *            The reference type definition
 
2676
     * 
 
2677
     * @return boolean True if the type is derived by restriciton for the
 
2678
     *         reference type
 
2679
     */
 
2680
    private boolean isDerivedByRestriction (String ancestorNS, String ancestorName, XSTypeDefinition type) {
 
2681
        XSTypeDefinition oldType = null;
 
2682
        while (type != null && type != oldType) {
 
2683
            if ((ancestorName.equals(type.getName()))
 
2684
                    && ((ancestorNS != null && ancestorNS.equals(type.getNamespace())) 
 
2685
                            || (type.getNamespace() == null && ancestorNS == null))) { 
 
2686
 
 
2687
                return true;
 
2688
            }
 
2689
            oldType = type;
 
2690
            type = type.getBaseType();
 
2691
        }
 
2692
 
 
2693
        return false;
 
2694
    }
 
2695
 
 
2696
    /**
 
2697
     * Checks if a type is derived from another by list. See:
 
2698
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 
2699
     * 
 
2700
     * @param ancestorNS
 
2701
     *            The namspace of the ancestor type declaration
 
2702
     * @param ancestorName
 
2703
     *            The name of the ancestor type declaration
 
2704
     * @param type
 
2705
     *            The reference type definition
 
2706
     * 
 
2707
     * @return boolean True if the type is derived by list for the reference type
 
2708
     */    
 
2709
    private boolean isDerivedByList (String ancestorNS, String ancestorName, XSTypeDefinition type) {
 
2710
        // If the variety is union
 
2711
        if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) {
 
2712
 
 
2713
            // get the {item type}
 
2714
            XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType();
 
2715
 
 
2716
            // T2 is the {item type definition}
 
2717
            if (itemType != null) {
 
2718
 
 
2719
                // T2 is derived from the other type definition by DERIVATION_RESTRICTION
 
2720
                if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) {
 
2721
                    return true;
 
2722
                } 
 
2723
            }
 
2724
        }
 
2725
        return false;
 
2726
    }
 
2727
 
 
2728
    /**
 
2729
     * Checks if a type is derived from another by union.  See:
 
2730
     * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 
2731
     * 
 
2732
     * @param ancestorNS
 
2733
     *            The namspace of the ancestor type declaration
 
2734
     * @param ancestorName
 
2735
     *            The name of the ancestor type declaration
 
2736
     * @param type
 
2737
     *            The reference type definition
 
2738
     * 
 
2739
     * @return boolean True if the type is derived by union for the reference type
 
2740
     */    
 
2741
    private boolean isDerivedByUnion (String ancestorNS, String ancestorName, XSTypeDefinition type) {
 
2742
 
 
2743
        // If the variety is union
 
2744
        if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) {
 
2745
 
 
2746
            // get member types
 
2747
            XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes();
 
2748
 
 
2749
            for (int i = 0; i < memberTypes.getLength(); i++) {
 
2750
                // One of the {member type definitions} is T2.
 
2751
                if (memberTypes.item(i) != null) {
 
2752
                    // T2 is derived from the other type definition by DERIVATION_RESTRICTION
 
2753
                    if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) {
 
2754
                        return true;
 
2755
                    } 
 
2756
                }
 
2757
            }   
 
2758
        }
 
2759
        return false;
 
2760
    }
 
2761
 
 
2762
 
 
2763
    static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT);
 
2764
 
 
2765
    static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT);
 
2766
 
 
2767
    /**
 
2768
     * Validation context used to validate facet values.
 
2769
     */
 
2770
    static final ValidationContext fDummyContext = new ValidationContext() {
 
2771
        public boolean needFacetChecking() {
 
2772
            return true;
 
2773
        }
 
2774
 
 
2775
        public boolean needExtraChecking() {
 
2776
            return false;
 
2777
        }
 
2778
        public boolean needToNormalize() {
 
2779
            return false;
 
2780
        }
 
2781
        public boolean useNamespaces() {
 
2782
            return true;
 
2783
        }
 
2784
 
 
2785
        public boolean isEntityDeclared(String name) {
 
2786
            return false;
 
2787
        }
 
2788
 
 
2789
        public boolean isEntityUnparsed(String name) {
 
2790
            return false;
 
2791
        }
 
2792
 
 
2793
        public boolean isIdDeclared(String name) {
 
2794
            return false;
 
2795
        }
 
2796
 
 
2797
        public void addId(String name) {
 
2798
        }
 
2799
 
 
2800
        public void addIdRef(String name) {
 
2801
        }
 
2802
 
 
2803
        public String getSymbol (String symbol) {
 
2804
            return symbol.intern();
 
2805
        }
 
2806
 
 
2807
        public String getURI(String prefix) {
 
2808
            return null;
 
2809
        }
 
2810
    };
 
2811
 
 
2812
    private boolean fAnonymous = false;
 
2813
 
 
2814
    /**
 
2815
     * A wrapper of ValidationContext, to provide a way of switching to a
 
2816
     * different Namespace declaration context.
 
2817
     */
 
2818
    static final class ValidationContextImpl implements ValidationContext {
 
2819
 
 
2820
        final ValidationContext fExternal;
 
2821
        
 
2822
        ValidationContextImpl(ValidationContext external) {
 
2823
            fExternal = external;
 
2824
        }
 
2825
 
 
2826
        NamespaceContext fNSContext;
 
2827
        void setNSContext(NamespaceContext nsContext) {
 
2828
            fNSContext = nsContext;
 
2829
        }
 
2830
 
 
2831
        public boolean needFacetChecking() {
 
2832
            return fExternal.needFacetChecking();
 
2833
        }
 
2834
 
 
2835
        public boolean needExtraChecking() {
 
2836
            return fExternal.needExtraChecking();
 
2837
        }
 
2838
        public boolean needToNormalize() {
 
2839
            return fExternal.needToNormalize();
 
2840
        }
 
2841
        // schema validation is predicated upon namespaces
 
2842
        public boolean useNamespaces() {
 
2843
            return true;
 
2844
        }
 
2845
 
 
2846
        public boolean isEntityDeclared (String name) {
 
2847
            return fExternal.isEntityDeclared(name);
 
2848
        }
 
2849
 
 
2850
        public boolean isEntityUnparsed (String name) {
 
2851
            return fExternal.isEntityUnparsed(name);
 
2852
        }
 
2853
 
 
2854
        public boolean isIdDeclared (String name) {
 
2855
            return fExternal.isIdDeclared(name);
 
2856
        }
 
2857
 
 
2858
        public void addId(String name) {
 
2859
            fExternal.addId(name);
 
2860
        }
 
2861
 
 
2862
        public void addIdRef(String name) {
 
2863
            fExternal.addIdRef(name);
 
2864
        }
 
2865
 
 
2866
        public String getSymbol (String symbol) {
 
2867
            return fExternal.getSymbol(symbol);
 
2868
        }
 
2869
 
 
2870
        public String getURI(String prefix) {
 
2871
            if (fNSContext == null) {
 
2872
                return fExternal.getURI(prefix);
 
2873
            }
 
2874
            else {
 
2875
                return fNSContext.getURI(prefix);
 
2876
            }
 
2877
        }
 
2878
    }
 
2879
 
 
2880
    public void reset(){
 
2881
 
 
2882
        // if it's immutable, can't be reset:
 
2883
        if (fIsImmutable) return;
 
2884
        fItemType = null;
 
2885
        fMemberTypes = null;
 
2886
 
 
2887
        fTypeName = null;
 
2888
        fTargetNamespace = null;
 
2889
        fFinalSet = 0;
 
2890
        fBase = null;
 
2891
        fVariety = -1;
 
2892
        fValidationDV = -1;
 
2893
 
 
2894
        fFacetsDefined = 0;
 
2895
        fFixedFacet = 0;
 
2896
 
 
2897
        //for constraining facets
 
2898
        fWhiteSpace = 0;
 
2899
        fLength = -1;
 
2900
        fMinLength = -1;
 
2901
        fMaxLength = -1;
 
2902
        fTotalDigits = -1;
 
2903
        fFractionDigits = -1;
 
2904
        fPattern = null;
 
2905
        fPatternStr = null;
 
2906
        fEnumeration = null;
 
2907
        fEnumerationType = null;
 
2908
        fEnumerationItemType = null;
 
2909
        fLexicalPattern = null;
 
2910
        fLexicalEnumeration = null;
 
2911
        fMaxInclusive = null;
 
2912
        fMaxExclusive = null;
 
2913
        fMinExclusive = null;
 
2914
        fMinInclusive = null;
 
2915
        lengthAnnotation = null;
 
2916
        minLengthAnnotation = null;
 
2917
        maxLengthAnnotation = null;
 
2918
        whiteSpaceAnnotation = null;
 
2919
        totalDigitsAnnotation = null;
 
2920
        fractionDigitsAnnotation = null;
 
2921
        patternAnnotations = null;
 
2922
        enumerationAnnotations = null;
 
2923
        maxInclusiveAnnotation = null;
 
2924
        maxExclusiveAnnotation = null;
 
2925
        minInclusiveAnnotation = null;
 
2926
        minExclusiveAnnotation = null;
 
2927
 
 
2928
        fPatternType = SPECIAL_PATTERN_NONE;
 
2929
        fAnnotations = null;
 
2930
        fFacets = null;
 
2931
 
 
2932
        // REVISIT: reset for fundamental facets
 
2933
    }
 
2934
    /**
 
2935
     * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
 
2936
     */
 
2937
    public XSNamespaceItem getNamespaceItem() {
 
2938
        // REVISIT: implement
 
2939
        return null;
 
2940
    }
 
2941
 
 
2942
    /**
 
2943
     * @see java.lang.Object#toString()
 
2944
     */
 
2945
    public String toString() {
 
2946
        return this.fTargetNamespace+"," +this.fTypeName;
 
2947
    }
 
2948
 
 
2949
    /**
 
2950
     *  A list of constraining facets if it exists, otherwise an empty
 
2951
     * <code>XSObjectList</code>. Note: This method must not be used to
 
2952
     * retrieve values for <code>enumeration</code> and <code>pattern</code>
 
2953
     * facets.
 
2954
     */
 
2955
    public XSObjectList getFacets() {
 
2956
        if (fFacets == null &&
 
2957
                (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) {
 
2958
 
 
2959
            XSFacetImpl[] facets = new XSFacetImpl[10];
 
2960
            int count = 0;
 
2961
            if ((fFacetsDefined & FACET_WHITESPACE) != 0) {
 
2962
                facets[count] =
 
2963
                    new XSFacetImpl(
 
2964
                            FACET_WHITESPACE,
 
2965
                            WS_FACET_STRING[fWhiteSpace],
 
2966
                            (fFixedFacet & FACET_WHITESPACE) != 0,
 
2967
                            whiteSpaceAnnotation);
 
2968
                count++;
 
2969
            }
 
2970
            if (fLength != -1) {
 
2971
                facets[count] =
 
2972
                    new XSFacetImpl(
 
2973
                            FACET_LENGTH,
 
2974
                            Integer.toString(fLength),
 
2975
                            (fFixedFacet & FACET_LENGTH) != 0,
 
2976
                            lengthAnnotation);
 
2977
                count++;
 
2978
            }
 
2979
            if (fMinLength != -1) {
 
2980
                facets[count] =
 
2981
                    new XSFacetImpl(
 
2982
                            FACET_MINLENGTH,
 
2983
                            Integer.toString(fMinLength),
 
2984
                            (fFixedFacet & FACET_MINLENGTH) != 0,
 
2985
                            minLengthAnnotation);
 
2986
                count++;
 
2987
            }
 
2988
            if (fMaxLength != -1) {
 
2989
                facets[count] =
 
2990
                    new XSFacetImpl(
 
2991
                            FACET_MAXLENGTH,
 
2992
                            Integer.toString(fMaxLength),
 
2993
                            (fFixedFacet & FACET_MAXLENGTH) != 0,
 
2994
                            maxLengthAnnotation);
 
2995
                count++;
 
2996
            }
 
2997
            if (fTotalDigits != -1) {
 
2998
                facets[count] =
 
2999
                    new XSFacetImpl(
 
3000
                            FACET_TOTALDIGITS,
 
3001
                            Integer.toString(fTotalDigits),
 
3002
                            (fFixedFacet & FACET_TOTALDIGITS) != 0,
 
3003
                            totalDigitsAnnotation);
 
3004
                count++;
 
3005
            }
 
3006
            if (fValidationDV == DV_INTEGER) {
 
3007
                facets[count] =
 
3008
                    new XSFacetImpl(
 
3009
                            FACET_FRACTIONDIGITS,
 
3010
                            "0",
 
3011
                            true,
 
3012
                            fractionDigitsAnnotation);
 
3013
                count++;
 
3014
            }
 
3015
            else if (fFractionDigits != -1) {
 
3016
                facets[count] =
 
3017
                    new XSFacetImpl(
 
3018
                            FACET_FRACTIONDIGITS,
 
3019
                            Integer.toString(fFractionDigits),
 
3020
                            (fFixedFacet & FACET_FRACTIONDIGITS) != 0,
 
3021
                            fractionDigitsAnnotation);
 
3022
                count++;
 
3023
            }
 
3024
            if (fMaxInclusive != null) {
 
3025
                facets[count] =
 
3026
                    new XSFacetImpl(
 
3027
                            FACET_MAXINCLUSIVE,
 
3028
                            fMaxInclusive.toString(),
 
3029
                            (fFixedFacet & FACET_MAXINCLUSIVE) != 0,
 
3030
                            maxInclusiveAnnotation);
 
3031
                count++;
 
3032
            }
 
3033
            if (fMaxExclusive != null) {
 
3034
                facets[count] =
 
3035
                    new XSFacetImpl(
 
3036
                            FACET_MAXEXCLUSIVE,
 
3037
                            fMaxExclusive.toString(),
 
3038
                            (fFixedFacet & FACET_MAXEXCLUSIVE) != 0,
 
3039
                            maxExclusiveAnnotation);
 
3040
                count++;
 
3041
            }
 
3042
            if (fMinExclusive != null) {
 
3043
                facets[count] =
 
3044
                    new XSFacetImpl(
 
3045
                            FACET_MINEXCLUSIVE,
 
3046
                            fMinExclusive.toString(),
 
3047
                            (fFixedFacet & FACET_MINEXCLUSIVE) != 0,
 
3048
                            minExclusiveAnnotation);
 
3049
                count++;
 
3050
            }
 
3051
            if (fMinInclusive != null) {
 
3052
                facets[count] =
 
3053
                    new XSFacetImpl(
 
3054
                            FACET_MININCLUSIVE,
 
3055
                            fMinInclusive.toString(),
 
3056
                            (fFixedFacet & FACET_MININCLUSIVE) != 0,
 
3057
                            minInclusiveAnnotation);
 
3058
                count++;
 
3059
            }
 
3060
            fFacets = new XSObjectListImpl(facets, count);
 
3061
        }
 
3062
        return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST;
 
3063
    }
 
3064
 
 
3065
    /**
 
3066
     *  A list of enumeration and pattern constraining facets if it exists,
 
3067
     * otherwise an empty <code>XSObjectList</code>.
 
3068
     */
 
3069
    public XSObjectList getMultiValueFacets() {
 
3070
        if (fMultiValueFacets == null &&
 
3071
                ((fFacetsDefined & FACET_ENUMERATION) != 0 ||
 
3072
                        (fFacetsDefined & FACET_PATTERN) != 0 ||
 
3073
                        fPatternType != SPECIAL_PATTERN_NONE ||
 
3074
                        fValidationDV == DV_INTEGER)) {
 
3075
 
 
3076
            XSMVFacetImpl[] facets = new XSMVFacetImpl[2];
 
3077
            int count = 0;
 
3078
            if ((fFacetsDefined & FACET_PATTERN) != 0 ||
 
3079
                    fPatternType != SPECIAL_PATTERN_NONE ||
 
3080
                    fValidationDV == DV_INTEGER) {
 
3081
                facets[count] =
 
3082
                    new XSMVFacetImpl(
 
3083
                            FACET_PATTERN,
 
3084
                            this.getLexicalPattern(),
 
3085
                            patternAnnotations);
 
3086
                count++;
 
3087
            }
 
3088
            if (fEnumeration != null) {
 
3089
                facets[count] =
 
3090
                    new XSMVFacetImpl(
 
3091
                            FACET_ENUMERATION,
 
3092
                            this.getLexicalEnumeration(),
 
3093
                            enumerationAnnotations);
 
3094
                count++;
 
3095
            }
 
3096
            fMultiValueFacets = new XSObjectListImpl(facets, count);
 
3097
        }
 
3098
        return (fMultiValueFacets != null) ?
 
3099
                fMultiValueFacets : XSObjectListImpl.EMPTY_LIST;
 
3100
    }
 
3101
 
 
3102
    public Object getMinInclusiveValue() {
 
3103
        return fMinInclusive;
 
3104
    }
 
3105
 
 
3106
    public Object getMinExclusiveValue() {
 
3107
        return fMinExclusive;
 
3108
    }
 
3109
 
 
3110
    public Object getMaxInclusiveValue() {
 
3111
        return fMaxInclusive;
 
3112
    }
 
3113
 
 
3114
    public Object getMaxExclusiveValue() {
 
3115
        return fMaxExclusive;
 
3116
    }
 
3117
 
 
3118
    public void setAnonymous(boolean anon) {
 
3119
        fAnonymous = anon;
 
3120
    }
 
3121
 
 
3122
    private static final class XSFacetImpl implements XSFacet {
 
3123
        final short kind;
 
3124
        final String value;
 
3125
        final boolean fixed;
 
3126
        final XSObjectList annotations;  
 
3127
 
 
3128
        public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) {
 
3129
            this.kind = kind;
 
3130
            this.value = value;
 
3131
            this.fixed = fixed;
 
3132
 
 
3133
            if (annotation != null) {
 
3134
                this.annotations = new XSObjectListImpl();
 
3135
                ((XSObjectListImpl)this.annotations).add(annotation);
 
3136
            } 
 
3137
            else {
 
3138
                this.annotations =  XSObjectListImpl.EMPTY_LIST;
 
3139
            }
 
3140
        }
 
3141
 
 
3142
        /*
 
3143
         * (non-Javadoc)
 
3144
         * 
 
3145
         * @see org.apache.xerces.xs.XSFacet#getAnnotation()
 
3146
         */
 
3147
        /**
 
3148
         * Optional. Annotation.
 
3149
         */
 
3150
        public XSAnnotation getAnnotation() {
 
3151
            return (XSAnnotation) annotations.item(0);
 
3152
        }
 
3153
 
 
3154
        /*
 
3155
         * (non-Javadoc)
 
3156
         * 
 
3157
         * @see org.apache.xerces.xs.XSFacet#getAnnotations()
 
3158
         */
 
3159
        /**
 
3160
         * Optional. Annotations.
 
3161
         */
 
3162
        public XSObjectList getAnnotations() {
 
3163
            return annotations;
 
3164
        }
 
3165
 
 
3166
        /* (non-Javadoc)
 
3167
         * @see org.apache.xerces.xs.XSFacet#getFacetKind()
 
3168
         */
 
3169
        public short getFacetKind() {
 
3170
            return kind;
 
3171
        }
 
3172
 
 
3173
        /* (non-Javadoc)
 
3174
         * @see org.apache.xerces.xs.XSFacet#getLexicalFacetValue()
 
3175
         */
 
3176
        public String getLexicalFacetValue() {
 
3177
            return value;
 
3178
        }
 
3179
 
 
3180
        /* (non-Javadoc)
 
3181
         * @see org.apache.xerces.xs.XSFacet#isFixed()
 
3182
         */
 
3183
        public boolean getFixed() {
 
3184
            return fixed;
 
3185
        }
 
3186
 
 
3187
        /* (non-Javadoc)
 
3188
         * @see org.apache.xerces.xs.XSObject#getName()
 
3189
         */
 
3190
        public String getName() {
 
3191
            return null;
 
3192
        }
 
3193
 
 
3194
        /* (non-Javadoc)
 
3195
         * @see org.apache.xerces.xs.XSObject#getNamespace()
 
3196
         */
 
3197
        public String getNamespace() {
 
3198
            return null;
 
3199
        }
 
3200
 
 
3201
        /* (non-Javadoc)
 
3202
         * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
 
3203
         */
 
3204
        public XSNamespaceItem getNamespaceItem() {
 
3205
            // REVISIT: implement
 
3206
            return null;
 
3207
        }
 
3208
 
 
3209
        /* (non-Javadoc)
 
3210
         * @see org.apache.xerces.xs.XSObject#getType()
 
3211
         */
 
3212
        public short getType() {
 
3213
            return XSConstants.FACET;
 
3214
        }
 
3215
 
 
3216
    }
 
3217
 
 
3218
    private static final class XSMVFacetImpl implements XSMultiValueFacet {
 
3219
        final short kind;
 
3220
        final XSObjectList annotations;
 
3221
        final StringList values;
 
3222
 
 
3223
        public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) {
 
3224
            this.kind = kind;
 
3225
            this.values = values;
 
3226
            this.annotations = (annotations != null) ? annotations : XSObjectListImpl.EMPTY_LIST;
 
3227
        }               
 
3228
 
 
3229
        /* (non-Javadoc)
 
3230
         * @see org.apache.xerces.xs.XSFacet#getFacetKind()
 
3231
         */
 
3232
        public short getFacetKind() {
 
3233
            return kind;
 
3234
        }       
 
3235
 
 
3236
        /* (non-Javadoc)
 
3237
         * @see org.apache.xerces.xs.XSMultiValueFacet#getAnnotations()
 
3238
         */
 
3239
        public XSObjectList getAnnotations() {
 
3240
            return annotations;
 
3241
        }
 
3242
 
 
3243
        /* (non-Javadoc)
 
3244
         * @see org.apache.xerces.xs.XSMultiValueFacet#getLexicalFacetValues()
 
3245
         */
 
3246
        public StringList getLexicalFacetValues() {
 
3247
            return values;
 
3248
        }
 
3249
 
 
3250
        /* (non-Javadoc)
 
3251
         * @see org.apache.xerces.xs.XSObject#getName()
 
3252
         */
 
3253
        public String getName() {
 
3254
            return null;
 
3255
        }
 
3256
 
 
3257
        /* (non-Javadoc)
 
3258
         * @see org.apache.xerces.xs.XSObject#getNamespace()
 
3259
         */
 
3260
        public String getNamespace() {
 
3261
            return null;
 
3262
        }
 
3263
 
 
3264
        /* (non-Javadoc)
 
3265
         * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
 
3266
         */
 
3267
        public XSNamespaceItem getNamespaceItem() {
 
3268
            // REVISIT: implement
 
3269
            return null;
 
3270
        }
 
3271
 
 
3272
        /* (non-Javadoc)
 
3273
         * @see org.apache.xerces.xs.XSObject#getType()
 
3274
         */
 
3275
        public short getType() {
 
3276
            return XSConstants.MULTIVALUE_FACET;
 
3277
        }
 
3278
    }
 
3279
 
 
3280
    public String getTypeNamespace() {
 
3281
        return getNamespace();
 
3282
    }
 
3283
 
 
3284
    public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) {
 
3285
        return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
 
3286
    }
 
3287
 
 
3288
    private short convertToPrimitiveKind(short valueType) {
 
3289
        /** Primitive datatypes. */
 
3290
        if (valueType <= XSConstants.NOTATION_DT) {
 
3291
            return valueType;
 
3292
        }
 
3293
        /** Types derived from string. */
 
3294
        if (valueType <= XSConstants.ENTITY_DT) {
 
3295
            return XSConstants.STRING_DT;
 
3296
        }
 
3297
        /** Types derived from decimal. */
 
3298
        if (valueType <= XSConstants.POSITIVEINTEGER_DT) {
 
3299
            return XSConstants.DECIMAL_DT;
 
3300
        }
 
3301
        /** Other types. */
 
3302
        return valueType;
 
3303
    }
 
3304
 
 
3305
} // class XSSimpleTypeDecl
 
3306