Source code: org/apache/xerces/validators/common/XMLValidator.java
1 /*
2 * The Apache Software License, Version 1.1
3 *
4 *
5 * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6 * 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.apache.xerces.validators.common;
59
60 import org.apache.xerces.framework.XMLAttrList;
61 import org.apache.xerces.framework.XMLContentSpec;
62 import org.apache.xerces.framework.XMLDocumentHandler;
63 import org.apache.xerces.framework.XMLDocumentScanner;
64 import org.apache.xerces.framework.XMLErrorReporter;
65 import org.apache.xerces.readers.DefaultEntityHandler;
66 import org.apache.xerces.readers.XMLEntityHandler;
67 import org.apache.xerces.utils.ChunkyCharArray;
68 import org.apache.xerces.utils.Hash2intTable;
69 import org.apache.xerces.utils.NamespacesScope;
70 import org.apache.xerces.utils.QName;
71 import org.apache.xerces.utils.StringPool;
72 import org.apache.xerces.utils.XMLCharacterProperties;
73 import org.apache.xerces.utils.XMLMessages;
74 import org.apache.xerces.utils.ImplementationMessages;
75
76 import org.apache.xerces.parsers.DOMParser;
77
78 import org.w3c.dom.Document;
79 import org.w3c.dom.Element;
80
81 import org.xml.sax.InputSource;
82 import org.xml.sax.EntityResolver;
83 import org.xml.sax.Locator;
84 import org.xml.sax.helpers.LocatorImpl;
85 import org.xml.sax.SAXException;
86 import org.xml.sax.SAXParseException;
87
88 import java.io.IOException;
89 import java.io.InputStream;
90
91 import java.util.Enumeration;
92 import java.util.Hashtable;
93 import java.util.StringTokenizer;
94 import java.util.Vector;
95
96 import org.apache.xerces.validators.dtd.DTDGrammar;
97
98 import org.apache.xerces.validators.schema.EquivClassComparator;
99 import org.apache.xerces.validators.schema.SchemaGrammar;
100 import org.apache.xerces.validators.schema.SchemaMessageProvider;
101 import org.apache.xerces.validators.schema.SchemaSymbols;
102 import org.apache.xerces.validators.schema.TraverseSchema;
103
104 import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
105 import org.apache.xerces.validators.datatype.DatatypeValidator;
106 import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
107 import org.apache.xerces.validators.datatype.StateMessageDatatype;
108 import org.apache.xerces.validators.datatype.IDREFDatatypeValidator;
109 import org.apache.xerces.validators.datatype.IDDatatypeValidator;
110 import org.apache.xerces.validators.datatype.ENTITYDatatypeValidator;
111
112 /**
113 * This class is the super all-in-one validator used by the parser.
114 *
115 * @version $Id: XMLValidator.java,v 1.2 2000/10/07 18:06:55 markd Exp $
116 */
117 public final class XMLValidator
118 implements DefaultEntityHandler.EventHandler,
119 XMLEntityHandler.CharDataHandler,
120 XMLDocumentScanner.EventHandler,
121 NamespacesScope.NamespacesHandler {
122
123 //
124 // Constants
125 //
126
127 // debugging
128
129 private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
130 private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
131 private static final boolean DEBUG_PRINT_CONTENT = false;
132 private static final boolean DEBUG_SCHEMA_VALIDATION = false;
133 private static final boolean DEBUG_ELEMENT_CHILDREN = false;
134
135 // Chunk size constants
136
137 private static final int CHUNK_SHIFT = 8; // 2^8 = 256
138 private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
139 private static final int CHUNK_MASK = CHUNK_SIZE - 1;
140 private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
141
142 private Hashtable fIdDefs = null;
143
144
145 private StateMessageDatatype fStoreIDRef = new StateMessageDatatype() {
146 private Hashtable fIdDefs;
147 public Object getDatatypeObject(){
148 return(Object) fIdDefs;
149 }
150 public int getDatatypeState(){
151 return IDREFDatatypeValidator.IDREF_STORE;
152 }
153 public void setDatatypeObject( Object data ){
154 fIdDefs = (Hashtable) data;
155 }
156 };
157
158 private StateMessageDatatype fResetID = new StateMessageDatatype() {
159 public Object getDatatypeObject(){
160 return(Object) null;
161 }
162 public int getDatatypeState(){
163 return IDDatatypeValidator.ID_CLEAR;
164 }
165 public void setDatatypeObject( Object data ){
166 }
167 };
168
169
170 private StateMessageDatatype fResetIDRef = new StateMessageDatatype() {
171 public Object getDatatypeObject(){
172 return(Object) null;
173 }
174 public int getDatatypeState(){
175 return IDREFDatatypeValidator.IDREF_CLEAR;
176 }
177 public void setDatatypeObject( Object data ){
178 }
179 };
180
181 private StateMessageDatatype fValidateIDRef = new StateMessageDatatype() {
182 public Object getDatatypeObject(){
183 return(Object) null;
184 }
185 public int getDatatypeState(){
186 return IDREFDatatypeValidator.IDREF_VALIDATE;
187 }
188 public void setDatatypeObject( Object data ){
189 }
190 };
191
192
193 private StateMessageDatatype fValidateENTITYMsg = new StateMessageDatatype() {
194 private Object packagedMessage = null;
195 public Object getDatatypeObject(){
196 return packagedMessage;
197 }
198 public int getDatatypeState(){
199 return ENTITYDatatypeValidator.ENTITY_INITIALIZE;//No state
200 }
201 public void setDatatypeObject( Object data ){
202 packagedMessage = data;// Set Entity Handler
203 }
204 };
205
206 /*
207 private StateMessageDatatype fValidateNOTATIONMsg = new StateMessageDatatype() {
208 private Object packagedMessage = null;
209 public Object getDatatypeObject(){
210 return packagedMessage;
211 }
212 public int getDatatypeState(){
213 return NOTATIONDatatypeValidator.ENTITY_INITIALIZE;//No state
214 }
215 public void setDatatypeObject( Object data ){
216 packagedMessage = data;// Set Entity Handler
217 }
218 };
219 */
220
221
222
223
224
225 //
226 // Data
227 //
228
229 // REVISIT: The data should be regrouped and re-organized so that
230 // it's easier to find a meaningful field.
231
232 // debugging
233
234 // private static boolean DEBUG = false;
235
236 // other
237
238 // attribute validators
239
240 private AttributeValidator fAttValidatorNOTATION = new AttValidatorNOTATION();
241 private AttributeValidator fAttValidatorENUMERATION = new AttValidatorENUMERATION();
242 private AttributeValidator fAttValidatorDATATYPE = null;
243
244 // Package access for use by AttributeValidator classes.
245
246 StringPool fStringPool = null;
247 boolean fValidating = false;
248 boolean fInElementContent = false;
249 int fStandaloneReader = -1;
250
251
252 // settings
253
254 private boolean fValidationEnabled = false;
255 private boolean fDynamicValidation = false;
256 private boolean fSchemaValidation = true;
257 private boolean fValidationEnabledByDynamic = false;
258 private boolean fDynamicDisabledByValidation = false;
259 private boolean fWarningOnDuplicateAttDef = false;
260 private boolean fWarningOnUndeclaredElements = false;
261 private boolean fLoadDTDGrammar = true;
262
263 // declarations
264
265 private int fDeclaration[];
266 private XMLErrorReporter fErrorReporter = null;
267 private DefaultEntityHandler fEntityHandler = null;
268 private QName fCurrentElement = new QName();
269
270 private ContentLeafNameTypeVector[] fContentLeafStack = new ContentLeafNameTypeVector[8];
271 private int[] fValidationFlagStack = new int[8];
272
273 private int[] fScopeStack = new int[8];
274 private int[] fGrammarNameSpaceIndexStack = new int[8];
275
276 private int[] fElementEntityStack = new int[8];
277 private int[] fElementIndexStack = new int[8];
278 private int[] fContentSpecTypeStack = new int[8];
279
280 private static final int sizeQNameParts = 8;
281 private QName[] fElementQNamePartsStack = new QName[sizeQNameParts];
282
283 private QName[] fElementChildren = new QName[32];
284 private int fElementChildrenLength = 0;
285 private int[] fElementChildrenOffsetStack = new int[32];
286 private int fElementDepth = -1;
287
288 private boolean fNamespacesEnabled = false;
289 private NamespacesScope fNamespacesScope = null;
290 private int fNamespacesPrefix = -1;
291 private QName fRootElement = new QName();
292 private int fAttrListHandle = -1;
293 private int fCurrentElementEntity = -1;
294 private int fCurrentElementIndex = -1;
295 private int fCurrentContentSpecType = -1;
296 private boolean fSeenDoctypeDecl = false;
297
298 private final int TOP_LEVEL_SCOPE = -1;
299 private int fCurrentScope = TOP_LEVEL_SCOPE;
300 private int fCurrentSchemaURI = -1;
301 private int fEmptyURI = - 1;
302 private int fXsiPrefix = - 1;
303 private int fXsiURI = -2;
304 private int fXsiTypeAttValue = -1;
305 private DatatypeValidator fXsiTypeValidator = null;
306
307 private Grammar fGrammar = null;
308 private int fGrammarNameSpaceIndex = -1;
309 private GrammarResolver fGrammarResolver = null;
310
311 // state and stuff
312
313 private boolean fScanningDTD = false;
314 private XMLDocumentScanner fDocumentScanner = null;
315 private boolean fCalledStartDocument = false;
316 private XMLDocumentHandler fDocumentHandler = null;
317 private XMLDocumentHandler.DTDHandler fDTDHandler = null;
318 private boolean fSeenRootElement = false;
319 private XMLAttrList fAttrList = null;
320 private int fXMLLang = -1;
321 private LocatorImpl fAttrNameLocator = null;
322 private boolean fCheckedForSchema = false;
323 private boolean fDeclsAreExternal = false;
324 private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
325 private char[] fCharRefData = null;
326 private boolean fSendCharDataAsCharArray = false;
327 private boolean fBufferDatatype = false;
328 private StringBuffer fDatatypeBuffer = new StringBuffer();
329
330 private QName fTempQName = new QName();
331 private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
332 private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
333 private XMLElementDecl fTempElementDecl = new XMLElementDecl();
334
335 private boolean fGrammarIsDTDGrammar = false;
336 private boolean fGrammarIsSchemaGrammar = false;
337
338 private boolean fNeedValidationOff = false;
339
340 // symbols
341
342 private int fEMPTYSymbol = -1;
343 private int fANYSymbol = -1;
344 private int fMIXEDSymbol = -1;
345 private int fCHILDRENSymbol = -1;
346 private int fCDATASymbol = -1;
347 private int fIDSymbol = -1;
348 private int fIDREFSymbol = -1;
349 private int fIDREFSSymbol = -1;
350 private int fENTITYSymbol = -1;
351 private int fENTITIESSymbol = -1;
352 private int fNMTOKENSymbol = -1;
353 private int fNMTOKENSSymbol = -1;
354 private int fNOTATIONSymbol = -1;
355 private int fENUMERATIONSymbol = -1;
356 private int fREQUIREDSymbol = -1;
357 private int fFIXEDSymbol = -1;
358 private int fDATATYPESymbol = -1;
359 private int fEpsilonIndex = -1;
360
361
362 //Datatype Registry
363
364 private DatatypeValidatorFactoryImpl fDataTypeReg =
365 DatatypeValidatorFactoryImpl.getDatatypeRegistry();
366
367 private DatatypeValidator fValID = this.fDataTypeReg.getDatatypeValidator("ID" );
368 private DatatypeValidator fValIDRef = this.fDataTypeReg.getDatatypeValidator("IDREF" );
369 private DatatypeValidator fValIDRefs = this.fDataTypeReg.getDatatypeValidator("IDREFS" );
370 private DatatypeValidator fValENTITY = this.fDataTypeReg.getDatatypeValidator("ENTITY" );
371 private DatatypeValidator fValENTITIES = this.fDataTypeReg.getDatatypeValidator("ENTITIES" );
372 private DatatypeValidator fValNMTOKEN = this.fDataTypeReg.getDatatypeValidator("NMTOKEN");
373 private DatatypeValidator fValNMTOKENS = this.fDataTypeReg.getDatatypeValidator("NMTOKENS");
374 private DatatypeValidator fValNOTATION = this.fDataTypeReg.getDatatypeValidator("NOTATION" );
375
376
377 //
378 // Constructors
379 //
380
381 /** Constructs an XML validator. */
382 public XMLValidator(StringPool stringPool,
383 XMLErrorReporter errorReporter,
384 DefaultEntityHandler entityHandler,
385 XMLDocumentScanner documentScanner) {
386
387 // keep references
388 fStringPool = stringPool;
389 fErrorReporter = errorReporter;
390 fEntityHandler = entityHandler;
391 fDocumentScanner = documentScanner;
392
393 fEmptyURI = fStringPool.addSymbol("");
394 fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
395 // initialize
396 fAttrList = new XMLAttrList(fStringPool);
397 entityHandler.setEventHandler(this);
398 entityHandler.setCharDataHandler(this);
399 fDocumentScanner.setEventHandler(this);
400
401 for (int i = 0; i < sizeQNameParts; i++) {
402 fElementQNamePartsStack[i] = new QName();
403 }
404 init();
405
406 } // <init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)
407
408 public void setGrammarResolver(GrammarResolver grammarResolver){
409 fGrammarResolver = grammarResolver;
410 }
411
412 //
413 // Public methods
414 //
415
416 // initialization
417
418 /** Set char data processing preference and handlers. */
419 public void initHandlers(boolean sendCharDataAsCharArray,
420 XMLDocumentHandler docHandler,
421 XMLDocumentHandler.DTDHandler dtdHandler) {
422
423 fSendCharDataAsCharArray = sendCharDataAsCharArray;
424 fEntityHandler.setSendCharDataAsCharArray(fSendCharDataAsCharArray);
425 fDocumentHandler = docHandler;
426 fDTDHandler = dtdHandler;
427
428 } // initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)
429
430 /** Reset or copy. */
431 public void resetOrCopy(StringPool stringPool) throws Exception {
432 fAttrList = new XMLAttrList(stringPool);
433 resetCommon(stringPool);
434 }
435
436 /** Reset. */
437 public void reset(StringPool stringPool) throws Exception {
438 fAttrList.reset(stringPool);
439 resetCommon(stringPool);
440 }
441
442
443 // settings
444
445 /**
446 * Turning on validation/dynamic turns on validation if it is off, and
447 * this is remembered. Turning off validation DISABLES validation/dynamic
448 * if it is on. Turning off validation/dynamic DOES NOT turn off
449 * validation if it was explicitly turned on, only if it was turned on
450 * BECAUSE OF the call to turn validation/dynamic on. Turning on
451 * validation will REENABLE and turn validation/dynamic back on if it
452 * was disabled by a call that turned off validation while
453 * validation/dynamic was enabled.
454 */
455 public void setValidationEnabled(boolean flag) throws Exception {
456 fValidationEnabled = flag;
457 fValidationEnabledByDynamic = false;
458 if (fValidationEnabled) {
459 if (fDynamicDisabledByValidation) {
460 fDynamicValidation = true;
461 fDynamicDisabledByValidation = false;
462 }
463 } else if (fDynamicValidation) {
464 fDynamicValidation = false;
465 fDynamicDisabledByValidation = true;
466 }
467 fValidating = fValidationEnabled;
468 }
469
470 /** Returns true if validation is enabled. */
471 public boolean getValidationEnabled() {
472 return fValidationEnabled;
473 }
474
475 /** Sets whether Schema support is on/off. */
476 public void setSchemaValidationEnabled(boolean flag) {
477 fSchemaValidation = flag;
478 }
479
480 /** Returns true if Schema support is on. */
481 public boolean getSchemaValidationEnabled() {
482 return fSchemaValidation;
483 }
484
485 /** Sets whether validation is dynamic. */
486 public void setDynamicValidationEnabled(boolean flag) throws Exception {
487 fDynamicValidation = flag;
488 fDynamicDisabledByValidation = false;
489 if (!fDynamicValidation) {
490 if (fValidationEnabledByDynamic) {
491 fValidationEnabled = false;
492 fValidationEnabledByDynamic = false;
493 }
494 } else if (!fValidationEnabled) {
495 fValidationEnabled = true;
496 fValidationEnabledByDynamic = true;
497 }
498 fValidating = fValidationEnabled;
499 }
500
501 /** Returns true if validation is dynamic. */
502 public boolean getDynamicValidationEnabled() {
503 return fDynamicValidation;
504 }
505
506 /** Sets fLoadDTDGrammar when validation is off **/
507 public void setLoadDTDGrammar(boolean loadDG){
508 if (fValidating) {
509 fLoadDTDGrammar = true;
510 } else {
511 fLoadDTDGrammar = loadDG;
512 }
513 }
514
515 /** Returns fLoadDTDGrammar **/
516 public boolean getLoadDTDGrammar() {
517 return fLoadDTDGrammar;
518 }
519
520 /** Sets whether namespaces are enabled. */
521 public void setNamespacesEnabled(boolean flag) {
522 fNamespacesEnabled = flag;
523 }
524
525 /** Returns true if namespaces are enabled. */
526 public boolean getNamespacesEnabled() {
527 return fNamespacesEnabled;
528 }
529
530 /** Sets whether duplicate attribute definitions signal a warning. */
531 public void setWarningOnDuplicateAttDef(boolean flag) {
532 fWarningOnDuplicateAttDef = flag;
533 }
534
535 /** Returns true if duplicate attribute definitions signal a warning. */
536 public boolean getWarningOnDuplicateAttDef() {
537 return fWarningOnDuplicateAttDef;
538 }
539
540 /** Sets whether undeclared elements signal a warning. */
541 public void setWarningOnUndeclaredElements(boolean flag) {
542 fWarningOnUndeclaredElements = flag;
543 }
544
545 /** Returns true if undeclared elements signal a warning. */
546 public boolean getWarningOnUndeclaredElements() {
547 return fWarningOnUndeclaredElements;
548 }
549
550 //
551 // DefaultEntityHandler.EventHandler methods
552 //
553
554 /** Start entity reference. */
555 public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception {
556 fDocumentHandler.startEntityReference(entityName, entityType, entityContext);
557 }
558
559 /** End entity reference. */
560 public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception {
561 fDocumentHandler.endEntityReference(entityName, entityType, entityContext);
562 }
563
564 /** Send end of input notification. */
565 public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception {
566 fDocumentScanner.endOfInput(entityName, moreToFollow);
567 /***
568 if (fScanningDTD) {
569 fDTDImporter.sendEndOfInputNotifications(entityName, moreToFollow);
570 }
571 /***/
572 }
573
574 /** Send reader change notifications. */
575 public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception {
576 fDocumentScanner.readerChange(reader, readerId);
577 /***
578 if (fScanningDTD) {
579 fDTDImporter.sendReaderChangeNotifications(reader, readerId);
580 }
581 /***/
582 }
583
584 /** External entity standalone check. */
585 public boolean externalEntityStandaloneCheck() {
586 return(fStandaloneReader != -1 && fValidating);
587 }
588
589 /** Return true if validating. */
590 public boolean getValidating() {
591 return fValidating;
592 }
593
594 //
595 // XMLEntityHandler.CharDataHandler methods
596 //
597
598 /** Process characters. */
599 public void processCharacters(char[] chars, int offset, int length) throws Exception {
600 if (fValidating) {
601 if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
602 charDataInContent();
603 }
604 if (fBufferDatatype) {
605 fDatatypeBuffer.append(chars, offset, length);
606 }
607 }
608 fDocumentHandler.characters(chars, offset, length);
609 }
610
611 /** Process characters. */
612 public void processCharacters(int data) throws Exception {
613 if (fValidating) {
614 if (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
615 charDataInContent();
616 }
617 if (fBufferDatatype) {
618 fDatatypeBuffer.append(fStringPool.toString(data));
619 }
620 }
621 fDocumentHandler.characters(data);
622 }
623
624 /** Process whitespace. */
625 public void processWhitespace(char[] chars, int offset, int length)
626 throws Exception {
627
628 if (fInElementContent) {
629 if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
630 reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
631 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
632 }
633 fDocumentHandler.ignorableWhitespace(chars, offset, length);
634 } else {
635 if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
636 charDataInContent();
637 }
638 fDocumentHandler.characters(chars, offset, length);
639 }
640
641 } // processWhitespace(char[],int,int)
642
643 /** Process whitespace. */
644 public void processWhitespace(int data) throws Exception {
645
646 if (fInElementContent) {
647 if (fStandaloneReader != -1 && fValidating && getElementDeclIsExternal(fCurrentElementIndex)) {
648 reportRecoverableXMLError(XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
649 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
650 }
651 fDocumentHandler.ignorableWhitespace(data);
652 } else {
653 if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
654 charDataInContent();
655 }
656 fDocumentHandler.characters(data);
657 }
658
659 } // processWhitespace(int)
660
661 //
662 // XMLDocumentScanner.EventHandler methods
663 //
664
665 /** Scans element type. */
666 public void scanElementType(XMLEntityHandler.EntityReader entityReader,
667 char fastchar, QName element) throws Exception {
668
669 if (!fNamespacesEnabled) {
670 element.clear();
671 element.localpart = entityReader.scanName(fastchar);
672 element.rawname = element.localpart;
673 } else {
674 entityReader.scanQName(fastchar, element);
675 if (entityReader.lookingAtChar(':', false)) {
676 fErrorReporter.reportError(fErrorReporter.getLocator(),
677 XMLMessages.XML_DOMAIN,
678 XMLMessages.MSG_TWO_COLONS_IN_QNAME,
679 XMLMessages.P5_INVALID_CHARACTER,
680 null,
681 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
682 entityReader.skipPastNmtoken(' ');
683 }
684 }
685
686 } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
687
688 /** Scans expected element type. */
689 public boolean scanExpectedElementType(XMLEntityHandler.EntityReader entityReader,
690 char fastchar, QName element)
691 throws Exception {
692
693 if (fCurrentElementCharArrayRange == null) {
694 fCurrentElementCharArrayRange = fStringPool.createCharArrayRange();
695 }
696 fStringPool.getCharArrayRange(fCurrentElement.rawname, fCurrentElementCharArrayRange);
697 return entityReader.scanExpectedName(fastchar, fCurrentElementCharArrayRange);
698
699 } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
700
701 /** Scans attribute name. */
702 public void scanAttributeName(XMLEntityHandler.EntityReader entityReader,
703 QName element, QName attribute)
704 throws Exception {
705
706 if (!fSeenRootElement) {
707 fSeenRootElement = true;
708 rootElementSpecified(element);
709 fStringPool.resetShuffleCount();
710 }
711
712 if (!fNamespacesEnabled) {
713 attribute.clear();
714 attribute.localpart = entityReader.scanName('=');
715 attribute.rawname = attribute.localpart;
716 } else {
717 entityReader.scanQName('=', attribute);
718 if (entityReader.lookingAtChar(':', false)) {
719 fErrorReporter.reportError(fErrorReporter.getLocator(),
720 XMLMessages.XML_DOMAIN,
721 XMLMessages.MSG_TWO_COLONS_IN_QNAME,
722 XMLMessages.P5_INVALID_CHARACTER,
723 null,
724 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
725 entityReader.skipPastNmtoken(' ');
726 }
727 }
728
729 } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)
730
731 /** Call start document. */
732 public void callStartDocument() throws Exception {
733
734 if (!fCalledStartDocument) {
735 fDocumentHandler.startDocument();
736 fCalledStartDocument = true;
737 }
738 }
739
740 /** Call end document. */
741 public void callEndDocument() throws Exception {
742
743 if (fCalledStartDocument) {
744 fDocumentHandler.endDocument();
745 }
746 }
747
748 /** Call XML declaration. */
749 public void callXMLDecl(int version, int encoding, int standalone) throws Exception {
750 fDocumentHandler.xmlDecl(version, encoding, standalone);
751 }
752 public void callStandaloneIsYes() throws Exception {
753 // standalone = "yes". said XMLDocumentScanner.
754 fStandaloneReader = fEntityHandler.getReaderId() ;
755
756 }
757
758
759
760 /** Call text declaration. */
761 public void callTextDecl(int version, int encoding) throws Exception {
762 fDocumentHandler.textDecl(version, encoding);
763 }
764
765 /**
766 * Signal the scanning of an element name in a start element tag.
767 *
768 * @param element Element name scanned.
769 */
770 public void element(QName element) throws Exception {
771 fAttrListHandle = -1;
772 }
773 /**
774 * Signal the scanning of an attribute associated to the previous
775 * start element tag.
776 *
777 * @param element Element name scanned.
778 * @param attrName Attribute name scanned.
779 * @param attrValue The string pool index of the attribute value.
780 */
781 public boolean attribute(QName element, QName attrName, int attrValue) throws Exception {
782 if (fAttrListHandle == -1) {
783 fAttrListHandle = fAttrList.startAttrList();
784 }
785
786 // if fAttrList.addAttr returns -1, indicates duplicate att in start tag of an element.
787 // specified: true, search : true
788 return fAttrList.addAttr(attrName, attrValue, fCDATASymbol, true, true) == -1;
789 }
790
791 /** Call start element. */
792 public void callStartElement(QName element) throws Exception {
793
794 if ( DEBUG_SCHEMA_VALIDATION )
795 System.out.println("\n=======StartElement : " + fStringPool.toString(element.localpart));
796
797
798 //
799 // Check after all specified attrs are scanned
800 // (1) report error for REQUIRED attrs that are missing (V_TAGc)
801 // (2) add default attrs (FIXED and NOT_FIXED)
802 //
803
804 if (!fSeenRootElement) {
805 fSeenRootElement = true;
806 rootElementSpecified(element);
807 fStringPool.resetShuffleCount();
808 }
809
810 if (fGrammar != null && fGrammarIsDTDGrammar) {
811 fAttrListHandle = addDTDDefaultAttributes(element, fAttrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
812 }
813
814 fCheckedForSchema = true;
815 if (fNamespacesEnabled) {
816 bindNamespacesToElementAndAttributes(element, fAttrList);
817 }
818
819 validateElementAndAttributes(element, fAttrList);
820 if (fAttrListHandle != -1) {
821 fAttrList.endAttrList();
822 }
823
824 fDocumentHandler.startElement(element, fAttrList, fAttrListHandle);
825 fAttrListHandle = -1;
826
827 //before we increment the element depth, add this element's QName to its enclosing element 's children list
828 fElementDepth++;
829 //if (fElementDepth >= 0) {
830 if (fValidating) {
831 // push current length onto stack
832 if (fElementChildrenOffsetStack.length < fElementDepth) {
833 int newarray[] = new int[fElementChildrenOffsetStack.length * 2];
834 System.arraycopy(fElementChildrenOffsetStack, 0, newarray, 0, fElementChildrenOffsetStack.length);
835 fElementChildrenOffsetStack = newarray;
836 }
837 fElementChildrenOffsetStack[fElementDepth] = fElementChildrenLength;
838
839 // add this element to children
840 if (fElementChildren.length <= fElementChildrenLength) {
841 QName[] newarray = new QName[fElementChildrenLength * 2];
842 System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
843 fElementChildren = newarray;
844 }
845 QName qname = fElementChildren[fElementChildrenLength];
846 if (qname == null) {
847 for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
848 fElementChildren[i] = new QName();
849 }
850 qname = fElementChildren[fElementChildrenLength];
851 }
852 qname.setValues(element);
853 fElementChildrenLength++;
854
855 if (DEBUG_ELEMENT_CHILDREN) {
856 printChildren();
857 printStack();
858 }
859 }
860
861 // One more level of depth
862 //fElementDepth++;
863
864 ensureStackCapacity(fElementDepth);
865 fCurrentElement.setValues(element);
866 fCurrentElementEntity = fEntityHandler.getReaderId();
867
868 fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement);
869
870 fElementEntityStack[fElementDepth] = fCurrentElementEntity;
871 fElementIndexStack[fElementDepth] = fCurrentElementIndex;
872 fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
873
874 if (fNeedValidationOff) {
875 fValidating = false;
876 fNeedValidationOff = false;
877 }
878
879 if (fValidating && fGrammarIsSchemaGrammar) {
880 pushContentLeafStack();
881 }
882
883 fValidationFlagStack[fElementDepth] = fValidating ? 0 : -1;
884
885 fScopeStack[fElementDepth] = fCurrentScope;
886 fGrammarNameSpaceIndexStack[fElementDepth] = fGrammarNameSpaceIndex;
887
888 } // callStartElement(QName)
889
890 private void pushContentLeafStack() throws Exception {
891 int contentType = getContentSpecType(fCurrentElementIndex);
892 if ( contentType == XMLElementDecl.TYPE_CHILDREN) {
893 XMLContentModel cm = getElementContentModel(fCurrentElementIndex);
894 ContentLeafNameTypeVector cv = cm.getContentLeafNameTypeVector();
895 if (cm != null) {
896 fContentLeafStack[fElementDepth] = cv;
897 }
898 }
899 }
900
901 private void ensureStackCapacity ( int newElementDepth) {
902
903 if (newElementDepth == fElementQNamePartsStack.length ) {
904 int[] newStack = new int[newElementDepth * 2];
905 System.arraycopy(fScopeStack, 0, newStack, 0, newElementDepth);
906 fScopeStack = newStack;
907
908 newStack = new int[newElementDepth * 2];
909 System.arraycopy(fGrammarNameSpaceIndexStack, 0, newStack, 0, newElementDepth);
910 fGrammarNameSpaceIndexStack = newStack;
911
912 QName[] newStackOfQueue = new QName[newElementDepth * 2];
913 System.arraycopy(this.fElementQNamePartsStack, 0, newStackOfQueue, 0, newElementDepth );
914 fElementQNamePartsStack = newStackOfQueue;
915
916 QName qname = fElementQNamePartsStack[newElementDepth];
917 if (qname == null) {
918 for (int i = newElementDepth; i < fElementQNamePartsStack.length; i++) {
919 fElementQNamePartsStack[i] = new QName();
920 }
921 }
922
923 newStack = new int[newElementDepth * 2];
924 System.arraycopy(fElementEntityStack, 0, newStack, 0, newElementDepth);
925 fElementEntityStack = newStack;
926
927 newStack = new int[newElementDepth * 2];
928 System.arraycopy(fElementIndexStack, 0, newStack, 0, newElementDepth);
929 fElementIndexStack = newStack;
930
931 newStack = new int[newElementDepth * 2];
932 System.arraycopy(fContentSpecTypeStack, 0, newStack, 0, newElementDepth);
933 fContentSpecTypeStack = newStack;
934
935 newStack = new int[newElementDepth * 2];
936 System.arraycopy(fValidationFlagStack, 0, newStack, 0, newElementDepth);
937 fValidationFlagStack = newStack;
938
939 ContentLeafNameTypeVector[] newStackV = new ContentLeafNameTypeVector[newElementDepth * 2];
940 System.arraycopy(fContentLeafStack, 0, newStackV, 0, newElementDepth);
941 fContentLeafStack = newStackV;
942 }
943 }
944
945 /** Call end element. */
946 public void callEndElement(int readerId) throws Exception {
947 if ( DEBUG_SCHEMA_VALIDATION )
948 System.out.println("=======EndElement : " + fStringPool.toString(fCurrentElement.localpart)+"\n");
949
950 int prefixIndex = fCurrentElement.prefix;
951 int elementType = fCurrentElement.rawname;
952
953 if (fCurrentElementEntity != readerId) {
954 fErrorReporter.reportError(fErrorReporter.getLocator(),
955 XMLMessages.XML_DOMAIN,
956 XMLMessages.MSG_ELEMENT_ENTITY_MISMATCH,
957 XMLMessages.P78_NOT_WELLFORMED,
958 new Object[] { fStringPool.toString(elementType)},
959 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
960 }
961
962 fElementDepth--;
963 if (fValidating) {
964 int elementIndex = fCurrentElementIndex;
965 if (elementIndex != -1 && fCurrentContentSpecType != -1) {
966 QName children[] = fElementChildren;
967 int childrenOffset = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
968 int childrenLength = fElementChildrenLength - childrenOffset;
969 if (DEBUG_ELEMENT_CHILDREN) {
970 System.out.println("endElement("+fStringPool.toString(fCurrentElement.rawname)+')');
971 System.out.println("fCurrentContentSpecType : " + fCurrentContentSpecType );
972 System.out.print("offset: ");
973 System.out.print(childrenOffset);
974 System.out.print(", length: ");
975 System.out.print(childrenLength);
976 System.out.println();
977 printChildren();
978 printStack();
979 }
980 int result = checkContent(elementIndex,
981 children, childrenOffset, childrenLength);
982
983 if ( DEBUG_SCHEMA_VALIDATION )
984 System.out.println("!!!!!!!!In XMLValidator, the return value from checkContent : " + result);
985
986 if (result != -1) {
987 int majorCode = result != childrenLength ? XMLMessages.MSG_CONTENT_INVALID : XMLMessages.MSG_CONTENT_INCOMPLETE;
988 fGrammar.getElementDecl(elementIndex, fTempElementDecl);
989 if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
990 reportRecoverableXMLError(majorCode,
991 0,
992 fStringPool.toString(elementType),
993 "EMPTY");
994 } else
995 reportRecoverableXMLError(majorCode,
996 0,
997 fStringPool.toString(elementType),
998 XMLContentSpec.toString(fGrammar, fStringPool, fTempElementDecl.contentSpecIndex));
999 }
1000 }
1001 fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
1002 }
1003 fDocumentHandler.endElement(fCurrentElement);
1004 if (fNamespacesEnabled) {
1005 fNamespacesScope.decreaseDepth();
1006 }
1007
1008 // now pop this element off the top of the element stack
1009 //if (fElementDepth-- < 0) {
1010 if (fElementDepth < -1) {
1011 throw new RuntimeException("FWK008 Element stack underflow");
1012 }
1013 if (fElementDepth < 0) {
1014 fCurrentElement.clear();
1015 fCurrentElementEntity = -1;
1016 fCurrentElementIndex = -1;
1017 fCurrentContentSpecType = -1;
1018 fInElementContent = false;
1019 //
1020 // Check after document is fully parsed
1021 // (1) check that there was an element with a matching id for every
1022 // IDREF and IDREFS attr (V_IDREF0)
1023 //
1024 if (fValidating ) {
1025 try {
1026 this.fValIDRef.validate( null, this.fValidateIDRef );
1027 this.fValIDRefs.validate( null, this.fValidateIDRef );
1028 } catch ( InvalidDatatypeValueException ex ) {
1029 reportRecoverableXMLError( ex.getMajorCode(), ex.getMinorCode(),
1030 ex.getMessage() );
1031
1032
1033 }
1034 }
1035
1036 try {//Reset datatypes state
1037 this.fValID.validate( null, this.fResetID );
1038 this.fValIDRef.validate(null, this.fResetIDRef );
1039 this.fValIDRefs.validate(null, this.fResetIDRef );
1040 } catch ( InvalidDatatypeValueException ex ) {
1041 System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
1042 }
1043 return;
1044 }
1045
1046
1047 //restore enclosing element to all the "current" variables
1048 // REVISIT: Validation. This information needs to be stored.
1049 fCurrentElement.prefix = -1;
1050
1051
1052 if (fNamespacesEnabled) { //If Namespace enable then localName != rawName
1053 fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].localpart;
1054 } else {//REVISIT - jeffreyr - This is so we still do old behavior when namespace is off
1055 fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].rawname;
1056 }
1057 fCurrentElement.rawname = fElementQNamePartsStack[fElementDepth].rawname;
1058 fCurrentElement.uri = fElementQNamePartsStack[fElementDepth].uri;
1059 fCurrentElement.prefix = fElementQNamePartsStack[fElementDepth].prefix;
1060
1061
1062 fCurrentElementEntity = fElementEntityStack[fElementDepth];
1063 fCurrentElementIndex = fElementIndexStack[fElementDepth];
1064 fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
1065
1066 fValidating = fValidationFlagStack[fElementDepth] == 0 ? true : false;
1067
1068 fCurrentScope = fScopeStack[fElementDepth];
1069
1070 //if ( DEBUG_SCHEMA_VALIDATION ) {
1071
1072/****
1073System.out.println("+++++ currentElement : " + fStringPool.toString(elementType)+
1074 "\n fCurrentElementIndex : " + fCurrentElementIndex +
1075 "\n fCurrentScope : " + fCurrentScope +
1076 "\n fCurrentContentSpecType : " + fCurrentContentSpecType +
1077 "\n++++++++++++++++++++++++++++++++++++++++++++++++" );
1078/****/
1079 //}
1080
1081 // if enclosing element's Schema is different, need to switch "context"
1082 if ( fGrammarNameSpaceIndex != fGrammarNameSpaceIndexStack[fElementDepth] ) {
1083 fGrammarNameSpaceIndex = fGrammarNameSpaceIndexStack[fElementDepth];
1084 if ( fValidating && fGrammarIsSchemaGrammar )
1085 if ( !switchGrammar(fGrammarNameSpaceIndex) ) {
1086 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR,
1087 "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex)
1088 + " , can not found");
1089 }
1090 }
1091
1092 if (fValidating) {
1093 fBufferDatatype = false;
1094 }
1095 fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
1096
1097 } // callEndElement(int)
1098
1099 /** Call start CDATA section. */
1100 public void callStartCDATA() throws Exception {
1101 fDocumentHandler.startCDATA();
1102 }
1103
1104 /** Call end CDATA section. */
1105 public void callEndCDATA() throws Exception {
1106 fDocumentHandler.endCDATA();
1107 }
1108
1109 /** Call characters. */
1110 public void callCharacters(int ch) throws Exception {
1111
1112 if (fCharRefData == null) {
1113 fCharRefData = new char[2];
1114 }
1115 int count = (ch < 0x10000) ? 1 : 2;
1116 if (count == 1) {
1117 fCharRefData[0] = (char)ch;
1118 } else {
1119 fCharRefData[0] = (char)(((ch-0x00010000)>>10)+0xd800);
1120 fCharRefData[1] = (char)(((ch-0x00010000)&0x3ff)+0xdc00);
1121 }
1122 if (fValidating && (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY)) {
1123 charDataInContent();
1124 }
1125 if (fSendCharDataAsCharArray) {
1126 fDocumentHandler.characters(fCharRefData, 0, count);
1127 } else {
1128 int index = fStringPool.addString(new String(fCharRefData, 0, count));
1129 fDocumentHandler.characters(index);
1130 }
1131
1132 } // callCharacters(int)
1133
1134 /** Call processing instruction. */
1135 public void callProcessingInstruction(int target, int data) throws Exception {
1136 fDocumentHandler.processingInstruction(target, data);
1137 }
1138
1139 /** Call comment. */
1140 public void callComment(int comment) throws Exception {
1141 fDocumentHandler.comment(comment);
1142 }
1143
1144 //
1145 // NamespacesScope.NamespacesHandler methods
1146 //
1147
1148 /** Start a new namespace declaration scope. */
1149 public void startNamespaceDeclScope(int prefix, int uri) throws Exception {
1150 fDocumentHandler.startNamespaceDeclScope(prefix, uri);
1151 }
1152
1153 /** End a namespace declaration scope. */
1154 public void endNamespaceDeclScope(int prefix) throws Exception {
1155 fDocumentHandler.endNamespaceDeclScope(prefix);
1156 }
1157
1158 // attributes
1159
1160
1161 // other
1162
1163 /** Sets the root element. */
1164 public void setRootElementType(QName rootElement) {
1165 fRootElement.setValues(rootElement);
1166 }
1167
1168 /**
1169 * Returns true if the element declaration is external.
1170 * <p>
1171 * <strong>Note:</strong> This method is primarilly useful for
1172 * DTDs with internal and external subsets.
1173 */
1174 private boolean getElementDeclIsExternal(int elementIndex) {
1175 /*if (elementIndex < 0 || elementIndex >= fElementCount) {
1176 return false;
1177 }
1178 int chunk = elementIndex >> CHUNK_SHIFT;
1179 int index = elementIndex & CHUNK_MASK;
1180 return (fElementDeclIsExternal[chunk][index] != 0);
1181 */
1182
1183 if (fGrammarIsDTDGrammar ) {
1184 return((DTDGrammar) fGrammar).getElementDeclIsExternal(elementIndex);
1185 }
1186 return false;
1187 }
1188
1189 /** Returns the content spec type for an element index. */
1190 public int getContentSpecType(int elementIndex) {
1191
1192 int contentSpecType = -1;
1193 if ( elementIndex > -1) {
1194 if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
1195 contentSpecType = fTempElementDecl.type;
1196 }
1197 }
1198 return contentSpecType;
1199 }
1200
1201 /** Returns the content spec handle for an element index. */
1202 public int getContentSpecHandle(int elementIndex) {
1203 int contentSpecHandle = -1;
1204 if ( elementIndex > -1) {
1205 if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
1206 contentSpecHandle = fTempElementDecl.contentSpecIndex;
1207 }
1208 }
1209 return contentSpecHandle;
1210 }
1211
1212 //
1213 // Protected methods
1214 //
1215
1216 // error reporting
1217
1218 /** Report a recoverable xml error. */
1219 protected void reportRecoverableXMLError(int majorCode, int minorCode)
1220 throws Exception {
1221
1222 fErrorReporter.reportError(fErrorReporter.getLocator(),
1223 XMLMessages.XML_DOMAIN,
1224 majorCode,
1225 minorCode,
1226 null,
1227 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1228
1229 } // reportRecoverableXMLError(int,int)
1230
1231 /** Report a recoverable xml error. */
1232 protected void reportRecoverableXMLError(int majorCode, int minorCode,
1233 int stringIndex1)
1234 throws Exception {
1235
1236 Object[] args = { fStringPool.toString(stringIndex1)};
1237 fErrorReporter.reportError(fErrorReporter.getLocator(),
1238 XMLMessages.XML_DOMAIN,
1239 majorCode,
1240 minorCode,
1241 args,
1242 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1243
1244 } // reportRecoverableXMLError(int,int,int)
1245
1246 /** Report a recoverable xml error. */
1247 protected void reportRecoverableXMLError(int majorCode, int minorCode,
1248 String string1) throws Exception {
1249
1250 Object[] args = { string1};
1251 fErrorReporter.reportError(fErrorReporter.getLocator(),
1252 XMLMessages.XML_DOMAIN,
1253 majorCode,
1254 minorCode,
1255 args,
1256 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1257
1258 } // reportRecoverableXMLError(int,int,String)
1259
1260 /** Report a recoverable xml error. */
1261 protected void reportRecoverableXMLError(int majorCode, int minorCode,
1262 int stringIndex1, int stringIndex2)
1263 throws Exception {
1264
1265 Object[] args = { fStringPool.toString(stringIndex1), fStringPool.toString(stringIndex2)};
1266 fErrorReporter.reportError(fErrorReporter.getLocator(),
1267 XMLMessages.XML_DOMAIN,
1268 majorCode,
1269 minorCode,
1270 args,
1271 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1272
1273 } // reportRecoverableXMLError(int,int,int,int)
1274
1275 /** Report a recoverable xml error. */
1276 protected void reportRecoverableXMLError(int majorCode, int minorCode,
1277 String string1, String string2)
1278 throws Exception {
1279
1280 Object[] args = { string1, string2};
1281 fErrorReporter.reportError(fErrorReporter.getLocator(),
1282 XMLMessages.XML_DOMAIN,
1283 majorCode,
1284 minorCode,
1285 args,
1286 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1287
1288 } // reportRecoverableXMLError(int,int,String,String)
1289
1290 /** Report a recoverable xml error. */
1291 protected void reportRecoverableXMLError(int majorCode, int minorCode,
1292 String string1, String string2,
1293 String string3) throws Exception {
1294
1295 Object[] args = { string1, string2, string3};
1296 fErrorReporter.reportError(fErrorReporter.getLocator(),
1297 XMLMessages.XML_DOMAIN,
1298 majorCode,
1299 minorCode,
1300 args,
1301 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1302
1303 } // reportRecoverableXMLError(int,int,String,String,String)
1304
1305 // content spec
1306
1307 /**
1308 * Returns information about which elements can be placed at a particular point
1309 * in the passed element's content model.
1310 * <p>
1311 * Note that the incoming content model to test must be valid at least up to
1312 * the insertion point. If not, then -1 will be returned and the info object
1313 * will not have been filled in.
1314 * <p>
1315 * If, on return, the info.isValidEOC flag is set, then the 'insert after'
1316 * elemement is a valid end of content, i.e. nothing needs to be inserted
1317 * after it to make the parent element's content model valid.
1318 *
1319 * @param elementIndex The index within the <code>ElementDeclPool</code> of the
1320 * element which is being querying.
1321 * @param fullyValid Only return elements that can be inserted and still
1322 * maintain the validity of subsequent elements past the
1323 * insertion point (if any). If the insertion point is at
1324 * the end, and this is true, then only elements that can
1325 * be legal final states will be returned.
1326 * @param info An object that contains the required input data for the method,
1327 * and which will contain the output information if successful.
1328 *
1329 * @return The value -1 if fully valid, else the 0 based index of the child
1330 * that first failed before the insertion point. If the value
1331 * returned is equal to the number of children, then the specified
1332 * children are valid but additional content is required to reach a
1333 * valid ending state.
1334 *
1335 * @exception Exception Thrown on error.
1336 *
1337 * @see InsertableElementsInfo
1338 */
1339 protected int whatCanGoHere(int elementIndex, boolean fullyValid,
1340 InsertableElementsInfo info) throws Exception {
1341
1342 //
1343 // Do some basic sanity checking on the info packet. First, make sure
1344 // that insertAt is not greater than the child count. It can be equal,
1345 // which means to get appendable elements, but not greater. Or, if
1346 // the current children array is null, that's bad too.
1347 //
1348 // Since the current children array must have a blank spot for where
1349 // the insert is going to be, the child count must always be at least
1350 // one.
1351 //
1352 // Make sure that the child count is not larger than the current children
1353 // array. It can be equal, which means get appendable elements, but not
1354 // greater.
1355 //
1356 if (info.insertAt > info.childCount || info.curChildren == null ||
1357 info.childCount < 1 || info.childCount > info.curChildren.length) {
1358 fErrorReporter.reportError(fErrorReporter.getLocator(),
1359 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
1360 ImplementationMessages.VAL_WCGHI,
1361 0,
1362 null,
1363 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1364 }
1365
1366 int retVal = 0;
1367 try {
1368 // Get the content model for this element
1369 final XMLContentModel cmElem = getElementContentModel(elementIndex);
1370
1371 // And delegate this call to it
1372 retVal = cmElem.whatCanGoHere(fullyValid, info);
1373 } catch (CMException excToCatch) {
1374 // REVISIT - Translate caught error to the protected error handler interface
1375 int majorCode = excToCatch.getErrorCode();
1376 fErrorReporter.reportError(fErrorReporter.getLocator(),
1377 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
1378 majorCode,
1379 0,
1380 null,
1381 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1382 throw excToCatch;
1383 }
1384 return retVal;
1385
1386 } // whatCanGoHere(int,boolean,InsertableElementsInfo):int
1387
1388 // attribute information
1389
1390 /** Protected for use by AttributeValidator classes. */
1391 protected boolean getAttDefIsExternal(QName element, QName attribute) {
1392 int attDefIndex = getAttDef(element, attribute);
1393 if (fGrammarIsDTDGrammar ) {
1394 return((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attDefIndex);
1395 }
1396 return false;
1397 }
1398
1399
1400
1401 //
1402 // Private methods
1403 //
1404
1405 // other
1406
1407 /** Returns true if using a standalone reader. */
1408 private boolean usingStandaloneReader() {
1409 return fStandaloneReader == -1 || fEntityHandler.getReaderId() == fStandaloneReader;
1410 }
1411
1412 /** Returns a locator implementation. */
1413 private LocatorImpl getLocatorImpl(LocatorImpl fillin) {
1414
1415 Locator here = fErrorReporter.getLocator();
1416 if (fillin == null)
1417 return new LocatorImpl(here);
1418 fillin.setPublicId(here.getPublicId());
1419 fillin.setSystemId(here.getSystemId());
1420 fillin.setLineNumber(here.getLineNumber());
1421 fillin.setColumnNumber(here.getColumnNumber());
1422 return fillin;
1423
1424 } // getLocatorImpl(LocatorImpl):LocatorImpl
1425
1426
1427 // initialization
1428
1429 /** Reset pool. */
1430 private void poolReset() {
1431 try {
1432 //System.out.println("We reset" );
1433 this.fValID.validate( null, this.fResetID );
1434 this.fValIDRef.validate(null, this.fResetIDRef );
1435 this.fValIDRefs.validate(null, this.fResetIDRef );
1436 } catch ( InvalidDatatypeValueException ex ) {
1437 System.err.println("Error re-Initializing: ID,IDRef,IDRefs pools" );
1438 }
1439 } // poolReset()
1440
1441 /** Reset common. */
1442 private void resetCommon(StringPool stringPool) throws Exception {
1443
1444 fStringPool = stringPool;
1445 fValidating = fValidationEnabled;
1446 fValidationEnabledByDynamic = false;
1447 fDynamicDisabledByValidation = false;
1448 poolReset();
1449 fCalledStartDocument = false;
1450 fStandaloneReader = -1;
1451 fElementChildrenLength = 0;
1452 fElementDepth = -1;
1453 fSeenRootElement = false;
1454 fSeenDoctypeDecl = false;
1455 fNamespacesScope = null;
1456 fNamespacesPrefix = -1;
1457 fRootElement.clear();
1458 fAttrListHandle = -1;
1459 fCheckedForSchema = false;
1460
1461 fCurrentScope = TOP_LEVEL_SCOPE;
1462 fCurrentSchemaURI = -1;
1463 fEmptyURI = - 1;
1464 fXsiPrefix = - 1;
1465 fXsiTypeValidator = null;
1466
1467 fGrammar = null;
1468 fGrammarNameSpaceIndex = -1;
1469 //fGrammarResolver = null;
1470 if (fGrammarResolver != null) {
1471 fGrammarResolver.clearGrammarResolver();
1472 }
1473 fGrammarIsDTDGrammar = false;
1474 fGrammarIsSchemaGrammar = false;
1475
1476
1477 init();
1478
1479 } // resetCommon(StringPool)
1480
1481 /** Initialize. */
1482 private void init() {
1483
1484 fEmptyURI = fStringPool.addSymbol("");
1485 fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
1486
1487
1488 fEMPTYSymbol = fStringPool.addSymbol("EMPTY");
1489 fANYSymbol = fStringPool.addSymbol("ANY");
1490 fMIXEDSymbol = fStringPool.addSymbol("MIXED");
1491 fCHILDRENSymbol = fStringPool.addSymbol("CHILDREN");
1492
1493 fCDATASymbol = fStringPool.addSymbol("CDATA");
1494 fIDSymbol = fStringPool.addSymbol("ID");
1495 fIDREFSymbol = fStringPool.addSymbol("IDREF");
1496 fIDREFSSymbol = fStringPool.addSymbol("IDREFS");
1497 fENTITYSymbol = fStringPool.addSymbol("ENTITY");
1498 fENTITIESSymbol = fStringPool.addSymbol("ENTITIES");
1499 fNMTOKENSymbol = fStringPool.addSymbol("NMTOKEN");
1500 fNMTOKENSSymbol = fStringPool.addSymbol("NMTOKENS");
1501 fNOTATIONSymbol = fStringPool.addSymbol("NOTATION");
1502 fENUMERATIONSymbol = fStringPool.addSymbol("ENUMERATION");
1503 fREQUIREDSymbol = fStringPool.addSymbol("#REQUIRED");
1504 fFIXEDSymbol = fStringPool.addSymbol("#FIXED");
1505 fDATATYPESymbol = fStringPool.addSymbol("<<datatype>>");
1506 fEpsilonIndex = fStringPool.addSymbol("<<CMNODE_EPSILON>>");
1507 fXMLLang = fStringPool.addSymbol("xml:lang");
1508
1509 try {//Initialize ENTITIES and ENTITY Validators
1510 Object[] packageArgsEntityVal = { (Object) this.fEntityHandler,
1511 (Object) this.fStringPool};
1512 fValidateENTITYMsg.setDatatypeObject( (Object ) packageArgsEntityVal);
1513 fValENTITIES.validate( null, fValidateENTITYMsg );
1514 fValENTITY.validate( null, fValidateENTITYMsg );
1515 } catch ( InvalidDatatypeValueException ex ) {
1516 System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
1517 }
1518
1519
1520 } // init()
1521
1522 // other
1523
1524 // default attribute
1525
1526 /** addDefaultAttributes. */
1527 private int addDefaultAttributes(int elementIndex, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {
1528
1529 //System.out.println("XMLValidator#addDefaultAttributes");
1530 //System.out.print(" ");
1531 //fGrammar.printAttributes(elementIndex);
1532
1533 //
1534 // Check after all specified attrs are scanned
1535 // (1) report error for REQUIRED attrs that are missing (V_TAGc)
1536 // (2) check that FIXED attrs have matching value (V_TAGd)
1537 // (3) add default attrs (FIXED and NOT_FIXED)
1538 //
1539 fGrammar.getElementDecl(elementIndex,fTempElementDecl);
1540
1541 int elementNameIndex = fTempElementDecl.name.localpart;
1542 int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
1543 int firstCheck = attrIndex;
1544 int lastCheck = -1;
1545 while (attlistIndex != -1) {
1546 //int adChunk = attlistIndex >> CHUNK_SHIFT;
1547 //int adIndex = attlistIndex & CHUNK_MASK;
1548 fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
1549
1550 // TO DO: For ericye Debug only
1551 /***
1552 if (fTempAttDecl != null) {
1553 XMLElementDecl element = new XMLElementDecl();
1554 fGrammar.getElementDecl(elementIndex, element);
1555 System.out.println("element: "+fStringPool.toString(element.name.localpart));
1556 System.out.println("attlistIndex " + attlistIndex + "\n"+
1557 "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
1558 + "attType : "+fTempAttDecl.type + "\n"
1559 + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
1560 + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
1561 + attrList.getLength() +"\n"
1562 );
1563 }
1564 /***/
1565
1566 int attPrefix = fTempAttDecl.name.prefix;
1567 int attName = fTempAttDecl.name.localpart;
1568 int attType = attributeTypeName(fTempAttDecl);
1569 int attDefType =fTempAttDecl.defaultType;
1570 int attValue = -1 ;
1571 if (fTempAttDecl.defaultValue != null ) {
1572 attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
1573 }
1574
1575 boolean specified = false;
1576 boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
1577
1578 if (firstCheck != -1) {
1579 boolean cdata = attType == fCDATASymbol;
1580 if (!cdata || required || attValue != -1) {
1581 int i = attrList.getFirstAttr(firstCheck);
1582 while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
1583
1584 if ( (fGrammarIsDTDGrammar && (attrList.getAttrName(i) == fTempAttDecl.name.rawname)) ||
1585 ( fStringPool.equalNames(attrList.getAttrLocalpart(i), attName)
1586 && fStringPool.equalNames(attrList.getAttrURI(i), fTempAttDecl.name.uri) ) ) {
1587
1588 if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
1589 int alistValue = attrList.getAttValue(i);
1590 if (alistValue != attValue &&
1591 !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
1592 Object[] args = { fStringPool.toString(elementNameIndex),
1593 fStringPool.toString(attName),
1594 fStringPool.toString(alistValue),
1595 fStringPool.toString(attValue)};
1596 fErrorReporter.reportError(fErrorReporter.getLocator(),
1597 XMLMessages.XML_DOMAIN,
1598 XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
1599 XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
1600 args,
1601 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1602 }
1603 }
1604 specified = true;
1605 break;
1606 }
1607 i = attrList.getNextAttr(i);
1608 }
1609 }
1610 }
1611
1612 if (!specified) {
1613 if (required) {
1614 if (validationEnabled) {
1615 Object[] args = { fStringPool.toString(elementNameIndex),
1616 fStringPool.toString(attName)};
1617 fErrorReporter.reportError(fErrorReporter.getLocator(),
1618 XMLMessages.XML_DOMAIN,
1619 XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
1620 XMLMessages.VC_REQUIRED_ATTRIBUTE,
1621 args,
1622 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1623 }
1624 } else if (attValue != -1) {
1625 if (validationEnabled && standalone )
1626 if ( fGrammarIsDTDGrammar
1627 && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
1628
1629 Object[] args = { fStringPool.toString(elementNameIndex),
1630 fStringPool.toString(attName)};
1631 fErrorReporter.reportError(fErrorReporter.getLocator(),
1632 XMLMessages.XML_DOMAIN,
1633 XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
1634 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
1635 args,
1636 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1637 }
1638 if (attType == fIDREFSymbol) {
1639 this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
1640 } else if (attType == fIDREFSSymbol) {
1641 this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
1642 }
1643 if (attrIndex == -1) {
1644 attrIndex = attrList.startAttrList();
1645 }
1646 // REVISIT: Validation. What should the prefix be?
1647 fTempQName.setValues(attPrefix, attName, attName, fTempAttDecl.name.uri);
1648 int newAttr = attrList.addAttr(fTempQName,
1649 attValue, attType,
1650 false, false);
1651 if (lastCheck == -1) {
1652 lastCheck = newAttr;
1653 }
1654 }
1655 }
1656 attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
1657 }
1658 return attrIndex;
1659
1660 } // addDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
1661
1662 /** addDTDDefaultAttributes. */
1663 private int addDTDDefaultAttributes(QName element, XMLAttrList attrList, int attrIndex, boolean validationEnabled, boolean standalone) throws Exception {
1664
1665
1666 //
1667 // Check after all specified attrs are scanned
1668 // (1) report error for REQUIRED attrs that are missing (V_TAGc)
1669 // (2) check that FIXED attrs have matching value (V_TAGd)
1670 // (3) add default attrs (FIXED and NOT_FIXED)
1671 //
1672
1673 int elementIndex = fGrammar.getElementDeclIndex(element, -1);
1674
1675 if (elementIndex == -1) {
1676 return attrIndex;
1677 }
1678
1679 fGrammar.getElementDecl(elementIndex,fTempElementDecl);
1680
1681
1682 int elementNameIndex = fTempElementDecl.name.rawname;
1683 int attlistIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
1684 int firstCheck = attrIndex;
1685 int lastCheck = -1;
1686 while (attlistIndex != -1) {
1687
1688 fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
1689
1690 // TO DO: For ericye Debug only
1691 /***
1692 if (fTempAttDecl != null) {
1693 XMLElementDecl element = new XMLElementDecl();
1694 fGrammar.getElementDecl(elementIndex, element);
1695 System.out.println("element: "+fStringPool.toString(element.name.localpart));
1696 System.out.println("attlistIndex " + attlistIndex + "\n"+
1697 "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
1698 + "attType : "+fTempAttDecl.type + "\n"
1699 + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
1700 + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
1701 + attrList.getLength() +"\n"
1702 );
1703 }
1704 /***/
1705
1706 int attPrefix = fTempAttDecl.name.prefix;
1707 int attName = fTempAttDecl.name.rawname;
1708 int attLocalpart = fTempAttDecl.name.localpart;
1709 int attType = attributeTypeName(fTempAttDecl);
1710 int attDefType =fTempAttDecl.defaultType;
1711 int attValue = -1 ;
1712 if (fTempAttDecl.defaultValue != null ) {
1713 attValue = fStringPool.addSymbol(fTempAttDecl.defaultValue);
1714 }
1715 boolean specified = false;
1716 boolean required = attDefType == XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
1717
1718
1719 /****
1720 if (fValidating && fGrammar != null && fGrammarIsDTDGrammar && attValue != -1) {
1721 normalizeAttValue(null, fTempAttDecl.name,
1722 attValue,attType,fTempAttDecl.list,
1723 fTempAttDecl.enumeration);
1724 }
1725 /****/
1726
1727 if (firstCheck != -1) {
1728 boolean cdata = attType == fCDATASymbol;
1729 if (!cdata || required || attValue != -1) {
1730 int i = attrList.getFirstAttr(firstCheck);
1731 while (i != -1 && (lastCheck == -1 || i <= lastCheck)) {
1732
1733 if ( attrList.getAttrName(i) == fTempAttDecl.name.rawname ) {
1734
1735 if (validationEnabled && attDefType == XMLAttributeDecl.DEFAULT_TYPE_FIXED) {
1736 int alistValue = attrList.getAttValue(i);
1737 if (alistValue != attValue &&
1738 !fStringPool.toString(alistValue).equals(fStringPool.toString(attValue))) {
1739 Object[] args = { fStringPool.toString(elementNameIndex),
1740 fStringPool.toString(attName),
1741 fStringPool.toString(alistValue),
1742 fStringPool.toString(attValue)};
1743 fErrorReporter.reportError(fErrorReporter.getLocator(),
1744 XMLMessages.XML_DOMAIN,
1745 XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
1746 XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
1747 args,
1748 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1749 }
1750 }
1751 specified = true;
1752 break;
1753 }
1754 i = attrList.getNextAttr(i);
1755 }
1756 }
1757 }
1758
1759 if (!specified) {
1760 if (required) {
1761 if (validationEnabled) {
1762 Object[] args = { fStringPool.toString(elementNameIndex),
1763 fStringPool.toString(attName)};
1764 fErrorReporter.reportError(fErrorReporter.getLocator(),
1765 XMLMessages.XML_DOMAIN,
1766 XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
1767 XMLMessages.VC_REQUIRED_ATTRIBUTE,
1768 args,
1769 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1770 }
1771 } else if (attValue != -1) {
1772 if (validationEnabled && standalone )
1773 if ( fGrammarIsDTDGrammar
1774 && ((DTDGrammar) fGrammar).getAttributeDeclIsExternal(attlistIndex) ) {
1775
1776 Object[] args = { fStringPool.toString(elementNameIndex),
1777 fStringPool.toString(attName)};
1778 fErrorReporter.reportError(fErrorReporter.getLocator(),
1779 XMLMessages.XML_DOMAIN,
1780 XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
1781 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
1782 args,
1783 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1784 }
1785 if (attType == fIDREFSymbol) {
1786 this.fValIDRef.validate( fStringPool.toString(attValue), this.fStoreIDRef );
1787 } else if (attType == fIDREFSSymbol) {
1788 this.fValIDRefs.validate( fStringPool.toString(attValue), this.fStoreIDRef );
1789 }
1790 if (attrIndex == -1) {
1791 attrIndex = attrList.startAttrList();
1792 }
1793
1794 fTempQName.setValues(attPrefix, attLocalpart, attName, fTempAttDecl.name.uri);
1795 int newAttr = attrList.addAttr(fTempQName,
1796 attValue, attType,
1797 false, false);
1798 if (lastCheck == -1) {
1799 lastCheck = newAttr;
1800 }
1801 }
1802 }
1803 attlistIndex = fGrammar.getNextAttributeDeclIndex(attlistIndex);
1804 }
1805 return attrIndex;
1806
1807 } // addDTDDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
1808
1809 // content models
1810
1811 /** Queries the content model for the specified element index. */
1812 private XMLContentModel getElementContentModel(int elementIndex) throws CMException {
1813 XMLContentModel contentModel = null;
1814 if ( elementIndex > -1) {
1815 if ( fGrammar.getElementDecl(elementIndex,fTempElementDecl) ) {
1816 contentModel = fGrammar.getElementContentModel(elementIndex);
1817 }
1818 }
1819 //return fGrammar.getElementContentModel(elementIndex);
1820 return contentModel;
1821 }
1822
1823
1824
1825 // query attribute information
1826
1827 /** Returns an attribute definition for an element type. */
1828 // this is only used by DTD validation.
1829 private int getAttDef(QName element, QName attribute) {
1830 if (fGrammar != null) {
1831 int scope = fCurrentScope;
1832 if (element.uri > -1) {
1833 scope = TOP_LEVEL_SCOPE;
1834 }
1835 int elementIndex = fGrammar.getElementDeclIndex(element,scope);
1836 if (elementIndex == -1) {
1837 return -1;
1838 }
1839 int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
1840 while (attDefIndex != -1) {
1841 fGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
1842 if (fTempAttributeDecl.name.localpart == attribute.localpart &&
1843 fTempAttributeDecl.name.uri == attribute.uri ) {
1844 return attDefIndex;
1845 }
1846 attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
1847 }
1848 }
1849 return -1;
1850
1851 } // getAttDef(QName,QName)
1852
1853 /** Returns an attribute definition for an element type. */
1854 private int getAttDefByElementIndex(int elementIndex, QName attribute) {
1855 if (fGrammar != null && elementIndex > -1) {
1856 if (elementIndex == -1) {
1857 return -1;
1858 }
1859 int attDefIndex = fGrammar.getFirstAttributeDeclIndex(elementIndex);
1860 while (attDefIndex != -1) {
1861 fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);
1862
1863 if (fGrammarIsDTDGrammar) {
1864 if (fTempAttDecl.name.rawname == attribute.rawname )
1865 return attDefIndex;
1866 } else
1867 if (fTempAttDecl.name.localpart == attribute.localpart &&
1868 fTempAttDecl.name.uri == attribute.uri ) {
1869 return attDefIndex;
1870 }
1871
1872 if (fGrammarIsSchemaGrammar) {
1873 if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY) {
1874 return attDefIndex;
1875 } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL) {
1876 if (attribute.uri == -1) {
1877 return attDefIndex;
1878 }
1879 } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
1880 if (attribute.uri != fTempAttDecl.name.uri) {
1881 return attDefIndex;
1882 }
1883 } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST) {
1884 if (fStringPool.stringInList(fTempAttDecl.enumeration, attribute.uri)) {
1885 return attDefIndex;
1886 }
1887 }
1888 }
1889
1890 attDefIndex = fGrammar.getNextAttributeDeclIndex(attDefIndex);
1891 }
1892 }
1893 return -1;
1894
1895 } // getAttDef(QName,QName)
1896
1897 // validation
1898
1899 /** Root element specified. */
1900 private void rootElementSpecified(QName rootElement) throws Exception {
1901
1902 // this is what it used to be
1903 //if (fDynamicValidation && !fSeenDoctypeDecl) {
1904 //fValidating = false;
1905 //}
1906
1907
1908 if ( fLoadDTDGrammar )
1909 // initialize the grammar to be the default one,
1910 // it definitely should be a DTD Grammar at this case;
1911 if (fGrammar == null) {
1912
1913 fGrammar = fGrammarResolver.getGrammar("");
1914
1915 //TO DO, for ericye debug only
1916 if (fGrammar == null && DEBUG_SCHEMA_VALIDATION) {
1917 System.out.println("Oops! no grammar is found for validation");
1918 }
1919
1920 if (fDynamicValidation && fGrammar==null) {
1921 fValidating = false;
1922 }
1923
1924 if (fGrammar != null) {
1925 if (fGrammar instanceof DTDGrammar) {
1926 fGrammarIsDTDGrammar = true;
1927 fGrammarIsSchemaGrammar = false;
1928 } else if ( fGrammar instanceof SchemaGrammar ) {
1929 fGrammarIsSchemaGrammar = true;
1930 fGrammarIsDTDGrammar = false;
1931 }
1932
1933 fGrammarNameSpaceIndex = fEmptyURI;
1934 }
1935 }
1936
1937 if (fValidating) {
1938 if ( fGrammarIsDTDGrammar &&
1939 ((DTDGrammar) fGrammar).getRootElementQName(fRootElement) ) {
1940
1941 String root1 = fStringPool.toString(fRootElement.rawname);
1942 String root2 = fStringPool.toString(rootElement.rawname);
1943 if (!root1.equals(root2)) {
1944 reportRecoverableXMLError(XMLMessages.MSG_ROOT_ELEMENT_TYPE,
1945 XMLMessages.VC_ROOT_ELEMENT_TYPE,
1946 fRootElement.rawname,
1947 rootElement.rawname);
1948 }
1949 }
1950 }
1951
1952 if (fNamespacesEnabled) {
1953 if (fNamespacesScope == null) {
1954 fNamespacesScope = new NamespacesScope(this);
1955 fNamespacesPrefix = fStringPool.addSymbol("xmlns");
1956 fNamespacesScope.setNamespaceForPrefix(fNamespacesPrefix, -1);
1957 int xmlSymbol = fStringPool.addSymbol("xml");
1958 int xmlNamespace = fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace");
1959 fNamespacesScope.setNamespaceForPrefix(xmlSymbol, xmlNamespace);
1960 }
1961 }
1962
1963 } // rootElementSpecified(QName)
1964
1965 /** Switchs to correct validating symbol tables when Schema changes.*/
1966
1967 private boolean switchGrammar(int newGrammarNameSpaceIndex) throws Exception {
1968 Grammar tempGrammar = fGrammarResolver.getGrammar(fStringPool.toString(newGrammarNameSpaceIndex));
1969 if (tempGrammar == null) {
1970 // This is a case where namespaces is on with a DTD grammar.
1971 tempGrammar = fGrammarResolver.getGrammar("");
1972 }
1973 if (tempGrammar == null) {
1974 return false;
1975 } else {
1976 fGrammar = tempGrammar;
1977 if (fGrammar instanceof DTDGrammar) {
1978 fGrammarIsDTDGrammar = true;
1979 fGrammarIsSchemaGrammar = false;
1980 } else if ( fGrammar instanceof SchemaGrammar ) {
1981 fGrammarIsSchemaGrammar = true;
1982 fGrammarIsDTDGrammar = false;
1983 }
1984
1985 return true;
1986 }
1987 }
1988
1989 /** Binds namespaces to the element and attributes. */
1990 private void bindNamespacesToElementAndAttributes(QName element,
1991 XMLAttrList attrList)
1992 throws Exception {
1993
1994 fNamespacesScope.increaseDepth();
1995
1996 //Vector schemaCandidateURIs = null;
1997 Hashtable locationUriPairs = null;
1998
1999 if (fAttrListHandle != -1) {
2000 int index = attrList.getFirstAttr(fAttrListHandle);
2001 while (index != -1) {
2002 int attName = attrList.getAttrName(index);
2003 int attPrefix = attrList.getAttrPrefix(index);
2004 if (fStringPool.equalNames(attName, fXMLLang)) {
2005 /***
2006 // NOTE: This check is done in the validateElementsAndAttributes
2007 // method.
2008 fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
2009 /***/
2010 } else if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
2011 int uri = fStringPool.addSymbol(attrList.getAttValue(index));
2012 fNamespacesScope.setNamespaceForPrefix(StringPool.EMPTY_STRING, uri);
2013 } else {
2014 if (attPrefix == fNamespacesPrefix) {
2015 int nsPrefix = attrList.getAttrLocalpart(index);
2016 int uri = fStringPool.addSymbol(attrList.getAttValue(index));
2017 fNamespacesScope.setNamespaceForPrefix(nsPrefix, uri);
2018
2019 if (fValidating && fSchemaValidation) {
2020 boolean seeXsi = false;
2021 String attrValue = fStringPool.toString(attrList.getAttValue(index));
2022
2023 if (attrValue.equals(SchemaSymbols.URI_XSI)) {
2024 fXsiPrefix = nsPrefix;
2025 seeXsi = true;
2026 }
2027
2028 if (!seeXsi) {
2029 /***
2030 if (schemaCandidateURIs == null) {
2031 schemaCandidateURIs = new Vector();
2032 }
2033 schemaCandidateURIs.addElement( fStringPool.toString(uri) );
2034 /***/
2035 }
2036 }
2037 }
2038 }
2039 index = attrList.getNextAttr(index);
2040 }
2041 // if validating, walk through the list again to deal with "xsi:...."
2042 if (fValidating && fSchemaValidation) {
2043 fXsiTypeAttValue = -1;
2044 index = attrList.getFirstAttr(fAttrListHandle);
2045 while (index != -1) {
2046
2047 int attName = attrList.getAttrName(index);
2048 int attPrefix = attrList.getAttrPrefix(index);
2049
2050 if (fStringPool.equalNames(attName, fNamespacesPrefix)) {
2051 // REVISIT
2052 } else {
2053 if ( DEBUG_SCHEMA_VALIDATION ) {
2054 System.out.println("deal with XSI");
2055 System.out.println("before find XSI: "+fStringPool.toString(attPrefix)
2056 +","+fStringPool.toString(fXsiPrefix) );
2057 }
2058 if ( fXsiPrefix != -1 && attPrefix == fXsiPrefix ) {
2059
2060 if (DEBUG_SCHEMA_VALIDATION) {
2061 System.out.println("find XSI: "+fStringPool.toString(attPrefix)
2062 +","+fStringPool.toString(attName) );
2063 }
2064
2065
2066 int localpart = attrList.getAttrLocalpart(index);
2067 if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_SCHEMALOCACTION)) {
2068 if (locationUriPairs == null) {
2069 locationUriPairs = new Hashtable();
2070 }
2071 parseSchemaLocation(fStringPool.toString(attrList.getAttValue(index)), locationUriPairs);
2072 } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_NONAMESPACESCHEMALOCACTION)) {
2073 if (locationUriPairs == null) {
2074 locationUriPairs = new Hashtable();
2075 }
2076 locationUriPairs.put(fStringPool.toString(attrList.getAttValue(index)), "");
2077 if (fNamespacesScope != null) {
2078 //bind prefix "" to URI "" in this case
2079 fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(""),
2080 fStringPool.addSymbol(""));
2081 }
2082 } else if (localpart == fStringPool.addSymbol(SchemaSymbols.XSI_TYPE)) {
2083 fXsiTypeAttValue = attrList.getAttValue(index);
2084 }
2085 // REVISIT: should we break here?
2086 //break;
2087 }
2088 }
2089 index = attrList.getNextAttr(index);
2090 }
2091
2092 // try to resolve all the grammars here
2093 if (locationUriPairs != null) {
2094 Enumeration locations = locationUriPairs.keys();
2095
2096 while (locations.hasMoreElements()) {
2097 String loc = (String) locations.nextElement();
2098 String uri = (String) locationUriPairs.get(loc);
2099 resolveSchemaGrammar( loc, uri);
2100 //schemaCandidateURIs.removeElement(uri);
2101 }
2102 }
2103
2104 //TO DO: This should be a feature that can be turned on or off
2105 /*****
2106 for (int i=0; i< schemaCandidateURIs.size(); i++) {
2107
2108 String uri = (String) schemaCandidateURIs.elementAt(i);
2109 resolveSchemaGrammar(uri);
2110 }
2111 /*****/
2112
2113 }
2114
2115 }
2116
2117 // bind element to URI
2118 int prefix = element.prefix != -1 ? element.prefix : 0;
2119 int uri = fNamespacesScope.getNamespaceForPrefix(prefix);
2120 if (element.prefix != -1 || uri != -1) {
2121 element.uri = uri;
2122 if (element.uri == -1) {
2123 Object[] args = { fStringPool.toString(element.prefix)};
2124 fErrorReporter.reportError(fErrorReporter.getLocator(),
2125 XMLMessages.XMLNS_DOMAIN,
2126 XMLMessages.MSG_PREFIX_DECLARED,
2127 XMLMessages.NC_PREFIX_DECLARED,
2128 args,
2129 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2130 }
2131 }
2132
2133
2134 if (fAttrListHandle != -1) {
2135 int index = attrList.getFirstAttr(fAttrListHandle);
2136 while (index != -1) {
2137 int attName = attrList.getAttrName(index);
2138 if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
2139 int attPrefix = attrList.getAttrPrefix(index);
2140 if (attPrefix != fNamespacesPrefix) {
2141 if (attPrefix != -1 ) {
2142 int attrUri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
2143 if (attrUri == -1) {
2144 Object[] args = { fStringPool.toString(attPrefix)};
2145 fErrorReporter.reportError(fErrorReporter.getLocator(),
2146 XMLMessages.XMLNS_DOMAIN,
2147 XMLMessages.MSG_PREFIX_DECLARED,
2148 XMLMessages.NC_PREFIX_DECLARED,
2149 args,
2150 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2151 }
2152 attrList.setAttrURI(index, attrUri);
2153 }
2154 }
2155 }
2156 index = attrList.getNextAttr(index);
2157 }
2158 }
2159
2160 } // bindNamespacesToElementAndAttributes(QName,XMLAttrList)
2161
2162 void parseSchemaLocation(String schemaLocationStr, Hashtable locationUriPairs){
2163 if (locationUriPairs != null) {
2164 StringTokenizer tokenizer = new StringTokenizer(schemaLocationStr, " \n\t\r", false);
2165 int tokenTotal = tokenizer.countTokens();
2166 if (tokenTotal % 2 != 0 ) {
2167 // TO DO: report warning - malformed schemaLocation string
2168 } else {
2169 while (tokenizer.hasMoreTokens()) {
2170 String uri = tokenizer.nextToken();
2171 String location = tokenizer.nextToken();
2172
2173 locationUriPairs.put(location, uri);
2174 }
2175 }
2176 } else {
2177 // TO DO: should report internal error here
2178 }
2179
2180 }// parseSchemaLocaltion(String, Hashtable)
2181 private void resolveSchemaGrammar( String loc, String uri) throws Exception {
2182
2183 SchemaGrammar grammar = (SchemaGrammar) fGrammarResolver.getGrammar(uri);
2184
2185 if (grammar == null) {
2186 DOMParser parser = new DOMParser();
2187 parser.setEntityResolver( new Resolver(fEntityHandler) );
2188 parser.setErrorHandler( new ErrorHandler() );
2189
2190 try {
2191 parser.setFeature("http://xml.org/sax/features/validation", false);
2192 parser.setFeature("http://xml.org/sax/features/namespaces", true);
2193 parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
2194 } catch ( org.xml.sax.SAXNotRecognizedException e ) {
2195 e.printStackTrace();
2196 } catch ( org.xml.sax.SAXNotSupportedException e ) {
2197 e.printStackTrace();
2198 }
2199
2200 // expand it before passing it to the parser
2201 InputSource source = null;
2202 EntityResolver currentER = parser.getEntityResolver();
2203 if (currentER != null) {
2204 source = currentER.resolveEntity("", loc);
2205 }
2206 if (source == null) {
2207 loc = fEntityHandler.expandSystemId(loc);
2208 source = new InputSource(loc);
2209 }
2210 try {
2211 parser.parse( source );
2212 } catch ( IOException e ) {
2213 e.printStackTrace();
2214 } catch ( SAXException e ) {
2215 //System.out.println("loc = "+loc);
2216 //e.printStackTrace();
2217 reportRecoverableXMLError( XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
2218 XMLMessages.SCHEMA_GENERIC_ERROR, e.getMessage() );
2219 }
2220
2221 Document document = parser.getDocument(); //Our Grammar
2222
2223 TraverseSchema tst = null;
2224 try {
2225 if (DEBUG_SCHEMA_VALIDATION) {
2226 System.out.println("I am geting the Schema Document");
2227 }
2228
2229 Element root = document.getDocumentElement();// This is what we pass to TraverserSchema
2230 if (root == null) {
2231 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Can't get back Schema document's root element :" + loc);
2232 } else {
2233 if (uri == null || !uri.equals(root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE)) ) {
2234 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Schema in " + loc + " has a different target namespace " +
2235 "from the one specified in the instance document :" + uri);
2236 }
2237 grammar = new SchemaGrammar();
2238 grammar.setGrammarDocument(document);
2239 tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId());
2240 fGrammarResolver.putGrammar(document.getDocumentElement().getAttribute("targetNamespace"), grammar);
2241 }
2242 } catch (Exception e) {
2243 e.printStackTrace(System.err);
2244 }
2245 }
2246
2247 }
2248
2249 private void resolveSchemaGrammar(String uri) throws Exception{
2250
2251 resolveSchemaGrammar(uri, uri);
2252
2253 }
2254
2255 static class Resolver implements EntityResolver {
2256
2257 //
2258 // Constants
2259 //
2260
2261 private static final String SYSTEM[] = {
2262 "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
2263 "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
2264 "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent",
2265 };
2266 private static final String PATH[] = {
2267 "/org/apache/xerces/validators/schema/structures.dtd",
2268 "/org/apache/xerces/validators/schema/datatypes.dtd",
2269 "/org/apache/xerces/validators/schema/versionInfo.ent",
2270 };
2271
2272 //
2273 // Data
2274 //
2275
2276 private DefaultEntityHandler fEntityHandler;
2277
2278 //
2279 // Constructors
2280 //
2281
2282 public Resolver(DefaultEntityHandler handler) {
2283 fEntityHandler = handler;
2284 }
2285
2286 //
2287 // EntityResolver methods
2288 //
2289
2290 public InputSource resolveEntity(String publicId, String systemId)
2291 throws IOException, SAXException {
2292 // looking for the schema DTDs?
2293 for (int i = 0; i < SYSTEM.length; i++) {
2294 if (systemId.equals(SYSTEM[i])) {
2295 InputStream stream = getClass().getResourceAsStream(PATH[i]);
2296 if (stream != null) {
2297 InputSource source = new InputSource(stream);
2298 source.setPublicId(publicId);
2299 source.setSystemId(systemId);
2300 return source;
2301 }
2302 }
2303 }
2304
2305 // first try to resolve using user's entity resolver
2306 EntityResolver resolver = fEntityHandler.getEntityResolver();
2307 if (resolver != null) {
2308 InputSource source = resolver.resolveEntity(publicId, systemId);
2309 if (source != null) {
2310 return source;
2311 }
2312 }
2313
2314 // use default resolution
2315 return new InputSource(fEntityHandler.expandSystemId(systemId));
2316
2317 } // resolveEntity(String,String):InputSource
2318
2319 } // class Resolver
2320
2321 static class ErrorHandler implements org.xml.sax.ErrorHandler {
2322
2323 /** Warning. */
2324 public void warning(SAXParseException ex) {
2325 System.err.println("[Warning] "+
2326 getLocationString(ex)+": "+
2327 ex.getMessage());
2328 }
2329
2330 /** Error. */
2331 public void error(SAXParseException ex) {
2332 System.err.println("[Error] "+
2333 getLocationString(ex)+": "+
2334 ex.getMessage());
2335 }
2336
2337 /** Fatal error. */
2338 public void fatalError(SAXParseException ex) {
2339 System.err.println("[Fatal Error] "+
2340 getLocationString(ex)+": "+
2341 ex.getMessage());
2342 //throw ex;
2343 }
2344
2345 //
2346 // Private methods
2347 //
2348
2349 /** Returns a string of the location. */
2350 private String getLocationString(SAXParseException ex) {
2351 StringBuffer str = new StringBuffer();
2352
2353 String systemId_ = ex.getSystemId();
2354 if (systemId_ != null) {
2355 int index = systemId_.lastIndexOf('/');
2356 if (index != -1)
2357 systemId_ = systemId_.substring(index + 1);
2358 str.append(systemId_);
2359 }
2360 str.append(':');
2361 str.append(ex.getLineNumber());
2362 str.append(':');
2363 str.append(ex.getColumnNumber());
2364
2365 return str.toString();
2366
2367 } // getLocationString(SAXParseException):String
2368 }
2369
2370 private int attributeTypeName(XMLAttributeDecl attrDecl) {
2371 switch (attrDecl.type) {
2372 case XMLAttributeDecl.TYPE_ENTITY: {
2373 return attrDecl.list ? fENTITIESSymbol : fENTITYSymbol;
2374 }
2375 case XMLAttributeDecl.TYPE_ENUMERATION: {
2376 String enumeration = fStringPool.stringListAsString(attrDecl.enumeration);
2377 return fStringPool.addString(enumeration);
2378 }
2379 case XMLAttributeDecl.TYPE_ID: {
2380 return fIDSymbol;
2381 }
2382 case XMLAttributeDecl.TYPE_IDREF: {
2383 return attrDecl.list ? fIDREFSSymbol : fIDREFSymbol;
2384 }
2385 case XMLAttributeDecl.TYPE_NMTOKEN: {
2386 return attrDecl.list ? fNMTOKENSSymbol : fNMTOKENSSymbol;
2387 }
2388 case XMLAttributeDecl.TYPE_NOTATION: {
2389 return fNOTATIONSymbol;
2390 }
2391 }
2392 return fCDATASymbol;
2393 }
2394
2395 /** Validates element and attributes. */
2396 private void validateElementAndAttributes(QName element,
2397 XMLAttrList attrList)
2398 throws Exception {
2399
2400 if ((fElementDepth >= 0 && fValidationFlagStack[fElementDepth] != 0 )||
2401 (fGrammar == null && !fValidating && !fNamespacesEnabled) ) {
2402 fCurrentElementIndex = -1;
2403 fCurrentContentSpecType = -1;
2404 fInElementContent = false;
2405 if (fAttrListHandle != -1) {
2406 fAttrList.endAttrList();
2407 int index = fAttrList.getFirstAttr(fAttrListHandle);
2408 while (index != -1) {
2409 if (fStringPool.equalNames(fAttrList.getAttrName(index), fXMLLang)) {
2410 fDocumentScanner.checkXMLLangAttributeValue(fAttrList.getAttValue(index));
2411 break;
2412 }
2413 index = fAttrList.getNextAttr(index);
2414 }
2415 }
2416 return;
2417 }
2418
2419 int elementIndex = -1;
2420 int contentSpecType = -1;
2421
2422 boolean skipThisOne = false;
2423 boolean laxThisOne = false;
2424
2425 if ( fGrammarIsSchemaGrammar && fContentLeafStack[fElementDepth] != null ) {
2426 ContentLeafNameTypeVector cv = fContentLeafStack[fElementDepth];
2427
2428 QName[] fElemMap = cv.leafNames;
2429 for (int i=0; i<cv.leafCount; i++) {
2430 int type = cv.leafTypes[i] ;
2431 //System.out.println("******* see a ANY_OTHER_SKIP, "+type+","+element+","+fElemMap[i]+"\n*******");
2432
2433 if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
2434 if (fElemMap[i].uri==element.uri
2435 && fElemMap[i].localpart == element.localpart)
2436 break;
2437 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
2438 int uri = fElemMap[i].uri;
2439 if (uri == -1 || uri == element.uri) {
2440 break;
2441 }
2442 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
2443 if (element.uri == -1) {
2444 break;
2445 }
2446 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
2447 if (fElemMap[i].uri != element.uri) {
2448 break;
2449 }
2450 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_SKIP) {
2451 int uri = fElemMap[i].uri;
2452 if (uri == -1 || uri == element.uri) {
2453 skipThisOne = true;
2454 break;
2455 }
2456 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_SKIP) {
2457 if (element.uri == -1) {
2458 skipThisOne = true;
2459 break;
2460 }
2461 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP) {
2462 if (fElemMap[i].uri != element.uri) {
2463 skipThisOne = true;
2464 break;
2465 }
2466 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LAX) {
2467 int uri = fElemMap[i].uri;
2468 if (uri == -1 || uri == element.uri) {
2469 laxThisOne = true;
2470 break;
2471 }
2472 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL_LAX) {
2473 if (element.uri == -1) {
2474 laxThisOne = true;
2475 break;
2476 }
2477 } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX) {
2478 if (fElemMap[i].uri != element.uri) {
2479 laxThisOne = true;
2480 break;
2481 }
2482 }
2483
2484 }
2485
2486 }
2487
2488 if (skipThisOne) {
2489 fNeedValidationOff = true;
2490 } else {
2491
2492 //REVISIT: is this the right place to check on if the Schema has changed?
2493
2494 if ( fNamespacesEnabled && fValidating && element.uri != fGrammarNameSpaceIndex && element.uri != -1 ) {
2495 fGrammarNameSpaceIndex = element.uri;
2496
2497 boolean success = switchGrammar(fGrammarNameSpaceIndex);
2498
2499 if (!success && !laxThisOne) {
2500 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR,
2501 "Grammar with uri : " + fStringPool.toString(fGrammarNameSpaceIndex)
2502 + " , can not found");
2503 }
2504 }
2505
2506
2507 if ( fGrammar != null ) {
2508 if (DEBUG_SCHEMA_VALIDATION) {
2509 System.out.println("*******Lookup element: uri: " + fStringPool.toString(element.uri)+
2510 "localpart: '" + fStringPool.toString(element.localpart)
2511 +"' and scope : " + fCurrentScope+"\n");
2512 }
2513
2514 elementIndex = fGrammar.getElementDeclIndex(element,fCurrentScope);
2515
2516 if (elementIndex == -1 ) {
2517 elementIndex = fGrammar.getElementDeclIndex(element, TOP_LEVEL_SCOPE);
2518 }
2519
2520 if (elementIndex == -1) {
2521 // if validating based on a Schema, try to resolve the element again by look it up in its ancestor types
2522 if (fGrammarIsSchemaGrammar && fCurrentElementIndex != -1) {
2523 TraverseSchema.ComplexTypeInfo baseTypeInfo = null;
2524 baseTypeInfo = ((SchemaGrammar)fGrammar).getElementComplexTypeInfo(fCurrentElementIndex);
2525 //TO DO:
2526 // should check if baseTypeInfo is from the same Schema.
2527 while (baseTypeInfo != null) {
2528 elementIndex = fGrammar.getElementDeclIndex(element, baseTypeInfo.scopeDefined);
2529 if (elementIndex > -1 ) {
2530 break;
2531 }
2532 baseTypeInfo = baseTypeInfo.baseComplexTypeInfo;
2533 }
2534 }
2535 //if still can't resolve it, try TOP_LEVEL_SCOPE AGAIN
2536 /****
2537 if ( element.uri == -1 && elementIndex == -1
2538 && fNamespacesScope != null
2539 && fNamespacesScope.getNamespaceForPrefix(StringPool.EMPTY_STRING) != -1 ) {
2540 elementIndex = fGrammar.getElementDeclIndex(element.localpart, TOP_LEVEL_SCOPE);
2541 // REVISIT:
2542 // this is a hack to handle the situation where namespace prefix "" is bound to nothing, and there
2543 // is a "noNamespaceSchemaLocation" specified, and element
2544 element.uri = StringPool.EMPTY_STRING;
2545 }
2546 /****/
2547
2548 /****/
2549 if (elementIndex == -1) {
2550 if (laxThisOne) {
2551 fNeedValidationOff = true;
2552 } else
2553 if (DEBUG_SCHEMA_VALIDATION)
2554 System.out.println("!!! can not find elementDecl in the grammar, " +
2555 " the element localpart: " + element.localpart +
2556 "["+fStringPool.toString(element.localpart) +"]" +
2557 " the element uri: " + element.uri +
2558 "["+fStringPool.toString(element.uri) +"]" +
2559 " and the current enclosing scope: " + fCurrentScope );
2560 }
2561 /****/
2562 }
2563
2564 if (DEBUG_SCHEMA_VALIDATION) {
2565 fGrammar.getElementDecl(elementIndex, fTempElementDecl);
2566 System.out.println("elementIndex: " + elementIndex+" \n and itsName : '"
2567 + fStringPool.toString(fTempElementDecl.name.localpart)
2568 +"' \n its ContentType:" + fTempElementDecl.type
2569 +"\n its ContentSpecIndex : " + fTempElementDecl.contentSpecIndex +"\n"+
2570 " and the current enclosing scope: " + fCurrentScope);
2571 }
2572 }
2573
2574 contentSpecType = getContentSpecType(elementIndex);
2575
2576 if (fGrammarIsSchemaGrammar && elementIndex != -1) {
2577
2578 // handle "xsi:type" right here
2579 if (fXsiTypeAttValue > -1) {
2580 String xsiType = fStringPool.toString(fXsiTypeAttValue);
2581 int colonP = xsiType.indexOf(":");
2582 String prefix = "";
2583 String localpart = xsiType;
2584 if (colonP > -1) {
2585 prefix = xsiType.substring(0,colonP);
2586 localpart = xsiType.substring(colonP+1);
2587 }
2588
2589 String uri = "";
2590 int uriIndex = -1;
2591 if (fNamespacesScope != null) {
2592 uriIndex = fNamespacesScope.getNamespaceForPrefix(fStringPool.addSymbol(prefix));
2593 if (uriIndex > -1) {
2594 uri = fStringPool.toString(uriIndex);
2595 if (uriIndex != fGrammarNameSpaceIndex) {
2596 fGrammarNameSpaceIndex = fCurrentSchemaURI = uriIndex;
2597 boolean success = switchGrammar(fCurrentSchemaURI);
2598 if (!success && !fNeedValidationOff) {
2599 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
2600 XMLMessages.SCHEMA_GENERIC_ERROR,
2601 "Grammar with uri : "
2602 + fStringPool.toString(fCurrentSchemaURI)
2603 + " , can not found");
2604 }
2605 }
2606 }
2607 }
2608
2609
2610 Hashtable complexRegistry = ((SchemaGrammar)fGrammar).getComplexTypeRegistry();
2611 DatatypeValidatorFactoryImpl dataTypeReg = ((SchemaGrammar)fGrammar).getDatatypeRegistry();
2612 if (complexRegistry==null || dataTypeReg == null) {
2613 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
2614 XMLMessages.SCHEMA_GENERIC_ERROR,
2615 fErrorReporter.getLocator().getSystemId()
2616 +" line"+fErrorReporter.getLocator().getLineNumber()
2617 +", canot resolve xsi:type = " + xsiType+" ---2");
2618 } else {
2619 TraverseSchema.ComplexTypeInfo typeInfo =
2620 (TraverseSchema.ComplexTypeInfo) complexRegistry.get(uri+","+localpart);
2621 //TO DO:
2622 // here need to check if this substitution is legal based on the current active grammar,
2623 // this should be easy, cause we already saved final, block and base type information in
2624 // the SchemaGrammar.
2625
2626 if (typeInfo==null) {
2627 if (uri.length() == 0 || uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) ) {
2628 fXsiTypeValidator = dataTypeReg.getDatatypeValidator(localpart);
2629 } else
2630 fXsiTypeValidator = dataTypeReg.getDatatypeValidator(uri+","+localpart);
2631 if ( fXsiTypeValidator == null )
2632 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
2633 XMLMessages.SCHEMA_GENERIC_ERROR,
2634 "unresolved type : "+uri+","+localpart
2635 +" found in xsi:type handling");
2636 } else
2637 elementIndex = typeInfo.templateElementIndex;
2638 }
2639
2640 fXsiTypeAttValue = -1;
2641 }
2642
2643 //Change the current scope to be the one defined by this element.
2644 fCurrentScope = ((SchemaGrammar) fGrammar).getElementDefinedScope(elementIndex);
2645
2646 // here need to check if we need to switch Grammar by asking SchemaGrammar whether
2647 // this element actually is of a type in another Schema.
2648 String anotherSchemaURI = ((SchemaGrammar)fGrammar).getElementFromAnotherSchemaURI(elementIndex);
2649 if (anotherSchemaURI != null) {
2650 //before switch Grammar, set the elementIndex to be the template elementIndex of its type
2651 if (contentSpecType != -1
2652 && contentSpecType != XMLElementDecl.TYPE_SIMPLE
2653 && contentSpecType != XMLElementDecl.TYPE_EMPTY ) {
2654 TraverseSchema.ComplexTypeInfo typeInfo = ((SchemaGrammar) fGrammar).getElementComplexTypeInfo(elementIndex);
2655 if (typeInfo != null) {
2656 elementIndex = typeInfo.templateElementIndex;
2657 }
2658
2659 }
2660
2661 // now switch the grammar
2662 fGrammarNameSpaceIndex = fCurrentSchemaURI = fStringPool.addSymbol(anotherSchemaURI);
2663 boolean success = switchGrammar(fCurrentSchemaURI);
2664 if (!success && !fNeedValidationOff) {
2665 reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
2666 XMLMessages.SCHEMA_GENERIC_ERROR,
2667 "Grammar with uri : "
2668 + fStringPool.toString(fCurrentSchemaURI)
2669 + " , can not found");
2670 }
2671 }
2672
2673 }
2674
2675 if (contentSpecType == -1 && fValidating && !fNeedValidationOff ) {
2676 reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
2677 XMLMessages.VC_ELEMENT_VALID,
2678 element.rawname);
2679 }
2680 if (fGrammar != null && fGrammarIsSchemaGrammar && elementIndex != -1) {
2681 fAttrListHandle = addDefaultAttributes(elementIndex, attrList, fAttrListHandle, fValidating, fStandaloneReader != -1);
2682 }
2683 if (fAttrListHandle != -1) {
2684 fAttrList.endAttrList();
2685 }
2686
2687 if (DEBUG_PRINT_ATTRIBUTES) {
2688 String elementStr = fStringPool.toString(element.rawname);
2689 System.out.print("startElement: <" + elementStr);
2690 if (fAttrListHandle != -1) {
2691 int index = attrList.getFirstAttr(fAttrListHandle);
2692 while (index != -1) {
2693 System.out.print(" " + fStringPool.toString(attrList.getAttrName(index)) + "=\"" +
2694 fStringPool.toString(attrList.getAttValue(index)) + "\"");
2695 index = attrList.getNextAttr(index);
2696 }
2697 }
2698 System.out.println(">");
2699 }
2700 // REVISIT: Validation. Do we need to recheck for the xml:lang
2701 // attribute? It was already checked above -- perhaps
2702 // this is to check values that are defaulted in? If
2703 // so, this check could move to the attribute decl
2704 // callback so we can check the default value before
2705 // it is used.
2706 if (fAttrListHandle != -1 && !fNeedValidationOff ) {
2707 int index = fAttrList.getFirstAttr(fAttrListHandle);
2708 while (index != -1) {
2709 int attrNameIndex = attrList.getAttrName(index);
2710
2711 if (fStringPool.equalNames(attrNameIndex, fXMLLang)) {
2712 fDocumentScanner.checkXMLLangAttributeValue(attrList.getAttValue(index));
2713 // break;
2714 }
2715 // here, we validate every "user-defined" attributes
2716 int _xmlns = fStringPool.addSymbol("xmlns");
2717
2718 if (attrNameIndex != _xmlns && attrList.getAttrPrefix(index) != _xmlns)
2719 if (fGrammar != null) {
2720 fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
2721 fTempQName.setValues(attrList.getAttrPrefix(index),
2722 attrList.getAttrLocalpart(index),
2723 attrList.getAttrName(index),
2724 attrList.getAttrURI(index) );
2725 int attDefIndex = getAttDefByElementIndex(elementIndex, fTempQName);
2726
2727 if (fTempQName.uri != fXsiURI)
2728 if (attDefIndex == -1 ) {
2729 if (fValidating) {
2730 // REVISIT - cache the elem/attr tuple so that we only give
2731 // this error once for each unique occurrence
2732 Object[] args = { fStringPool.toString(element.rawname),
2733 fStringPool.toString(attrList.getAttrName(index))};
2734
2735 /*****/
2736 fErrorReporter.reportError(fAttrNameLocator,
2737 XMLMessages.XML_DOMAIN,
2738 XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
2739 XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
2740 args,
2741 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2742 /******/
2743 }
2744 } else {
2745
2746 fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);
2747
2748 int attributeType = attributeTypeName(fTempAttDecl);
2749 attrList.setAttType(index, attributeType);
2750
2751 if (fValidating) {
2752
2753 if (fGrammarIsDTDGrammar &&
2754 (fTempAttDecl.type == XMLAttributeDecl.TYPE_ENTITY ||
2755 fTempAttDecl.type == XMLAttributeDecl.TYPE_ENUMERATION ||
2756 fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ||
2757 fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ||
2758 fTempAttDecl.type == XMLAttributeDecl.TYPE_NMTOKEN ||
2759 fTempAttDecl.type == XMLAttributeDecl.TYPE_NOTATION)
2760 ) {
2761 validateDTDattribute(element, attrList.getAttValue(index), fTempAttDecl);
2762 }
2763
2764 // check to see if this attribute matched an attribute wildcard
2765 else if ( fGrammarIsSchemaGrammar &&
2766 (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY
2767 ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
2768 ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LOCAL
2769 ||fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) ) {
2770
2771 if (fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_SKIP) {
2772 // attribute should just be bypassed,
2773 } else if ( fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT
2774 || fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_LAX) {
2775
2776 boolean reportError = false;
2777 boolean processContentStrict =
2778 fTempAttDecl.defaultType == XMLAttributeDecl.PROCESSCONTENTS_STRICT;
2779
2780 if (fTempQName.uri == -1) {
2781 if (processContentStrict) {
2782 reportError = true;
2783 }
2784 } else {
2785 Grammar aGrammar =
2786 fGrammarResolver.getGrammar(fStringPool.toString(fTempQName.uri));
2787
2788 if (aGrammar == null || !(aGrammar instanceof SchemaGrammar) ) {
2789 if (processContentStrict) {
2790 reportError = true;
2791 }
2792 } else {
2793 SchemaGrammar sGrammar = (SchemaGrammar) aGrammar;
2794 Hashtable attRegistry = sGrammar.getAttirubteDeclRegistry();
2795 if (attRegistry == null) {
2796 if (processContentStrict) {
2797 reportError = true;
2798 }
2799 } else {
2800 XMLAttributeDecl attDecl = (XMLAttributeDecl) attRegistry.get(fStringPool.toString(fTempQName.localpart));
2801 if (attDecl == null) {
2802 if (processContentStrict) {
2803 reportError = true;
2804 }
2805 } else {
2806 DatatypeValidator attDV = attDecl.datatypeValidator;
2807 if (attDV == null) {
2808 if (processContentStrict) {
2809 reportError = true;
2810 }
2811 } else {
2812 try {
2813 String unTrimValue = fStringPool.toString(attrList.getAttValue(index));
2814 String value = unTrimValue.trim();
2815 if (attDecl.type == XMLAttributeDecl.TYPE_ID ) {
2816 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
2817 }
2818 if (attDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
2819 attDV.validate(value, this.fStoreIDRef );
2820 } else
2821 attDV.validate(unTrimValue, null );
2822 } catch (InvalidDatatypeValueException idve) {
2823 fErrorReporter.reportError(fErrorReporter.getLocator(),
2824 SchemaMessageProvider.SCHEMA_DOMAIN,
2825 SchemaMessageProvider.DatatypeError,
2826 SchemaMessageProvider.MSG_NONE,
2827 new Object [] { idve.getMessage()},
2828 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2829 }
2830 }
2831 }
2832 }
2833 }
2834 }
2835 if (reportError) {
2836 Object[] args = { fStringPool.toString(element.rawname),
2837 "ANY---"+fStringPool.toString(attrList.getAttrName(index))};
2838
2839 fErrorReporter.reportError(fAttrNameLocator,
2840 XMLMessages.XML_DOMAIN,
2841 XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
2842 XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
2843 args,
2844 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2845
2846 }
2847 }
2848 } else if (fTempAttDecl.datatypeValidator == null) {
2849 Object[] args = { fStringPool.toString(element.rawname),
2850 fStringPool.toString(attrList.getAttrName(index))};
2851
2852 System.out.println("[Error] Datatypevalidator for attribute " + fStringPool.toString(attrList.getAttrName(index))
2853 + " not found in element type " + fStringPool.toString(element.rawname));
2854 //REVISIT : is this the right message?
2855 /****/
2856 fErrorReporter.reportError(fAttrNameLocator,
2857 XMLMessages.XML_DOMAIN,
2858 XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
2859 XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
2860 args,
2861 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2862 /****/
2863 } else {
2864 try {
2865 String unTrimValue = fStringPool.toString(attrList.getAttValue(index));
2866 String value = unTrimValue.trim();
2867 if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ID ) {
2868 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
2869 } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_IDREF ) {
2870 fTempAttDecl.datatypeValidator.validate(value, this.fStoreIDRef );
2871 } else {
2872 fTempAttDecl.datatypeValidator.validate(unTrimValue, null );
2873 }
2874
2875 } catch (InvalidDatatypeValueException idve) {
2876 fErrorReporter.reportError(fErrorReporter.getLocator(),
2877 SchemaMessageProvider.SCHEMA_DOMAIN,
2878 SchemaMessageProvider.DatatypeError,
2879 SchemaMessageProvider.MSG_NONE,
2880 new Object [] { idve.getMessage()},
2881 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2882 }
2883 }
2884 } // end of if (fValidating)
2885
2886
2887 } // end of if (attDefIndex == -1) else
2888
2889 }// end of if (fGrammar != null)
2890 index = fAttrList.getNextAttr(index);
2891 }
2892 }
2893 }
2894 if (fAttrListHandle != -1) {
2895 int index = attrList.getFirstAttr(fAttrListHandle);
2896 while (index != -1) {
2897 int attName = attrList.getAttrName(index);
2898 if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
2899 int attPrefix = attrList.getAttrPrefix(index);
2900 if (attPrefix != fNamespacesPrefix) {
2901 if (attPrefix != -1) {
2902 int uri = fNamespacesScope.getNamespaceForPrefix(attPrefix);
2903 if (uri == -1) {
2904 Object[] args = { fStringPool.toString(attPrefix)};
2905 fErrorReporter.reportError(fErrorReporter.getLocator(),
2906 XMLMessages.XMLNS_DOMAIN,
2907 XMLMessages.MSG_PREFIX_DECLARED,
2908 XMLMessages.NC_PREFIX_DECLARED,
2909 args,
2910 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2911 }
2912 attrList.setAttrURI(index, uri);
2913 }
2914 }
2915 }
2916 index = attrList.getNextAttr(index);
2917 }
2918 }
2919
2920 fCurrentElementIndex = elementIndex;
2921 fCurrentContentSpecType = contentSpecType;
2922
2923 if (fValidating && contentSpecType == XMLElementDecl.TYPE_SIMPLE) {
2924 fBufferDatatype = true;
2925 fDatatypeBuffer.setLength(0);
2926 }
2927
2928 fInElementContent = (contentSpecType == XMLElementDecl.TYPE_CHILDREN);
2929
2930 } // validateElementAndAttributes(QName,XMLAttrList)
2931
2932
2933 //validate attributes in DTD fashion
2934 private void validateDTDattribute(QName element, int attValue,
2935 XMLAttributeDecl attributeDecl) throws Exception{
2936 AttributeValidator av = null;
2937 switch (attributeDecl.type) {
2938 case XMLAttributeDecl.TYPE_ENTITY:
2939 {
2940 boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
2941 String unTrimValue = fStringPool.toString(attValue);
2942 String value = unTrimValue.trim();
2943 //System.out.println("value = " + value );
2944 //changes fTempAttDef
2945 if (fValidationEnabled) {
2946 if (value != unTrimValue) {
2947 if (invalidStandaloneAttDef(element, attributeDecl.name)) {
2948 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
2949 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
2950 fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
2951 }
2952 }
2953 }
2954
2955 try {
2956 if ( isAlistAttribute ) {
2957 fValENTITIES.validate( value, null );
2958 } else {
2959 fValENTITY.validate( value, null );
2960 }
2961 } catch ( InvalidDatatypeValueException ex ) {
2962 if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
2963 reportRecoverableXMLError(ex.getMajorCode(),
2964 ex.getMinorCode(),
2965 fStringPool.toString( attributeDecl.name.rawname), value );
2966 } else {
2967 System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
2968 }
2969 }
2970
2971 /*if (attributeDecl.list) {
2972 av = fAttValidatorENTITIES;
2973 }
2974 else {
2975 av = fAttValidatorENTITY;
2976 }*/
2977
2978 }
2979 break;
2980 case XMLAttributeDecl.TYPE_ENUMERATION:
2981 av = fAttValidatorENUMERATION;
2982 break;
2983 case XMLAttributeDecl.TYPE_ID:
2984 {
2985 String unTrimValue = fStringPool.toString(attValue);
2986 String value = unTrimValue.trim();
2987 if (fValidationEnabled) {
2988 if (value != unTrimValue) {
2989 if (invalidStandaloneAttDef(element, attributeDecl.name)) {
2990 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
2991 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
2992 fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
2993 }
2994 }
2995 }
2996 try {
2997 //this.fIdDefs = (Hashtable) fValID.validate( value, null );
2998 //System.out.println("this.fIdDefs = " + this.fIdDefs );
2999
3000 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
3001 } catch ( InvalidDatatypeValueException ex ) {
3002 reportRecoverableXMLError(ex.getMajorCode(),
3003 ex.getMinorCode(),
3004 fStringPool.toString( attributeDecl.name.rawname), value );
3005 }
3006 }
3007 break;
3008 case XMLAttributeDecl.TYPE_IDREF:
3009 {
3010 String unTrimValue = fStringPool.toString(attValue);
3011 String value = unTrimValue.trim();
3012 boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
3013 //changes fTempAttDef
3014 if (fValidationEnabled) {
3015 if (value != unTrimValue) {
3016 if (invalidStandaloneAttDef(element, attributeDecl.name)) {
3017 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
3018 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
3019 fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
3020 }
3021 }
3022 }
3023 try {
3024 if ( isAlistAttribute ) {
3025 fValIDRefs.validate( value, this.fStoreIDRef );
3026 } else {
3027 fValIDRef.validate( value, this.fStoreIDRef );
3028 }
3029 } catch ( InvalidDatatypeValueException ex ) {
3030 if ( ex.getMajorCode() != 1 && ex.getMinorCode() != -1 ) {
3031 reportRecoverableXMLError(ex.getMajorCode(),
3032 ex.getMinorCode(),
3033 fStringPool.toString( attributeDecl.name.rawname), value );
3034 } else {
3035 System.err.println("Error: " + ex.getLocalizedMessage() );//Should not happen
3036 }
3037 }
3038
3039 }
3040 break;
3041 case XMLAttributeDecl.TYPE_NOTATION:
3042 {
3043 /* WIP
3044 String unTrimValue = fStringPool.toString(attValue);
3045 String value = unTrimValue.trim();
3046 if (fValidationEnabled) {
3047 if (value != unTrimValue) {
3048 if (invalidStandaloneAttDef(element, attributeDecl.name)) {
3049 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
3050 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
3051 fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
3052 }
3053 }
3054 }
3055 try {
3056 //this.fIdDefs = (Hashtable) fValID.validate( value, null );
3057 //System.out.println("this.fIdDefs = " + this.fIdDefs );
3058
3059 this.fStoreIDRef.setDatatypeObject( fValID.validate( value, null ) );
3060 } catch ( InvalidDatatypeValueException ex ) {
3061 reportRecoverableXMLError(ex.getMajorCode(),
3062 ex.getMinorCode(),
3063 fStringPool.toString( attributeDecl.name.rawname), value );
3064 }
3065 }
3066 */
3067 av = fAttValidatorNOTATION;
3068
3069
3070 }
3071 break;
3072 case XMLAttributeDecl.TYPE_NMTOKEN:
3073 {
3074 String unTrimValue = fStringPool.toString(attValue);
3075 String value = unTrimValue.trim();
3076 boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
3077 //changes fTempAttDef
3078 if (fValidationEnabled) {
3079 if (value != unTrimValue) {
3080 if (invalidStandaloneAttDef(element, attributeDecl.name)) {
3081 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
3082 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
3083 fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
3084 }
3085 }
3086 }
3087 try {
3088 if ( isAlistAttribute ) {
3089 fValNMTOKENS.validate( value, null );
3090 } else {
3091 fValNMTOKEN.validate( value, null );
3092 }
3093 } catch ( InvalidDatatypeValueException ex ) {
3094 reportRecoverableXMLError(XMLMessages.MSG_NMTOKEN_INVALID,
3095 XMLMessages.VC_NAME_TOKEN,
3096 fStringPool.toString(attributeDecl.name.rawname), value);//TODO NMTOKENS messge
3097 }
3098
3099 }
3100 break;
3101 }
3102 if ( av != null )
3103 av.normalize(element, attributeDecl.name, attValue,
3104 attributeDecl.type, attributeDecl.enumeration);
3105 }
3106
3107 /** Character data in content. */
3108 private void charDataInContent() {
3109
3110 if (DEBUG_ELEMENT_CHILDREN) {
3111 System.out.println("charDataInContent()");
3112 }
3113 if (fElementChildren.length <= fElementChildrenLength) {
3114 QName[] newarray = new QName[fElementChildren.length * 2];
3115 System.arraycopy(fElementChildren, 0, newarray, 0, fElementChildren.length);
3116 fElementChildren = newarray;
3117 }
3118 QName qname = fElementChildren[fElementChildrenLength];
3119 if (qname == null) {
3120 for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
3121 fElementChildren[i] = new QName();
3122 }
3123 qname = fElementChildren[fElementChildrenLength];
3124 }
3125 qname.clear();
3126 fElementChildrenLength++;
3127
3128 } // charDataInCount()
3129
3130 /**
3131 * Check that the content of an element is valid.
3132 * <p>
3133 * This is the method of primary concern to the validator. This method is called
3134 * upon the scanner reaching the end tag of an element. At that time, the
3135 * element's children must be structurally validated, so it calls this method.
3136 * The index of the element being checked (in the decl pool), is provided as
3137 * well as an array of element name indexes of the children. The validator must
3138 * confirm that this element can have these children in this order.
3139 * <p>
3140 * This can also be called to do 'what if' testing of content models just to see
3141 * if they would be valid.
3142 * <p>
3143 * Note that the element index is an index into the element decl pool, whereas
3144 * the children indexes are name indexes, i.e. into the string pool.
3145 * <p>
3146 * A value of -1 in the children array indicates a PCDATA node. All other
3147 * indexes will be positive and represent child elements. The count can be
3148 * zero, since some elements have the EMPTY content model and that must be
3149 * confirmed.
3150 *
3151 * @param elementIndex The index within the <code>ElementDeclPool</code> of this
3152 * element.
3153 * @param childCount The number of entries in the <code>children</code> array.
3154 * @param children The children of this element. Each integer is an index within
3155 * the <code>StringPool</code> of the child element name. An index
3156 * of -1 is used to indicate an occurrence of non-whitespace character
3157 * data.
3158 *
3159 * @return The value -1 if fully valid, else the 0 based index of the child
3160 * that first failed. If the value returned is equal to the number
3161 * of children, then additional content is required to reach a valid
3162 * ending state.
3163 *
3164 * @exception Exception Thrown on error.
3165 */
3166 private int checkContent(int elementIndex,
3167 QName[] children,
3168 int childOffset,
3169 int childCount) throws Exception {
3170
3171 // Get the element name index from the element
3172 // REVISIT: Validation
3173 final int elementType = fCurrentElement.rawname;
3174
3175 if (DEBUG_PRINT_CONTENT) {
3176 String strTmp = fStringPool.toString(elementType);
3177 System.out.println("Name: "+strTmp+", "+
3178 "Count: "+childCount+", "+
3179 "ContentSpecType: " +fCurrentContentSpecType); //+getContentSpecAsString(elementIndex));
3180 for (int index = childOffset; index < (childOffset+childCount) && index < 10; index++) {
3181 if (index == 0) {
3182 System.out.print(" (");
3183 }
3184 String childName = (children[index].localpart == -1) ? "#PCDATA" : fStringPool.toString(children[index].localpart);
3185 if (index + 1 == childCount) {
3186 System.out.println(childName + ")");
3187 } else if (index + 1 == 10) {
3188 System.out.println(childName + ",...)");
3189 } else {
3190 System.out.print(childName + ",");
3191 }
3192 }
3193 }
3194
3195 // Get out the content spec for this element
3196 final int contentType = fCurrentContentSpecType;
3197
3198// debugging
3199//System.out.println("~~~~~~in checkContent, fCurrentContentSpecType : " + fCurrentContentSpecType);
3200
3201 //
3202 // Deal with the possible types of content. We try to optimized here
3203 // by dealing specially with content models that don't require the
3204 // full DFA treatment.
3205 //
3206 if (contentType == XMLElementDecl.TYPE_EMPTY) {
3207 //
3208 // If the child count is greater than zero, then this is
3209 // an error right off the bat at index 0.
3210 //
3211 if (childCount != 0) {
3212 return 0;
3213 }
3214 } else if (contentType == XMLElementDecl.TYPE_ANY) {
3215 //
3216 // This one is open game so we don't pass any judgement on it
3217 // at all. Its assumed to fine since it can hold anything.
3218 //
3219 } else if (contentType == XMLElementDecl.TYPE_MIXED ||
3220 contentType == XMLElementDecl.TYPE_CHILDREN) {
3221 // Get the content model for this element, faulting it in if needed
3222 XMLContentModel cmElem = null;
3223 try {
3224 cmElem = getElementContentModel(elementIndex);
3225 int result = cmElem.validateContent(children, childOffset, childCount);
3226 if (result != -1 && fGrammarIsSchemaGrammar) {
3227 // REVISIT: not optimized for performance,
3228 EquivClassComparator comparator = new EquivClassComparator(fGrammarResolver, fStringPool);
3229 cmElem.setEquivClassComparator(comparator);
3230 result = cmElem.validateContentSpecial(children, childOffset, childCount);
3231 }
3232 return result;
3233 } catch (CMException excToCatch) {
3234 // REVISIT - Translate the caught exception to the protected error API
3235 int majorCode = excToCatch.getErrorCode();
3236 fErrorReporter.reportError(fErrorReporter.getLocator(),
3237 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
3238 majorCode,
3239 0,
3240 null,
3241 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3242 }
3243 } else if (contentType == -1) {
3244 reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
3245 XMLMessages.VC_ELEMENT_VALID,
3246 elementType);
3247 } else if (contentType == XMLElementDecl.TYPE_SIMPLE ) {
3248
3249 XMLContentModel cmElem = null;
3250 if (childCount > 0) {
3251 fErrorReporter.reportError(fErrorReporter.getLocator(),
3252 SchemaMessageProvider.SCHEMA_DOMAIN,
3253 SchemaMessageProvider.DatatypeError,
3254 SchemaMessageProvider.MSG_NONE,
3255 new Object [] { "In element '"+fStringPool.toString(elementType)+"' : "+
3256 "Can not have element children within a simple type content"},
3257 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
3258 } else {
3259 try {
3260
3261 fGrammar.getElementDecl(elementIndex, fTempElementDecl);
3262
3263 DatatypeValidator dv = fTempElementDecl.datatypeValidator;
3264
3265 // If there is xsi:type validator, substitute it.
3266 if ( fXsiTypeValidator != null ) {
3267 dv = fXsiTypeValidator;
3268 fXsiTypeValidator = null;
3269 }
3270
3271 if (dv == null) {
3272 System.out.println("Internal Error: this element have a simpletype "+
3273 "but no datatypevalidator was found, element "+fTempElementDecl.name
3274 +",locapart: "+fStringPool.toString(fTempElementDecl.name.localpart));
3275 } else {
3276 dv.validate(fDatatypeBuffer.toString(), null);
3277 }
3278
3279 } catch (InvalidDatatypeValueException idve) {
3280 fErrorReporter.reportError(fErrorReporter.getLocator(),
3281 SchemaMessageProvider.SCHEMA_DOMAIN,
3282 SchemaMessageProvider.DatatypeError,
3283 SchemaMessageProvider.MSG_NONE,
3284 new Object [] { idve.getMessage()},
3285 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
3286 }
3287 }
3288 } else {
3289 fErrorReporter.reportError(fErrorReporter.getLocator(),
3290 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
3291 ImplementationMessages.VAL_CST,
3292 0,
3293 null,
3294 XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3295 }
3296
3297 // We succeeded
3298 return -1;
3299
3300 } // checkContent(int,int,int[]):int
3301
3302
3303 /**
3304 * Checks that all declared elements refer to declared elements
3305 * in their content models. This method calls out to the error
3306 * handler to indicate warnings.
3307 */
3308 /*private void checkDeclaredElements() throws Exception {
3309
3310 //****DEBUG****
3311 if (DEBUG) print("(???) XMLValidator.checkDeclaredElements\n");
3312 //****DEBUG****
3313
3314 for (int i = 0; i < fElementCount; i++) {
3315 int type = fGrammar.getContentSpecType(i);
3316 if (type == XMLElementDecl.TYPE_MIXED || type == XMLElementDecl.TYPE_CHILDREN) {
3317 int chunk = i >> CHUNK_SHIFT;
3318 int index = i & CHUNK_MASK;
3319 int contentSpecIndex = fContentSpec[chunk][index];
3320 checkDeclaredElements(i, contentSpecIndex);
3321 }
3322 }
3323 }
3324 */
3325
3326 private void printChildren() {
3327 if (DEBUG_ELEMENT_CHILDREN) {
3328 System.out.print('[');
3329 for (int i = 0; i < fElementChildrenLength; i++) {
3330 System.out.print(' ');
3331 QName qname = fElementChildren[i];
3332 if (qname != null) {
3333 System.out.print(fStringPool.toString(qname.rawname));
3334 } else {
3335 System.out.print("null");
3336 }
3337 if (i < fElementChildrenLength - 1) {
3338 System.out.print(", ");
3339 }
3340 System.out.flush();
3341 }
3342 System.out.print(" ]");
3343 System.out.println();
3344 }
3345 }
3346
3347 private void printStack() {
3348 if (DEBUG_ELEMENT_CHILDREN) {
3349 System.out.print('{');
3350 for (int i = 0; i <= fElementDepth; i++) {
3351 System.out.print(' ');
3352 System.out.print(fElementChildrenOffsetStack[i]);
3353 if (i < fElementDepth) {
3354 System.out.print(", ");
3355 }
3356 System.out.flush();
3357 }
3358 System.out.print(" }");
3359 System.out.println();
3360 }
3361 }
3362
3363
3364 //
3365 // Interfaces
3366 //
3367
3368 /**
3369 * AttributeValidator.
3370 */
3371 public interface AttributeValidator {
3372
3373 //
3374 // AttributeValidator methods
3375 //
3376
3377 /** Normalize. */
3378 public int normalize(QName element, QName attribute,
3379 int attValue, int attType, int enumHandle)
3380 throws Exception;
3381
3382 } // interface AttributeValidator
3383
3384
3385 /** Returns true if invalid standalone attribute definition. */
3386 boolean invalidStandaloneAttDef(QName element, QName attribute) {
3387 if (fStandaloneReader == -1) {
3388 return false;
3389 }
3390 // we are normalizing a default att value... this ok?
3391 if (element.rawname == -1) {
3392 return false;
3393 }
3394 return getAttDefIsExternal(element, attribute);
3395 }
3396
3397
3398 //
3399 // Classes
3400 //
3401
3402
3403 /**
3404 * AttValidatorNOTATION.
3405 */
3406 final class AttValidatorNOTATION
3407 implements AttributeValidator {
3408
3409 //
3410 // AttributeValidator methods
3411 //
3412
3413 /** Normalize. */
3414 public int normalize(QName element, QName attribute,
3415 int attValueHandle, int attType,
3416 int enumHandle) throws Exception {
3417 //
3418 // Normalize attribute based upon attribute type...
3419 //
3420 String attValue = fStringPool.toString(attValueHandle);
3421 String newAttValue = attValue.trim();
3422 if (fValidating) {
3423 // REVISIT - can we release the old string?
3424 if (newAttValue != attValue) {
3425 if (invalidStandaloneAttDef(element, attribute)) {
3426 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
3427 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
3428 fStringPool.toString(attribute.rawname), attValue, newAttValue);
3429 }
3430 attValueHandle = fStringPool.addSymbol(newAttValue);
3431 } else {
3432 attValueHandle = fStringPool.addSymbol(attValueHandle);
3433 }
3434 //
3435 // NOTATION - check that the value is in the AttDef enumeration (V_TAGo)
3436 //
3437 if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
3438 reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
3439 XMLMessages.VC_NOTATION_ATTRIBUTES,
3440 fStringPool.toString(attribute.rawname),
3441 newAttValue, fStringPool.stringListAsString(enumHandle));
3442 }
3443 } else if (newAttValue != attValue) {
3444 // REVISIT - can we release the old string?
3445 attValueHandle = fStringPool.addSymbol(newAttValue);
3446 }
3447 return attValueHandle;
3448
3449 } // normalize(QName,QName,int,int,int):int
3450
3451 //
3452 // Package methods
3453 //
3454
3455 /** Returns true if invalid standalone attribute definition. */
3456 boolean invalidStandaloneAttDef(QName element, QName attribute) {
3457 if (fStandaloneReader == -1) {
3458 return false;
3459 }
3460 // we are normalizing a default att value... this ok?
3461 if (element.rawname == -1) {
3462 return false;
3463 }
3464 return getAttDefIsExternal(element, attribute);
3465 }
3466
3467 } // class AttValidatorNOTATION
3468
3469 /**
3470 * AttValidatorENUMERATION.
3471 */
3472 final class AttValidatorENUMERATION
3473 implements AttributeValidator {
3474
3475 //
3476 // AttributeValidator methods
3477 //
3478
3479 /** Normalize. */
3480 public int normalize(QName element, QName attribute,
3481 int attValueHandle, int attType,
3482 int enumHandle) throws Exception {
3483 //
3484 // Normalize attribute based upon attribute type...
3485 //
3486 String attValue = fStringPool.toString(attValueHandle);
3487 String newAttValue = attValue.trim();
3488 if (fValidating) {
3489 // REVISIT - can we release the old string?
3490 if (newAttValue != attValue) {
3491 if (invalidStandaloneAttDef(element, attribute)) {
3492 reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
3493 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
3494 fStringPool.toString(attribute.rawname), attValue, newAttValue);
3495 }
3496 attValueHandle = fStringPool.addSymbol(newAttValue);
3497 } else {
3498 attValueHandle = fStringPool.addSymbol(attValueHandle);
3499 }
3500 //
3501 // ENUMERATION - check that value is in the AttDef enumeration (V_TAG9)
3502 //
3503 if (!fStringPool.stringInList(enumHandle, attValueHandle)) {
3504 reportRecoverableXMLError(XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
3505 XMLMessages.VC_ENUMERATION,
3506 fStringPool.toString(attribute.rawname),
3507 newAttValue, fStringPool.stringListAsString(enumHandle));
3508 }
3509 } else if (newAttValue != attValue) {
3510 // REVISIT - can we release the old string?
3511 attValueHandle = fStringPool.addSymbol(newAttValue);
3512 }
3513 return attValueHandle;
3514
3515 } // normalize(QName,QName,int,int,int):int
3516
3517 //
3518 // Package methods
3519 //
3520
3521 /** Returns true if invalid standalone attribute definition. */
3522 boolean invalidStandaloneAttDef(QName element, QName attribute) {
3523 if (fStandaloneReader == -1) {
3524 return false;
3525 }
3526 // we are normalizing a default att value... this ok?
3527 if (element.rawname == -1) {
3528 return false;
3529 }
3530 return getAttDefIsExternal(element, attribute);
3531 }
3532
3533 } // class AttValidatorENUMERATION
3534
3535} // class XMLValidator