KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > validators > common > XMLValidator


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000,2001 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.validators.common;
59
60 import java.io.IOException JavaDoc;
61 import java.util.Enumeration JavaDoc;
62 import java.util.Hashtable JavaDoc;
63 import java.util.Stack JavaDoc;
64 import java.util.StringTokenizer JavaDoc;
65 import java.util.Vector JavaDoc;
66
67 import org.enhydra.apache.xerces.framework.XMLAttrList;
68 import org.enhydra.apache.xerces.framework.XMLContentSpec;
69 import org.enhydra.apache.xerces.framework.XMLDocumentHandler;
70 import org.enhydra.apache.xerces.framework.XMLDocumentScanner;
71 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
72 import org.enhydra.apache.xerces.parsers.DOMParser;
73 import org.enhydra.apache.xerces.readers.DefaultEntityHandler;
74 import org.enhydra.apache.xerces.readers.XMLEntityHandler;
75 import org.enhydra.apache.xerces.utils.ImplementationMessages;
76 import org.enhydra.apache.xerces.utils.IntStack;
77 import org.enhydra.apache.xerces.utils.NamespacesScope;
78 import org.enhydra.apache.xerces.utils.QName;
79 import org.enhydra.apache.xerces.utils.StringPool;
80 import org.enhydra.apache.xerces.utils.XMLMessages;
81 import org.enhydra.apache.xerces.validators.datatype.AnySimpleType;
82 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidator;
83 import org.enhydra.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
84 import org.enhydra.apache.xerces.validators.datatype.ENTITYDatatypeValidator;
85 import org.enhydra.apache.xerces.validators.datatype.IDDatatypeValidator;
86 import org.enhydra.apache.xerces.validators.datatype.IDREFDatatypeValidator;
87 import org.enhydra.apache.xerces.validators.datatype.InvalidDatatypeValueException;
88 import org.enhydra.apache.xerces.validators.datatype.NOTATIONDatatypeValidator;
89 import org.enhydra.apache.xerces.validators.datatype.StateMessageDatatype;
90 import org.enhydra.apache.xerces.validators.datatype.UnionDatatypeValidator;
91 import org.enhydra.apache.xerces.validators.dtd.DTDGrammar;
92 import org.enhydra.apache.xerces.validators.schema.GeneralAttrCheck;
93 import org.enhydra.apache.xerces.validators.schema.SchemaGrammar;
94 import org.enhydra.apache.xerces.validators.schema.SchemaMessageProvider;
95 import org.enhydra.apache.xerces.validators.schema.SchemaSymbols;
96 import org.enhydra.apache.xerces.validators.schema.SubstitutionGroupComparator;
97 import org.enhydra.apache.xerces.validators.schema.TraverseSchema;
98 import org.enhydra.apache.xerces.validators.schema.identity.Field;
99 import org.enhydra.apache.xerces.validators.schema.identity.FieldActivator;
100 import org.enhydra.apache.xerces.validators.schema.identity.IDValue;
101 import org.enhydra.apache.xerces.validators.schema.identity.IdentityConstraint;
102 import org.enhydra.apache.xerces.validators.schema.identity.Key;
103 import org.enhydra.apache.xerces.validators.schema.identity.KeyRef;
104 import org.enhydra.apache.xerces.validators.schema.identity.Selector;
105 import org.enhydra.apache.xerces.validators.schema.identity.Unique;
106 import org.enhydra.apache.xerces.validators.schema.identity.ValueStore;
107 import org.enhydra.apache.xerces.validators.schema.identity.XPathMatcher;
108 import org.w3c.dom.Document JavaDoc;
109 import org.w3c.dom.Element JavaDoc;
110 import org.xml.sax.EntityResolver JavaDoc;
111 import org.xml.sax.InputSource JavaDoc;
112 import org.xml.sax.Locator JavaDoc;
113 import org.xml.sax.SAXException JavaDoc;
114 import org.xml.sax.SAXParseException JavaDoc;
115 import org.xml.sax.helpers.LocatorImpl JavaDoc;
116
117 /**
118  * This class is the super all-in-one validator used by the parser.
119  *
120  * @version $Id: XMLValidator.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
121  */

122 public final class XMLValidator
123     implements DefaultEntityHandler.EventHandler,
124                XMLEntityHandler.CharDataHandler,
125                XMLDocumentScanner.EventHandler,
126                NamespacesScope.NamespacesHandler,
127                FieldActivator // for identity constraints
128
{
129
130    //
131
// Constants
132
//
133

134    // debugging
135

136    private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
137    private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
138    private static final boolean DEBUG_PRINT_CONTENT = false;
139    private static final boolean DEBUG_SCHEMA_VALIDATION = false;
140    private static final boolean DEBUG_ELEMENT_CHILDREN = false;
141
142    /** Compile to true to debug identity constraints. */
143    protected static final boolean DEBUG_IDENTITY_CONSTRAINTS = false;
144
145    /** Compile to true to debug value stores. */
146    protected static final boolean DEBUG_VALUE_STORES = false;
147
148    // Chunk size constants
149

150    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
151
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
152    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
153    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
154

155    private Hashtable JavaDoc fIdDefs = new Hashtable JavaDoc();
156    private Hashtable JavaDoc fIdREFDefs = new Hashtable JavaDoc();
157
158    private StateMessageDatatype fValidateIDRef = new StateMessageDatatype() {
159       private Hashtable JavaDoc fIdDefs;
160       public Object JavaDoc getDatatypeObject(){
161          return(Object JavaDoc) fIdDefs;
162       }
163       public int getDatatypeState(){
164          return IDREFDatatypeValidator.IDREF_VALIDATE;
165       }
166       public void setDatatypeObject( Object JavaDoc data ){
167          fIdDefs = (Hashtable JavaDoc) data;
168       }
169    };
170
171    private StateMessageDatatype fCheckIDRef = new StateMessageDatatype() {
172       private Object JavaDoc[] fLists;
173       public Object JavaDoc getDatatypeObject(){
174          return(Object JavaDoc) fLists;
175       }
176       public int getDatatypeState(){
177          return IDREFDatatypeValidator.IDREF_CHECKID;
178       }
179       public void setDatatypeObject( Object JavaDoc data ){
180         fLists = (Object JavaDoc[]) data;
181       }
182    };
183
184    private StateMessageDatatype fValidateEntity = new StateMessageDatatype() {
185       private Object JavaDoc fData;
186       public Object JavaDoc getDatatypeObject(){
187          return fData;
188       }
189       public int getDatatypeState(){
190          return ENTITYDatatypeValidator.ENTITY_VALIDATE;
191       }
192       public void setDatatypeObject( Object JavaDoc data ){
193          fData = data;
194       }
195    };
196
197    //
198
// Data
199
//
200

201    // REVISIT: The data should be regrouped and re-organized so that
202
// it's easier to find a meaningful field.
203

204    // attribute validators
205

206    private AttributeValidator fAttValidatorNOTATION = new AttValidatorNOTATION();
207    private AttributeValidator fAttValidatorENUMERATION = new AttValidatorENUMERATION();
208    private AttributeValidator fAttValidatorDATATYPE = null;
209
210    // Package access for use by AttributeValidator classes.
211

212    StringPool fStringPool = null;
213    boolean fValidating = false;
214    boolean fInElementContent = false;
215    int fStandaloneReader = -1;
216
217
218    // settings
219

220    private boolean fValidationEnabled = false;
221    private boolean fDynamicValidation = false;
222    private boolean fSchemaValidation = true;
223    private boolean fSchemaValidationFullChecking = false;
224    private boolean fValidationEnabledByDynamic = false;
225    private boolean fDynamicDisabledByValidation = false;
226    private boolean fWarningOnDuplicateAttDef = false;
227    private boolean fWarningOnUndeclaredElements = false;
228    private boolean fNormalizeAttributeValues = true;
229    private boolean fLoadDTDGrammar = true;
230    // expose normalized values for element/attribute content
231
// default: expose Infoset
232
private boolean fNormalizeContents = false;
233
234    // REVISIT: normalization
235
// would not work properly for UNION types since we don't have
236
// correct whiteSpace facet to normalize values.
237
//
238

239    // Private temporary variables
240

241   private Hashtable JavaDoc fLocationUriPairs = new Hashtable JavaDoc(10);
242
243
244    // declarations
245

246    private String JavaDoc fExternalSchemas = null;
247    private String JavaDoc fExternalNoNamespaceSchema = null;
248    private DOMParser fSchemaGrammarParser = null;
249    private int fDeclaration[];
250    private XMLErrorReporter fErrorReporter = null;
251    private DefaultEntityHandler fEntityHandler = null;
252    private QName fCurrentElement = new QName();
253
254    private ContentLeafNameTypeVector[] fContentLeafStack = new ContentLeafNameTypeVector[8];
255
256    //OTWI: on-the-way-in
257
// store the content model
258
private XMLContentModel[] fContentModelStack = new XMLContentModel[8];
259    // >= 0 normal state; -1: error; -2: on-the-way-out
260
private int[] fContentModelStateStack = new int[8];
261    // how many child elements have succefully validated
262
private int[] fContentModelEleCount = new int[8];
263
264    private int[] fValidationFlagStack = new int[8];
265
266    private int[] fScopeStack = new int[8];
267    private int[] fGrammarNameSpaceIndexStack = new int[8];
268
269    private int[] fElementEntityStack = new int[8];
270    private int[] fElementIndexStack = new int[8];
271    private int[] fContentSpecTypeStack = new int[8];
272
273    private static final int sizeQNameParts = 8;
274    private QName[] fElementQNamePartsStack = new QName[sizeQNameParts];
275
276    private QName[] fElementChildren = new QName[32];
277    private int fElementChildrenLength = 0;
278    private int[] fElementChildrenOffsetStack = new int[32];
279    private int fElementDepth = -1;
280
281    private boolean fNamespacesEnabled = false;
282    private NamespacesScope fNamespacesScope = null;
283    private int fNamespacesPrefix = -1;
284    private QName fRootElement = new QName();
285    private int fAttrListHandle = -1;
286    private int fCurrentElementEntity = -1;
287    private int fCurrentElementIndex = -1;
288    private int fCurrentContentSpecType = -1;
289    private boolean fSeenDoctypeDecl = false;
290
291    private final int TOP_LEVEL_SCOPE = -1;
292    private int fCurrentScope = TOP_LEVEL_SCOPE;
293    private int fCurrentSchemaURI = StringPool.EMPTY_STRING;
294    private int fEmptyURI = StringPool.EMPTY_STRING;
295    private int fXsiPrefix = - 1;
296    private int fXsiURI = -2;
297    private int fXsiTypeAttValue = -1;
298    private DatatypeValidator fXsiTypeValidator = null;
299
300    private boolean fNil = false;
301
302    private Grammar fGrammar = null;
303    private int fGrammarNameSpaceIndex = StringPool.EMPTY_STRING;
304    private GrammarResolver fGrammarResolver = null;
305
306
307    // state and stuff
308

309    private boolean fScanningDTD = false;
310    private XMLDocumentScanner fDocumentScanner = null;
311    private boolean fCalledStartDocument = false;
312    private XMLDocumentHandler fDocumentHandler = null;
313    private XMLDocumentHandler.DTDHandler fDTDHandler = null;
314    private boolean fSeenRootElement = false;
315    private XMLAttrList fAttrList = null;
316    private int fXMLLang = -1;
317    private LocatorImpl JavaDoc fAttrNameLocator = null;
318    private boolean fCheckedForSchema = false;
319    private boolean fDeclsAreExternal = false;
320    private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
321    private char[] fCharRefData = null;
322    private boolean fSendCharDataAsCharArray = false;
323    private boolean fBufferDatatype = false;
324    // holds normalized or unnormalized string element value,
325
private StringBuffer JavaDoc fDatatypeBuffer = new StringBuffer JavaDoc();
326
327    private QName fTempQName = new QName();
328    private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
329    private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
330    private XMLElementDecl fTempElementDecl = new XMLElementDecl();
331
332    private boolean fGrammarIsDTDGrammar = false;
333    private boolean fGrammarIsSchemaGrammar = false;
334
335    private boolean fNeedValidationOff = false;
336
337    //Schema Normalization
338
private static final boolean DEBUG_NORMALIZATION = false;
339     private DatatypeValidator fCurrentDV = null; //current datatype validator
340
private boolean fFirstChunk = true; // got first chunk in characters() (SAX)
341
private boolean fTrailing = false; // Previous chunk had a trailing space
342
private short fWhiteSpace = DatatypeValidator.COLLAPSE; //whiteSpace: preserve/replace/collapse
343
private StringBuffer JavaDoc fNormalizedStr = new StringBuffer JavaDoc(CHUNK_SIZE); //holds normalized str value
344
private StringBuffer JavaDoc fUnnormalizedStr = new StringBuffer JavaDoc(CHUNK_SIZE); //holds unnormalized str value
345

346
347
348    // symbols
349

350    private int fEMPTYSymbol = -1;
351    private int fANYSymbol = -1;
352    private int fMIXEDSymbol = -1;
353    private int fCHILDRENSymbol = -1;
354    private int fCDATASymbol = -1;
355    private int fIDSymbol = -1;
356    private int fIDREFSymbol = -1;
357    private int fIDREFSSymbol = -1;
358    private int fENTITYSymbol = -1;
359    private int fENTITIESSymbol = -1;
360    private int fNMTOKENSymbol = -1;
361    private int fNMTOKENSSymbol = -1;
362    private int fNOTATIONSymbol = -1;
363    private int fENUMERATIONSymbol = -1;
364    private int fREQUIREDSymbol = -1;
365    private int fFIXEDSymbol = -1;
366    private int fDATATYPESymbol = -1;
367    private int fEpsilonIndex = -1;
368
369
370    //Datatype Registry
371

372    private DatatypeValidatorFactoryImpl fDataTypeReg = null;
373    private DatatypeValidator fValID = null;
374    private DatatypeValidator fValIDRef = null;
375    private DatatypeValidator fValIDRefs = null;
376    private DatatypeValidator fValENTITY = null;
377    private DatatypeValidator fValENTITIES = null;
378    private DatatypeValidator fValNMTOKEN = null;
379    private DatatypeValidator fValNMTOKENS = null;
380    private DatatypeValidator fValNOTATION = null;
381
382     // identity constraint information
383

384     /**
385      * Stack of active XPath matchers for identity constraints. All
386      * active XPath matchers are notified of startElement, characters
387      * and endElement callbacks in order to perform their matches.
388      * <p>
389      * For each element with identity constraints, the selector of
390      * each identity constraint is activated. When the selector matches
391      * its XPath, then all the fields of the identity constraint are
392      * activated.
393      * <p>
394      * <strong>Note:</strong> Once the activation scope is left, the
395      * XPath matchers are automatically removed from the stack of
396      * active matchers and no longer receive callbacks.
397      */

398     protected XPathMatcherStack fMatcherStack = new XPathMatcherStack();
399
400     /** Cache of value stores for identity constraint fields. */
401     protected ValueStoreCache fValueStoreCache = new ValueStoreCache();
402
403     // store the substitution group comparator
404
protected SubstitutionGroupComparator fSGComparator = null;
405
406     // on which grammars we have checked UPA
407
protected Hashtable JavaDoc UPACheckedGrammarURIs = new Hashtable JavaDoc();
408     protected static Object JavaDoc fgNullObject = new Object JavaDoc();
409
410    //
411
// Constructors
412
//
413

414    /** Constructs an XML validator. */
415    public XMLValidator(StringPool stringPool,
416                        XMLErrorReporter errorReporter,
417                        DefaultEntityHandler entityHandler,
418                        XMLDocumentScanner documentScanner) {
419
420       // keep references
421
fStringPool = stringPool;
422       fErrorReporter = errorReporter;
423       fEntityHandler = entityHandler;
424       fDocumentScanner = documentScanner;
425
426       fValidateEntity.setDatatypeObject(new Object JavaDoc[]{entityHandler, stringPool});
427       fValidateIDRef.setDatatypeObject(fIdREFDefs);
428       fCheckIDRef.setDatatypeObject(new Object JavaDoc[]{fIdDefs, fIdREFDefs});
429
430       fEmptyURI = fStringPool.addSymbol("");
431       fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
432       // initialize
433
fAttrList = new XMLAttrList(fStringPool);
434       entityHandler.setEventHandler(this);
435       entityHandler.setCharDataHandler(this);
436       fDocumentScanner.setEventHandler(this);
437
438       for (int i = 0; i < sizeQNameParts; i++) {
439          fElementQNamePartsStack[i] = new QName();
440       }
441       init();
442
443    } // <init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)
444

445    public void setGrammarResolver(GrammarResolver grammarResolver){
446       fGrammarResolver = grammarResolver;
447     }
448
449    //
450
// Public methods
451
//
452

453    // initialization
454

455    /** Set char data processing preference and handlers. */
456    public void initHandlers(boolean sendCharDataAsCharArray,
457                             XMLDocumentHandler docHandler,
458                             XMLDocumentHandler.DTDHandler dtdHandler) {
459
460       fSendCharDataAsCharArray = sendCharDataAsCharArray;
461       fEntityHandler.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
462       fDocumentHandler = docHandler;
463       fDTDHandler = dtdHandler;
464
465    } // initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)
466

467    /** Reset or copy. */
468    public void resetOrCopy(StringPool stringPool) throws Exception JavaDoc {
469       fAttrList = new XMLAttrList(stringPool);
470       resetCommon(stringPool);
471    }
472
473    /** Reset. */
474    public void reset(StringPool stringPool) throws Exception JavaDoc {
475       fAttrList.reset(stringPool);
476       resetCommon(stringPool);
477    }
478
479
480    // settings
481

482    /**
483     * Turning on validation/dynamic turns on validation if it is off, and
484     * this is remembered. Turning off validation DISABLES validation/dynamic
485     * if it is on. Turning off validation/dynamic DOES NOT turn off
486     * validation if it was explicitly turned on, only if it was turned on
487     * BECAUSE OF the call to turn validation/dynamic on. Turning on
488     * validation will REENABLE and turn validation/dynamic back on if it
489     * was disabled by a call that turned off validation while
490     * validation/dynamic was enabled.
491     */

492    public void setValidationEnabled(boolean flag) throws Exception JavaDoc {
493       fValidationEnabled = flag;
494       fValidationEnabledByDynamic = false;
495       if (fValidationEnabled) {
496          if (fDynamicDisabledByValidation) {
497             fDynamicValidation = true;
498             fDynamicDisabledByValidation = false;
499          }
500       } else if (fDynamicValidation) {
501          fDynamicValidation = false;
502          fDynamicDisabledByValidation = true;
503       }
504       fValidating = fValidationEnabled;
505       if (fValidating) {
506         initDataTypeValidators();
507       }
508     }
509
510    /** Returns true if validation is enabled. */
511    public boolean getValidationEnabled() {
512       return fValidationEnabled;
513    }
514
515    /** Sets whether Schema support is on/off. */
516    public void setSchemaValidationEnabled(boolean flag) {
517       fSchemaValidation = flag;
518    }
519
520    /** Returns true if Schema support is on. */
521    public boolean getSchemaValidationEnabled() {
522       return fSchemaValidation;
523    }
524
525    /** Sets whether full Schema error checking is on/off */
526    public void setSchemaFullCheckingEnabled(boolean flag) {
527       fSchemaValidationFullChecking = flag;
528    }
529
530    //Properties on the parser to allow the user to specify
531
//XML schemas externaly
532
//
533
public void setExternalSchemas(Object JavaDoc value){
534        fExternalSchemas = (String JavaDoc)value;
535    }
536    public void setExternalNoNamespaceSchema(Object JavaDoc value){
537        fExternalNoNamespaceSchema = (String JavaDoc)value;
538    }
539
540    public String JavaDoc getExternalSchemas(){
541        return fExternalSchemas;
542    }
543    public String JavaDoc getExternalNoNamespaceSchema(){
544        return fExternalNoNamespaceSchema;
545    }
546
547    /** Returns true if full Schema checking is on. */
548    public boolean getSchemaFullCheckingEnabled() {
549       return fSchemaValidationFullChecking;
550    }
551
552    /** Sets whether validation is dynamic. */
553    public void setDynamicValidationEnabled(boolean flag) throws Exception JavaDoc {
554       fDynamicValidation = flag;
555       fDynamicDisabledByValidation = false;
556       if (!fDynamicValidation) {
557          if (fValidationEnabledByDynamic) {
558             fValidationEnabled = false;
559             fValidationEnabledByDynamic = false;
560          }
561       } else if (!fValidationEnabled) {
562          fValidationEnabled = true;
563          fValidationEnabledByDynamic = true;
564       }
565       fValidating = fValidationEnabled;
566       if (fValidating) {
567         initDataTypeValidators();
568       }
569     }
570
571    /** Returns true if validation is dynamic. */
572    public boolean getDynamicValidationEnabled() {
573       return fDynamicValidation;
574    }
575
576    /** Sets fNormalizeAttributeValues **/
577    public void setNormalizeAttributeValues(boolean normalize){
578       fNormalizeAttributeValues = normalize;
579    }
580
581    /** Sets fLoadDTDGrammar when validation is off **/
582    public void setLoadDTDGrammar(boolean loadDG){
583       if (fValidating) {
584          fLoadDTDGrammar = true;
585       } else {
586          fLoadDTDGrammar = loadDG;
587       }
588    }
589
590    /** Returns fLoadDTDGrammar **/
591    public boolean getLoadDTDGrammar() {
592       return fLoadDTDGrammar;
593    }
594
595    /** Sets whether namespaces are enabled. */
596    public void setNamespacesEnabled(boolean flag) {
597       fNamespacesEnabled = flag;
598    }
599
600    /** Returns true if namespaces are enabled. */
601    public boolean getNamespacesEnabled() {
602       return fNamespacesEnabled;
603    }
604
605    /** Sets whether duplicate attribute definitions signal a warning. */
606    public void setWarningOnDuplicateAttDef(boolean flag) {
607       fWarningOnDuplicateAttDef = flag;
608    }
609
610    /** Returns true if duplicate attribute definitions signal a warning. */
611    public boolean getWarningOnDuplicateAttDef() {
612       return fWarningOnDuplicateAttDef;
613    }
614
615    /** Sets whether undeclared elements signal a warning. */
616    public void setWarningOnUndeclaredElements(boolean flag) {
617       fWarningOnUndeclaredElements = flag;
618    }
619
620    /** Returns true if undeclared elements signal a warning. */
621    public boolean getWarningOnUndeclaredElements() {
622       return fWarningOnUndeclaredElements;
623    }
624
625    /** Sets fNormalizeContents **/
626    public void setNormalizeContents(boolean normalize){
627       fNormalizeContents = normalize;
628    }
629    public boolean getNormalizeConents() {
630       return fNormalizeContents;
631    }
632
633     //
634
// FieldActivator methods
635
//
636

637    /**
638     * Start the value scope for the specified identity constraint. This
639     * method is called when the selector matches in order to initialize
640     * the value store.
641     *
642     * @param identityConstraint The identity constraint.
643     */

644    public void startValueScopeFor(IdentityConstraint identityConstraint)
645         throws Exception JavaDoc {
646
647         for(int i=0; i<identityConstraint.getFieldCount(); i++) {
648             Field field = identityConstraint.getFieldAt(i);
649             ValueStoreBase valueStore = fValueStoreCache.getValueStoreFor(field);
650             valueStore.startValueScope();
651         }
652
653     } // startValueScopeFor(IdentityConstraint identityConstraint)
654

655     /**
656      * Request to activate the specified field. This method returns the
657      * matcher for the field.
658      *
659      * @param field The field to activate.
660      */

661     public XPathMatcher activateField(Field field) throws Exception JavaDoc {
662         if (DEBUG_IDENTITY_CONSTRAINTS) {
663             System.out.println("<IC>: activateField(\""+field+"\")");
664         }
665         ValueStore valueStore = fValueStoreCache.getValueStoreFor(field);
666         field.setMayMatch(true);
667         XPathMatcher matcher = field.createMatcher(valueStore);
668         fMatcherStack.addMatcher(matcher);
669         matcher.startDocumentFragment(fStringPool);
670         return matcher;
671     } // activateField(Field):XPathMatcher
672

673     /**
674      * Ends the value scope for the specified identity constraint.
675      *
676      * @param identityConstraint The identity constraint.
677      */

678     public void endValueScopeFor(IdentityConstraint identityConstraint)
679         throws Exception JavaDoc {
680
681         ValueStoreBase valueStore = fValueStoreCache.getValueStoreFor(identityConstraint);
682         valueStore.endValueScope();
683
684     } // endValueScopeFor(IdentityConstraint)
685

686    //
687
// DefaultEntityHandler.EventHandler methods
688
//
689

690    /** Start entity reference. */
691    public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception JavaDoc {
692       fDocumentHandler.startEntityReference(entityName, entityType, entityContext);
693    }
694
695    /** End entity reference. */
696    public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception JavaDoc {
697       fDocumentHandler.endEntityReference(entityName, entityType, entityContext);
698    }
699
700    /** Send end of input notification. */
701    public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception JavaDoc {
702       fDocumentScanner.endOfInput(entityName, moreToFollow);
703       /***
704       if (fScanningDTD) {
705           fDTDImporter.sendEndOfInputNotifications(entityName, moreToFollow);
706       }
707       /***/

708    }
709
710    /** Send reader change notifications. */
711    public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception JavaDoc {
712       fDocumentScanner.readerChange(reader, readerId);
713       /***
714       if (fScanningDTD) {
715           fDTDImporter.sendReaderChangeNotifications(reader, readerId);
716       }
717       /***/

718    }
719
720    /** External entity standalone check. */
721    public boolean externalEntityStandaloneCheck() {
722       return(fStandaloneReader != -1 && fValidating);
723    }
724
725    /** Return true if validating. */
726    public boolean getValidating() {
727       return fValidating;
728    }
729
730    //
731
// XMLEntityHandler.CharDataHandler methods
732
//
733

734    private String JavaDoc normalizeValue (String JavaDoc unNormalizedValue){
735        fUnnormalizedStr.setLength(0);
736        fUnnormalizedStr.append(unNormalizedValue);
737        normalizeWhitespace(fUnnormalizedStr, (fWhiteSpace == DatatypeValidator.COLLAPSE));
738        return fNormalizedStr.toString();
739    }
740
741     /**
742      * Normalize whitespace in an XMLString according to the rules of attribute
743      * value normalization - converting all whitespace characters to space
744      * characters.
745      * In addition for attributes of type other than CDATA: trim leading and
746      * trailing spaces and collapse spaces (0x20 only).
747      *
748      * @param value The string to normalize.
749      * @returns 0 if no triming is done or if there is neither leading nor
750      * trailing whitespace,
751      * 1 if there is only leading whitespace,
752      * 2 if there is only trailing whitespace,
753      * 3 if there is both leading and trailing whitespace.
754      */

755
756     private int normalizeWhitespace( StringBuffer JavaDoc chars, boolean collapse) {
757         int length = fUnnormalizedStr.length();
758         fNormalizedStr.setLength(0);
759         boolean skipSpace = collapse;
760         boolean sawNonWS = false;
761         int leading = 0;
762         int trailing = 0;
763         int c;
764         for (int i = 0; i < length; i++) {
765             c = chars.charAt(i);
766             if (c == 0x20 || c == 0x0D || c == 0x0A || c == 0x09) {
767                 if (!skipSpace) {
768                     // take the first whitespace as a space and skip the others
769
fNormalizedStr.append(' ');
770                     skipSpace = collapse;
771                 }
772                 if (!sawNonWS) {
773                     // this is a leading whitespace, record it
774
leading = 1;
775                 }
776             }
777             else {
778                 fNormalizedStr.append((char)c);
779                 skipSpace = false;
780                 sawNonWS = true;
781             }
782         }
783         if (skipSpace) {
784             c = fNormalizedStr.length();
785             if ( c != 0) {
786                 // if we finished on a space trim it but also record it
787
fNormalizedStr.setLength (--c);
788                 trailing = 2;
789             }
790             else if (leading != 0 && !sawNonWS) {
791                 // if all we had was whitespace we skipped record it as
792
// trailing whitespace as well
793
trailing = 2;
794             }
795         }
796         //value.setValues(fNormalizedStr);
797
return collapse ? leading + trailing : 0;
798     }
799
800    /** Process characters. Schema Normalization*/
801    public void processCharacters(char[] chars, int offset, int length) throws Exception JavaDoc {
802        if (DEBUG_NORMALIZATION) {
803            System.out.println("==>processCharacters(char[] chars, int offset, int length");
804        }
805        if (fValidating) {
806            if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
807                if (DEBUG_NORMALIZATION) {
808                    System.out.println("==>char