Source Code Cross Referenced for XMLValidator.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » xerces » validators » common » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Server » Rimfaxe Web Server » org.apache.xerces.validators.common 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The Apache Software License, Version 1.1
0003:         *
0004:         *
0005:         * Copyright (c) 1999,2000,2001 The Apache Software Foundation.
0006:         * All rights reserved.
0007:         *
0008:         * Redistribution and use in source and binary forms, with or without
0009:         * modification, are permitted provided that the following conditions
0010:         * are met:
0011:         *
0012:         * 1. Redistributions of source code must retain the above copyright
0013:         *    notice, this list of conditions and the following disclaimer.
0014:         *
0015:         * 2. Redistributions in binary form must reproduce the above copyright
0016:         *    notice, this list of conditions and the following disclaimer in
0017:         *    the documentation and/or other materials provided with the
0018:         *    distribution.
0019:         *
0020:         * 3. The end-user documentation included with the redistribution,
0021:         *    if any, must include the following acknowledgment:
0022:         *       "This product includes software developed by the
0023:         *        Apache Software Foundation (http://www.apache.org/)."
0024:         *    Alternately, this acknowledgment may appear in the software itself,
0025:         *    if and wherever such third-party acknowledgments normally appear.
0026:         *
0027:         * 4. The names "Xerces" and "Apache Software Foundation" must
0028:         *    not be used to endorse or promote products derived from this
0029:         *    software without prior written permission. For written
0030:         *    permission, please contact apache@apache.org.
0031:         *
0032:         * 5. Products derived from this software may not be called "Apache",
0033:         *    nor may "Apache" appear in their name, without prior written
0034:         *    permission of the Apache Software Foundation.
0035:         *
0036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0040:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047:         * SUCH DAMAGE.
0048:         * ====================================================================
0049:         *
0050:         * This software consists of voluntary contributions made by many
0051:         * individuals on behalf of the Apache Software Foundation and was
0052:         * originally based on software copyright (c) 1999, International
0053:         * Business Machines, Inc., http://www.apache.org.  For more
0054:         * information on the Apache Software Foundation, please see
0055:         * <http://www.apache.org/>.
0056:         */
0057:
0058:        package org.apache.xerces.validators.common;
0059:
0060:        import org.apache.xerces.framework.XMLAttrList;
0061:        import org.apache.xerces.framework.XMLContentSpec;
0062:        import org.apache.xerces.framework.XMLDocumentHandler;
0063:        import org.apache.xerces.framework.XMLDocumentScanner;
0064:        import org.apache.xerces.framework.XMLErrorReporter;
0065:        import org.apache.xerces.readers.DefaultEntityHandler;
0066:        import org.apache.xerces.readers.XMLEntityHandler;
0067:        import org.apache.xerces.utils.ChunkyCharArray;
0068:        import org.apache.xerces.utils.Hash2intTable;
0069:        import org.apache.xerces.utils.IntStack;
0070:        import org.apache.xerces.utils.NamespacesScope;
0071:        import org.apache.xerces.utils.QName;
0072:        import org.apache.xerces.utils.StringPool;
0073:        import org.apache.xerces.utils.XMLCharacterProperties;
0074:        import org.apache.xerces.utils.XMLMessages;
0075:        import org.apache.xerces.utils.ImplementationMessages;
0076:
0077:        import org.apache.xerces.parsers.DOMParser;
0078:
0079:        import org.w3c.dom.Document;
0080:        import org.w3c.dom.Element;
0081:
0082:        import org.xml.sax.InputSource;
0083:        import org.xml.sax.EntityResolver;
0084:        import org.xml.sax.Locator;
0085:        import org.xml.sax.helpers.LocatorImpl;
0086:        import org.xml.sax.SAXException;
0087:        import org.xml.sax.SAXParseException;
0088:
0089:        import java.io.IOException;
0090:
0091:        import java.util.Enumeration;
0092:        import java.util.Hashtable;
0093:        import java.util.Stack;
0094:        import java.util.StringTokenizer;
0095:        import java.util.Vector;
0096:
0097:        import org.apache.xerces.validators.dtd.DTDGrammar;
0098:
0099:        import org.apache.xerces.validators.schema.GeneralAttrCheck;
0100:        import org.apache.xerces.validators.schema.SubstitutionGroupComparator;
0101:        import org.apache.xerces.validators.schema.SchemaGrammar;
0102:        import org.apache.xerces.validators.schema.SchemaMessageProvider;
0103:        import org.apache.xerces.validators.schema.SchemaSymbols;
0104:        import org.apache.xerces.validators.schema.TraverseSchema;
0105:        import org.apache.xerces.validators.schema.identity.Field;
0106:        import org.apache.xerces.validators.schema.identity.FieldActivator;
0107:        import org.apache.xerces.validators.schema.identity.IdentityConstraint;
0108:        import org.apache.xerces.validators.schema.identity.IDValue;
0109:        import org.apache.xerces.validators.schema.identity.Key;
0110:        import org.apache.xerces.validators.schema.identity.KeyRef;
0111:        import org.apache.xerces.validators.schema.identity.Selector;
0112:        import org.apache.xerces.validators.schema.identity.Unique;
0113:        import org.apache.xerces.validators.schema.identity.ValueStore;
0114:        import org.apache.xerces.validators.schema.identity.XPathMatcher;
0115:
0116:        import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
0117:        import org.apache.xerces.validators.datatype.DatatypeValidator;
0118:        import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
0119:        import org.apache.xerces.validators.datatype.StateMessageDatatype;
0120:        import org.apache.xerces.validators.datatype.IDREFDatatypeValidator;
0121:        import org.apache.xerces.validators.datatype.IDDatatypeValidator;
0122:        import org.apache.xerces.validators.datatype.ENTITYDatatypeValidator;
0123:        import org.apache.xerces.validators.datatype.NOTATIONDatatypeValidator;
0124:        import org.apache.xerces.validators.datatype.UnionDatatypeValidator;
0125:        import org.apache.xerces.validators.datatype.AnySimpleType;
0126:
0127:        /**
0128:         * This class is the super all-in-one validator used by the parser.
0129:         *
0130:         * @version $Id: XMLValidator.java,v 1.186.2.8 2001/11/07 20:08:48 neilg Exp $
0131:         */
0132:        public final class XMLValidator implements 
0133:                DefaultEntityHandler.EventHandler,
0134:                XMLEntityHandler.CharDataHandler,
0135:                XMLDocumentScanner.EventHandler,
0136:                NamespacesScope.NamespacesHandler, FieldActivator // for identity constraints
0137:        {
0138:
0139:            //
0140:            // Constants
0141:            //
0142:
0143:            // debugging
0144:
0145:            private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
0146:            private static final boolean DEBUG_PRINT_ATTRIBUTES = false;
0147:            private static final boolean DEBUG_PRINT_CONTENT = false;
0148:            private static final boolean DEBUG_SCHEMA_VALIDATION = false;
0149:            private static final boolean DEBUG_ELEMENT_CHILDREN = false;
0150:
0151:            /** Compile to true to debug identity constraints. */
0152:            protected static final boolean DEBUG_IDENTITY_CONSTRAINTS = false;
0153:
0154:            /** Compile to true to debug value stores. */
0155:            protected static final boolean DEBUG_VALUE_STORES = false;
0156:
0157:            // Chunk size constants
0158:
0159:            private static final int CHUNK_SHIFT = 8; // 2^8 = 256
0160:            private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
0161:            private static final int CHUNK_MASK = CHUNK_SIZE - 1;
0162:            private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
0163:
0164:            private Hashtable fIdDefs = new Hashtable();
0165:            private Hashtable fIdREFDefs = new Hashtable();
0166:
0167:            private StateMessageDatatype fValidateIDRef = new StateMessageDatatype() {
0168:                private Hashtable fIdDefs;
0169:
0170:                public Object getDatatypeObject() {
0171:                    return (Object) fIdDefs;
0172:                }
0173:
0174:                public int getDatatypeState() {
0175:                    return IDREFDatatypeValidator.IDREF_VALIDATE;
0176:                }
0177:
0178:                public void setDatatypeObject(Object data) {
0179:                    fIdDefs = (Hashtable) data;
0180:                }
0181:            };
0182:
0183:            private StateMessageDatatype fCheckIDRef = new StateMessageDatatype() {
0184:                private Object[] fLists;
0185:
0186:                public Object getDatatypeObject() {
0187:                    return (Object) fLists;
0188:                }
0189:
0190:                public int getDatatypeState() {
0191:                    return IDREFDatatypeValidator.IDREF_CHECKID;
0192:                }
0193:
0194:                public void setDatatypeObject(Object data) {
0195:                    fLists = (Object[]) data;
0196:                }
0197:            };
0198:
0199:            private StateMessageDatatype fValidateEntity = new StateMessageDatatype() {
0200:                private Object fData;
0201:
0202:                public Object getDatatypeObject() {
0203:                    return fData;
0204:                }
0205:
0206:                public int getDatatypeState() {
0207:                    return ENTITYDatatypeValidator.ENTITY_VALIDATE;
0208:                }
0209:
0210:                public void setDatatypeObject(Object data) {
0211:                    fData = data;
0212:                }
0213:            };
0214:
0215:            //
0216:            // Data
0217:            //
0218:
0219:            // REVISIT: The data should be regrouped and re-organized so that
0220:            //          it's easier to find a meaningful field.
0221:
0222:            // attribute validators
0223:
0224:            private AttributeValidator fAttValidatorNOTATION = new AttValidatorNOTATION();
0225:            private AttributeValidator fAttValidatorENUMERATION = new AttValidatorENUMERATION();
0226:            private AttributeValidator fAttValidatorDATATYPE = null;
0227:
0228:            // Package access for use by AttributeValidator classes.
0229:
0230:            StringPool fStringPool = null;
0231:            boolean fValidating = false;
0232:            boolean fInElementContent = false;
0233:            int fStandaloneReader = -1;
0234:
0235:            // settings
0236:
0237:            private boolean fValidationEnabled = false;
0238:            private boolean fDynamicValidation = false;
0239:            private boolean fSchemaValidation = true;
0240:            private boolean fSchemaValidationFullChecking = false;
0241:            private boolean fValidationEnabledByDynamic = false;
0242:            private boolean fDynamicDisabledByValidation = false;
0243:            private boolean fWarningOnDuplicateAttDef = false;
0244:            private boolean fWarningOnUndeclaredElements = false;
0245:            private boolean fNormalizeAttributeValues = true;
0246:            private boolean fLoadDTDGrammar = true;
0247:            // expose normalized values for element/attribute content
0248:            // default: expose Infoset
0249:            private boolean fNormalizeContents = false;
0250:
0251:            // REVISIT: normalization
0252:            // would not work properly for UNION types since we don't have
0253:            // correct whiteSpace facet to normalize values.
0254:            //
0255:
0256:            // Private temporary variables
0257:
0258:            private Hashtable fLocationUriPairs = new Hashtable(10);
0259:
0260:            // declarations
0261:
0262:            private String fExternalSchemas = null;
0263:            private String fExternalNoNamespaceSchema = null;
0264:            private DOMParser fSchemaGrammarParser = null;
0265:            private int fDeclaration[];
0266:            private XMLErrorReporter fErrorReporter = null;
0267:            private DefaultEntityHandler fEntityHandler = null;
0268:            private QName fCurrentElement = new QName();
0269:
0270:            private ContentLeafNameTypeVector[] fContentLeafStack = new ContentLeafNameTypeVector[8];
0271:
0272:            //OTWI: on-the-way-in
0273:            // store the content model
0274:            private XMLContentModel[] fContentModelStack = new XMLContentModel[8];
0275:            // >= 0 normal state; -1: error; -2: on-the-way-out
0276:            private int[] fContentModelStateStack = new int[8];
0277:            // how many child elements have succefully validated
0278:            private int[] fContentModelEleCount = new int[8];
0279:
0280:            private int[] fValidationFlagStack = new int[8];
0281:
0282:            private int[] fScopeStack = new int[8];
0283:            private int[] fGrammarNameSpaceIndexStack = new int[8];
0284:
0285:            private int[] fElementEntityStack = new int[8];
0286:            private int[] fElementIndexStack = new int[8];
0287:            private int[] fContentSpecTypeStack = new int[8];
0288:
0289:            private static final int sizeQNameParts = 8;
0290:            private QName[] fElementQNamePartsStack = new QName[sizeQNameParts];
0291:
0292:            private QName[] fElementChildren = new QName[32];
0293:            private int fElementChildrenLength = 0;
0294:            private int[] fElementChildrenOffsetStack = new int[32];
0295:            private int fElementDepth = -1;
0296:
0297:            private boolean fNamespacesEnabled = false;
0298:            private NamespacesScope fNamespacesScope = null;
0299:            private int fNamespacesPrefix = -1;
0300:            private QName fRootElement = new QName();
0301:            private int fAttrListHandle = -1;
0302:            private int fCurrentElementEntity = -1;
0303:            private int fCurrentElementIndex = -1;
0304:            private int fCurrentContentSpecType = -1;
0305:            private boolean fSeenDoctypeDecl = false;
0306:
0307:            private final int TOP_LEVEL_SCOPE = -1;
0308:            private int fCurrentScope = TOP_LEVEL_SCOPE;
0309:            private int fCurrentSchemaURI = StringPool.EMPTY_STRING;
0310:            private int fEmptyURI = StringPool.EMPTY_STRING;
0311:            private int fXsiPrefix = -1;
0312:            private int fXsiURI = -2;
0313:            private int fXsiTypeAttValue = -1;
0314:            private DatatypeValidator fXsiTypeValidator = null;
0315:
0316:            private boolean fNil = false;
0317:
0318:            private Grammar fGrammar = null;
0319:            private int fGrammarNameSpaceIndex = StringPool.EMPTY_STRING;
0320:            private GrammarResolver fGrammarResolver = null;
0321:
0322:            // state and stuff
0323:
0324:            private boolean fScanningDTD = false;
0325:            private XMLDocumentScanner fDocumentScanner = null;
0326:            private boolean fCalledStartDocument = false;
0327:            private XMLDocumentHandler fDocumentHandler = null;
0328:            private XMLDocumentHandler.DTDHandler fDTDHandler = null;
0329:            private boolean fSeenRootElement = false;
0330:            private XMLAttrList fAttrList = null;
0331:            private int fXMLLang = -1;
0332:            private LocatorImpl fAttrNameLocator = null;
0333:            private boolean fCheckedForSchema = false;
0334:            private boolean fDeclsAreExternal = false;
0335:            private StringPool.CharArrayRange fCurrentElementCharArrayRange = null;
0336:            private char[] fCharRefData = null;
0337:            private boolean fSendCharDataAsCharArray = false;
0338:            private boolean fBufferDatatype = false;
0339:            // holds normalized or unnormalized string element value, 
0340:            private StringBuffer fDatatypeBuffer = new StringBuffer();
0341:
0342:            private QName fTempQName = new QName();
0343:            private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
0344:            private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
0345:            private XMLElementDecl fTempElementDecl = new XMLElementDecl();
0346:
0347:            private boolean fGrammarIsDTDGrammar = false;
0348:            private boolean fGrammarIsSchemaGrammar = false;
0349:
0350:            private boolean fNeedValidationOff = false;
0351:
0352:            //Schema Normalization
0353:            private static final boolean DEBUG_NORMALIZATION = false;
0354:            private DatatypeValidator fCurrentDV = null; //current datatype validator
0355:            private boolean fFirstChunk = true; // got first chunk in characters() (SAX)
0356:            private boolean fTrailing = false; // Previous chunk had a trailing space
0357:            private short fWhiteSpace = DatatypeValidator.COLLAPSE; //whiteSpace: preserve/replace/collapse
0358:            private StringBuffer fNormalizedStr = new StringBuffer(CHUNK_SIZE); //holds normalized str value
0359:            private StringBuffer fUnnormalizedStr = new StringBuffer(CHUNK_SIZE); //holds unnormalized str value
0360:
0361:            // symbols
0362:
0363:            private int fEMPTYSymbol = -1;
0364:            private int fANYSymbol = -1;
0365:            private int fMIXEDSymbol = -1;
0366:            private int fCHILDRENSymbol = -1;
0367:            private int fCDATASymbol = -1;
0368:            private int fIDSymbol = -1;
0369:            private int fIDREFSymbol = -1;
0370:            private int fIDREFSSymbol = -1;
0371:            private int fENTITYSymbol = -1;
0372:            private int fENTITIESSymbol = -1;
0373:            private int fNMTOKENSymbol = -1;
0374:            private int fNMTOKENSSymbol = -1;
0375:            private int fNOTATIONSymbol = -1;
0376:            private int fENUMERATIONSymbol = -1;
0377:            private int fREQUIREDSymbol = -1;
0378:            private int fFIXEDSymbol = -1;
0379:            private int fDATATYPESymbol = -1;
0380:            private int fEpsilonIndex = -1;
0381:
0382:            //Datatype Registry
0383:
0384:            private DatatypeValidatorFactoryImpl fDataTypeReg = null;
0385:            private DatatypeValidator fValID = null;
0386:            private DatatypeValidator fValIDRef = null;
0387:            private DatatypeValidator fValIDRefs = null;
0388:            private DatatypeValidator fValENTITY = null;
0389:            private DatatypeValidator fValENTITIES = null;
0390:            private DatatypeValidator fValNMTOKEN = null;
0391:            private DatatypeValidator fValNMTOKENS = null;
0392:            private DatatypeValidator fValNOTATION = null;
0393:
0394:            // identity constraint information
0395:
0396:            /**
0397:             * Stack of active XPath matchers for identity constraints. All
0398:             * active XPath matchers are notified of startElement, characters
0399:             * and endElement callbacks in order to perform their matches.
0400:             * <p>
0401:             * For each element with identity constraints, the selector of
0402:             * each identity constraint is activated. When the selector matches
0403:             * its XPath, then all the fields of the identity constraint are
0404:             * activated.
0405:             * <p>
0406:             * <strong>Note:</strong> Once the activation scope is left, the
0407:             * XPath matchers are automatically removed from the stack of
0408:             * active matchers and no longer receive callbacks.
0409:             */
0410:            protected XPathMatcherStack fMatcherStack = new XPathMatcherStack();
0411:
0412:            /** Cache of value stores for identity constraint fields. */
0413:            protected ValueStoreCache fValueStoreCache = new ValueStoreCache();
0414:
0415:            // store the substitution group comparator
0416:            protected SubstitutionGroupComparator fSGComparator = null;
0417:
0418:            // on which grammars we have checked UPA
0419:            protected Hashtable UPACheckedGrammarURIs = new Hashtable();
0420:            protected static Object fgNullObject = new Object();
0421:
0422:            //
0423:            // Constructors
0424:            //
0425:
0426:            /** Constructs an XML validator. */
0427:            public XMLValidator(StringPool stringPool,
0428:                    XMLErrorReporter errorReporter,
0429:                    DefaultEntityHandler entityHandler,
0430:                    XMLDocumentScanner documentScanner) {
0431:
0432:                // keep references
0433:                fStringPool = stringPool;
0434:                fErrorReporter = errorReporter;
0435:                fEntityHandler = entityHandler;
0436:                fDocumentScanner = documentScanner;
0437:
0438:                fValidateEntity.setDatatypeObject(new Object[] { entityHandler,
0439:                        stringPool });
0440:                fValidateIDRef.setDatatypeObject(fIdREFDefs);
0441:                fCheckIDRef.setDatatypeObject(new Object[] { fIdDefs,
0442:                        fIdREFDefs });
0443:
0444:                fEmptyURI = fStringPool.addSymbol("");
0445:                fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
0446:                // initialize
0447:                fAttrList = new XMLAttrList(fStringPool);
0448:                entityHandler.setEventHandler(this );
0449:                entityHandler.setCharDataHandler(this );
0450:                fDocumentScanner.setEventHandler(this );
0451:
0452:                for (int i = 0; i < sizeQNameParts; i++) {
0453:                    fElementQNamePartsStack[i] = new QName();
0454:                }
0455:                init();
0456:
0457:            } // <init>(StringPool,XMLErrorReporter,DefaultEntityHandler,XMLDocumentScanner)
0458:
0459:            public void setGrammarResolver(GrammarResolver grammarResolver) {
0460:                fGrammarResolver = grammarResolver;
0461:            }
0462:
0463:            //
0464:            // Public methods
0465:            //
0466:
0467:            // initialization
0468:
0469:            /** Set char data processing preference and handlers. */
0470:            public void initHandlers(boolean sendCharDataAsCharArray,
0471:                    XMLDocumentHandler docHandler,
0472:                    XMLDocumentHandler.DTDHandler dtdHandler) {
0473:
0474:                fSendCharDataAsCharArray = sendCharDataAsCharArray;
0475:                fEntityHandler
0476:                        .setSendCharDataAsCharArray(fSendCharDataAsCharArray);
0477:                fDocumentHandler = docHandler;
0478:                fDTDHandler = dtdHandler;
0479:
0480:            } // initHandlers(boolean,XMLDocumentHandler,XMLDocumentHandler.DTDHandler)
0481:
0482:            /** Reset or copy. */
0483:            public void resetOrCopy(StringPool stringPool) throws Exception {
0484:                fAttrList = new XMLAttrList(stringPool);
0485:                resetCommon(stringPool);
0486:            }
0487:
0488:            /** Reset. */
0489:            public void reset(StringPool stringPool) throws Exception {
0490:                fAttrList.reset(stringPool);
0491:                resetCommon(stringPool);
0492:            }
0493:
0494:            // settings
0495:
0496:            /**
0497:             * Turning on validation/dynamic turns on validation if it is off, and
0498:             * this is remembered.  Turning off validation DISABLES validation/dynamic
0499:             * if it is on.  Turning off validation/dynamic DOES NOT turn off
0500:             * validation if it was explicitly turned on, only if it was turned on
0501:             * BECAUSE OF the call to turn validation/dynamic on.  Turning on
0502:             * validation will REENABLE and turn validation/dynamic back on if it
0503:             * was disabled by a call that turned off validation while
0504:             * validation/dynamic was enabled.
0505:             */
0506:            public void setValidationEnabled(boolean flag) throws Exception {
0507:                fValidationEnabled = flag;
0508:                fValidationEnabledByDynamic = false;
0509:                if (fValidationEnabled) {
0510:                    if (fDynamicDisabledByValidation) {
0511:                        fDynamicValidation = true;
0512:                        fDynamicDisabledByValidation = false;
0513:                    }
0514:                } else if (fDynamicValidation) {
0515:                    fDynamicValidation = false;
0516:                    fDynamicDisabledByValidation = true;
0517:                }
0518:                fValidating = fValidationEnabled;
0519:                if (fValidating) {
0520:                    initDataTypeValidators();
0521:                }
0522:            }
0523:
0524:            /** Returns true if validation is enabled. */
0525:            public boolean getValidationEnabled() {
0526:                return fValidationEnabled;
0527:            }
0528:
0529:            /** Sets whether Schema support is on/off. */
0530:            public void setSchemaValidationEnabled(boolean flag) {
0531:                fSchemaValidation = flag;
0532:            }
0533:
0534:            /** Returns true if Schema support is on. */
0535:            public boolean getSchemaValidationEnabled() {
0536:                return fSchemaValidation;
0537:            }
0538:
0539:            /** Sets whether full Schema error checking is on/off */
0540:            public void setSchemaFullCheckingEnabled(boolean flag) {
0541:                fSchemaValidationFullChecking = flag;
0542:            }
0543:
0544:            //Properties on the parser to allow the user to specify
0545:            //XML schemas externaly
0546:            //
0547:            public void setExternalSchemas(Object value) {
0548:                fExternalSchemas = (String) value;
0549:            }
0550:
0551:            public void setExternalNoNamespaceSchema(Object value) {
0552:                fExternalNoNamespaceSchema = (String) value;
0553:            }
0554:
0555:            public String getExternalSchemas() {
0556:                return fExternalSchemas;
0557:            }
0558:
0559:            public String getExternalNoNamespaceSchema() {
0560:                return fExternalNoNamespaceSchema;
0561:            }
0562:
0563:            /** Returns true if full Schema checking is on. */
0564:            public boolean getSchemaFullCheckingEnabled() {
0565:                return fSchemaValidationFullChecking;
0566:            }
0567:
0568:            /** Sets whether validation is dynamic. */
0569:            public void setDynamicValidationEnabled(boolean flag)
0570:                    throws Exception {
0571:                fDynamicValidation = flag;
0572:                fDynamicDisabledByValidation = false;
0573:                if (!fDynamicValidation) {
0574:                    if (fValidationEnabledByDynamic) {
0575:                        fValidationEnabled = false;
0576:                        fValidationEnabledByDynamic = false;
0577:                    }
0578:                } else if (!fValidationEnabled) {
0579:                    fValidationEnabled = true;
0580:                    fValidationEnabledByDynamic = true;
0581:                }
0582:                fValidating = fValidationEnabled;
0583:                if (fValidating) {
0584:                    initDataTypeValidators();
0585:                }
0586:            }
0587:
0588:            /** Returns true if validation is dynamic. */
0589:            public boolean getDynamicValidationEnabled() {
0590:                return fDynamicValidation;
0591:            }
0592:
0593:            /** Sets fNormalizeAttributeValues **/
0594:            public void setNormalizeAttributeValues(boolean normalize) {
0595:                fNormalizeAttributeValues = normalize;
0596:            }
0597:
0598:            /** Sets fLoadDTDGrammar when validation is off **/
0599:            public void setLoadDTDGrammar(boolean loadDG) {
0600:                if (fValidating) {
0601:                    fLoadDTDGrammar = true;
0602:                } else {
0603:                    fLoadDTDGrammar = loadDG;
0604:                }
0605:            }
0606:
0607:            /** Returns fLoadDTDGrammar **/
0608:            public boolean getLoadDTDGrammar() {
0609:                return fLoadDTDGrammar;
0610:            }
0611:
0612:            /** Sets whether namespaces are enabled. */
0613:            public void setNamespacesEnabled(boolean flag) {
0614:                fNamespacesEnabled = flag;
0615:            }
0616:
0617:            /** Returns true if namespaces are enabled. */
0618:            public boolean getNamespacesEnabled() {
0619:                return fNamespacesEnabled;
0620:            }
0621:
0622:            /** Sets whether duplicate attribute definitions signal a warning. */
0623:            public void setWarningOnDuplicateAttDef(boolean flag) {
0624:                fWarningOnDuplicateAttDef = flag;
0625:            }
0626:
0627:            /** Returns true if duplicate attribute definitions signal a warning. */
0628:            public boolean getWarningOnDuplicateAttDef() {
0629:                return fWarningOnDuplicateAttDef;
0630:            }
0631:
0632:            /** Sets whether undeclared elements signal a warning. */
0633:            public void setWarningOnUndeclaredElements(boolean flag) {
0634:                fWarningOnUndeclaredElements = flag;
0635:            }
0636:
0637:            /** Returns true if undeclared elements signal a warning. */
0638:            public boolean getWarningOnUndeclaredElements() {
0639:                return fWarningOnUndeclaredElements;
0640:            }
0641:
0642:            /** Sets fNormalizeContents **/
0643:            public void setNormalizeContents(boolean normalize) {
0644:                fNormalizeContents = normalize;
0645:            }
0646:
0647:            public boolean getNormalizeConents() {
0648:                return fNormalizeContents;
0649:            }
0650:
0651:            //
0652:            // FieldActivator methods
0653:            //
0654:
0655:            /**
0656:             * Start the value scope for the specified identity constraint. This
0657:             * method is called when the selector matches in order to initialize
0658:             * the value store.
0659:             *
0660:             * @param identityConstraint The identity constraint.
0661:             */
0662:            public void startValueScopeFor(IdentityConstraint identityConstraint)
0663:                    throws Exception {
0664:
0665:                for (int i = 0; i < identityConstraint.getFieldCount(); i++) {
0666:                    Field field = identityConstraint.getFieldAt(i);
0667:                    ValueStoreBase valueStore = fValueStoreCache
0668:                            .getValueStoreFor(field);
0669:                    valueStore.startValueScope();
0670:                }
0671:
0672:            } // startValueScopeFor(IdentityConstraint identityConstraint)
0673:
0674:            /**
0675:             * Request to activate the specified field. This method returns the
0676:             * matcher for the field.
0677:             *
0678:             * @param field The field to activate.
0679:             */
0680:            public XPathMatcher activateField(Field field) throws Exception {
0681:                if (DEBUG_IDENTITY_CONSTRAINTS) {
0682:                    System.out
0683:                            .println("<IC>: activateField(\"" + field + "\")");
0684:                }
0685:                ValueStore valueStore = fValueStoreCache
0686:                        .getValueStoreFor(field);
0687:                field.setMayMatch(true);
0688:                XPathMatcher matcher = field.createMatcher(valueStore);
0689:                fMatcherStack.addMatcher(matcher);
0690:                matcher.startDocumentFragment(fStringPool);
0691:                return matcher;
0692:            } // activateField(Field):XPathMatcher
0693:
0694:            /**
0695:             * Ends the value scope for the specified identity constraint.
0696:             *
0697:             * @param identityConstraint The identity constraint.
0698:             */
0699:            public void endValueScopeFor(IdentityConstraint identityConstraint)
0700:                    throws Exception {
0701:
0702:                ValueStoreBase valueStore = fValueStoreCache
0703:                        .getValueStoreFor(identityConstraint);
0704:                valueStore.endValueScope();
0705:
0706:            } // endValueScopeFor(IdentityConstraint)
0707:
0708:            //
0709:            // DefaultEntityHandler.EventHandler methods
0710:            //
0711:
0712:            /** Start entity reference. */
0713:            public void startEntityReference(int entityName, int entityType,
0714:                    int entityContext) throws Exception {
0715:                fDocumentHandler.startEntityReference(entityName, entityType,
0716:                        entityContext);
0717:            }
0718:
0719:            /** End entity reference. */
0720:            public void endEntityReference(int entityName, int entityType,
0721:                    int entityContext) throws Exception {
0722:                fDocumentHandler.endEntityReference(entityName, entityType,
0723:                        entityContext);
0724:            }
0725:
0726:            /** Send end of input notification. */
0727:            public void sendEndOfInputNotifications(int entityName,
0728:                    boolean moreToFollow) throws Exception {
0729:                fDocumentScanner.endOfInput(entityName, moreToFollow);
0730:                /***
0731:                if (fScanningDTD) {
0732:                    fDTDImporter.sendEndOfInputNotifications(entityName, moreToFollow);
0733:                }
0734:                /***/
0735:            }
0736:
0737:            /** Send reader change notifications. */
0738:            public void sendReaderChangeNotifications(
0739:                    XMLEntityHandler.EntityReader reader, int readerId)
0740:                    throws Exception {
0741:                fDocumentScanner.readerChange(reader, readerId);
0742:                /***
0743:                if (fScanningDTD) {
0744:                    fDTDImporter.sendReaderChangeNotifications(reader, readerId);
0745:                }
0746:                /***/
0747:            }
0748:
0749:            /** External entity standalone check. */
0750:            public boolean externalEntityStandaloneCheck() {
0751:                return (fStandaloneReader != -1 && fValidating);
0752:            }
0753:
0754:            /** Return true if validating. */
0755:            public boolean getValidating() {
0756:                return fValidating;
0757:            }
0758:
0759:            //
0760:            // XMLEntityHandler.CharDataHandler methods
0761:            //
0762:
0763:            private String normalizeValue(String unNormalizedValue) {
0764:                fUnnormalizedStr.setLength(0);
0765:                fUnnormalizedStr.append(unNormalizedValue);
0766:                normalizeWhitespace(fUnnormalizedStr,
0767:                        (fWhiteSpace == DatatypeValidator.COLLAPSE));
0768:                return fNormalizedStr.toString();
0769:            }
0770:
0771:            /**
0772:             * Normalize whitespace in an XMLString according to the rules of attribute
0773:             * value normalization - converting all whitespace characters to space
0774:             * characters.
0775:             * In addition for attributes of type other than CDATA: trim leading and
0776:             * trailing spaces and collapse spaces (0x20 only).
0777:             *
0778:             * @param value The string to normalize.
0779:             * @returns 0 if no triming is done or if there is neither leading nor
0780:             *            trailing whitespace,
0781:             *          1 if there is only leading whitespace,
0782:             *          2 if there is only trailing whitespace,
0783:             *          3 if there is both leading and trailing whitespace.
0784:             */
0785:
0786:            private int normalizeWhitespace(StringBuffer chars, boolean collapse) {
0787:                int length = fUnnormalizedStr.length();
0788:                fNormalizedStr.setLength(0);
0789:                boolean skipSpace = collapse;
0790:                boolean sawNonWS = false;
0791:                int leading = 0;
0792:                int trailing = 0;
0793:                int c;
0794:                for (int i = 0; i < length; i++) {
0795:                    c = chars.charAt(i);
0796:                    if (c == 0x20 || c == 0x0D || c == 0x0A || c == 0x09) {
0797:                        if (!skipSpace) {
0798:                            // take the first whitespace as a space and skip the others
0799:                            fNormalizedStr.append(' ');
0800:                            skipSpace = collapse;
0801:                        }
0802:                        if (!sawNonWS) {
0803:                            // this is a leading whitespace, record it
0804:                            leading = 1;
0805:                        }
0806:                    } else {
0807:                        fNormalizedStr.append((char) c);
0808:                        skipSpace = false;
0809:                        sawNonWS = true;
0810:                    }
0811:                }
0812:                if (skipSpace) {
0813:                    c = fNormalizedStr.length();
0814:                    if (c != 0) {
0815:                        // if we finished on a space trim it but also record it
0816:                        fNormalizedStr.setLength(--c);
0817:                        trailing = 2;
0818:                    } else if (leading != 0 && !sawNonWS) {
0819:                        // if all we had was whitespace we skipped record it as
0820:                        // trailing whitespace as well
0821:                        trailing = 2;
0822:                    }
0823:                }
0824:                //value.setValues(fNormalizedStr);
0825:                return collapse ? leading + trailing : 0;
0826:            }
0827:
0828:            /** Process characters. Schema Normalization*/
0829:            public void processCharacters(char[] chars, int offset, int length)
0830:                    throws Exception {
0831:                if (DEBUG_NORMALIZATION) {
0832:                    System.out
0833:                            .println("==>processCharacters(char[] chars, int offset, int length");
0834:                }
0835:                if (fValidating) {
0836:                    if (fInElementContent
0837:                            || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
0838:                        if (DEBUG_NORMALIZATION) {
0839:                            System.out.println("==>charDataInContent()");
0840:                        }
0841:                        charDataInContent();
0842:                    }
0843:                    if (fBufferDatatype) {
0844:                        if (fFirstChunk && fGrammar != null) {
0845:                            fGrammar.getElementDecl(fCurrentElementIndex,
0846:                                    fTempElementDecl);
0847:                            fCurrentDV = fTempElementDecl.datatypeValidator;
0848:                            if (fXsiTypeValidator != null) {
0849:                                fCurrentDV = fXsiTypeValidator;
0850:                                fXsiTypeValidator = null;
0851:                            }
0852:                            if (fCurrentDV != null) {
0853:                                fWhiteSpace = fCurrentDV.getWSFacet();
0854:                            }
0855:                        }
0856:                        if (DEBUG_NORMALIZATION) {
0857:                            System.out
0858:                                    .println("Start schema datatype normalization <whiteSpace value="
0859:                                            + fWhiteSpace + ">");
0860:                        }
0861:                        if (!fNormalizeContents
0862:                                || fWhiteSpace == DatatypeValidator.PRESERVE) { //do not normalize                
0863:                            fDatatypeBuffer.append(chars, offset, length);
0864:                        } else {
0865:                            fUnnormalizedStr.setLength(0);
0866:                            fUnnormalizedStr.append(chars, offset, length);
0867:                            int spaces = normalizeWhitespace(fUnnormalizedStr,
0868:                                    (fWhiteSpace == DatatypeValidator.COLLAPSE));
0869:                            int nLength = fNormalizedStr.length();
0870:                            if (nLength > 0) {
0871:                                if (!fFirstChunk
0872:                                        && (fWhiteSpace == DatatypeValidator.COLLAPSE)
0873:                                        && fTrailing) {
0874:                                    fNormalizedStr.insert(0, ' ');
0875:                                    nLength++;
0876:                                }
0877:                                if ((length - offset) != nLength) {
0878:                                    char[] newChars = new char[nLength];
0879:                                    fNormalizedStr.getChars(0, nLength,
0880:                                            newChars, 0);
0881:                                    chars = newChars;
0882:                                    offset = 0;
0883:                                    length = nLength;
0884:                                } else {
0885:                                    fNormalizedStr.getChars(0, nLength, chars,
0886:                                            0);
0887:                                }
0888:                                fDatatypeBuffer.append(chars, offset, length);
0889:
0890:                                // call all active identity constraints
0891:                                int count = fMatcherStack.getMatcherCount();
0892:                                for (int i = 0; i < count; i++) {
0893:                                    XPathMatcher matcher = fMatcherStack
0894:                                            .getMatcherAt(i);
0895:                                    if (DEBUG_IDENTITY_CONSTRAINTS) {
0896:                                        String text = new String(chars, offset,
0897:                                                length);
0898:                                        System.out.println("<IC>: "
0899:                                                + matcher.toString()
0900:                                                + "#characters(" + text + ")");
0901:                                    }
0902:                                    matcher.characters(chars, offset, length);
0903:                                }
0904:
0905:                                fDocumentHandler.characters(chars, offset,
0906:                                        length);
0907:                            }
0908:                            fTrailing = (spaces > 1) ? true : false;
0909:                            fFirstChunk = false;
0910:                            return;
0911:                        }
0912:                    }
0913:                }
0914:
0915:                fFirstChunk = false;
0916:
0917:                // call all active identity constraints
0918:                int count = fMatcherStack.getMatcherCount();
0919:                for (int i = 0; i < count; i++) {
0920:                    XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
0921:                    if (DEBUG_IDENTITY_CONSTRAINTS) {
0922:                        String text = new String(chars, offset, length);
0923:                        System.out.println("<IC>: " + matcher.toString()
0924:                                + "#characters(" + text + ")");
0925:                    }
0926:                    matcher.characters(chars, offset, length);
0927:                }
0928:
0929:                fDocumentHandler.characters(chars, offset, length);
0930:            }
0931:
0932:            /** Process characters. */
0933:            public void processCharacters(int data) throws Exception {
0934:                if (fValidating) {
0935:                    if (fInElementContent
0936:                            || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
0937:                        charDataInContent();
0938:                    }
0939:                    if (fBufferDatatype) {
0940:                        fGrammar.getElementDecl(fCurrentElementIndex,
0941:                                fTempElementDecl);
0942:                        //REVISIT: add normalization according to datatypes
0943:                        fCurrentDV = fTempElementDecl.datatypeValidator;
0944:                        if (fXsiTypeValidator != null) {
0945:                            fCurrentDV = fXsiTypeValidator;
0946:                            fXsiTypeValidator = null;
0947:                        }
0948:                        if (fCurrentDV != null) {
0949:                            fWhiteSpace = fCurrentDV.getWSFacet();
0950:                        }
0951:                        if (!fNormalizeContents
0952:                                || fWhiteSpace == DatatypeValidator.PRESERVE) { //no normalization done
0953:                            fDatatypeBuffer.append(fStringPool.toString(data));
0954:                        } else {
0955:                            String str = fStringPool.toString(data);
0956:                            int length = str.length();
0957:                            fUnnormalizedStr.setLength(0);
0958:                            fUnnormalizedStr.append(str);
0959:                            int spaces = normalizeWhitespace(fUnnormalizedStr,
0960:                                    (fWhiteSpace == DatatypeValidator.COLLAPSE));
0961:                            if (fWhiteSpace != DatatypeValidator.PRESERVE) {
0962:                                //normalization was done.
0963:                                fStringPool.releaseString(data);
0964:                                data = fStringPool.addString(fNormalizedStr
0965:                                        .toString());
0966:                            }
0967:                            fDatatypeBuffer.append(fNormalizedStr.toString());
0968:                        }
0969:                    }
0970:                }
0971:
0972:                // call all active identity constraints
0973:                int count = fMatcherStack.getMatcherCount();
0974:                if (count > 0) {
0975:                    String text = fStringPool.toString(data);
0976:                    char[] chars = new char[text.length()];
0977:                    int offset = 0;
0978:                    int length = chars.length;
0979:                    text.getChars(offset, length, chars, offset);
0980:                    for (int i = 0; i < count; i++) {
0981:                        XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
0982:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
0983:                            System.out.println("<IC>: " + matcher.toString()
0984:                                    + "#characters(" + text + ")");
0985:                        }
0986:                        matcher.characters(chars, offset, length);
0987:                    }
0988:                }
0989:
0990:                fDocumentHandler.characters(data);
0991:            }
0992:
0993:            /** Process whitespace. */
0994:            public void processWhitespace(char[] chars, int offset, int length)
0995:                    throws Exception {
0996:
0997:                if (fInElementContent) {
0998:                    if (fStandaloneReader != -1 && fValidating
0999:                            && getElementDeclIsExternal(fCurrentElementIndex)) {
1000:                        reportRecoverableXMLError(
1001:                                XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
1002:                                XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
1003:                    }
1004:                    fDocumentHandler.ignorableWhitespace(chars, offset, length);
1005:                } else {
1006:                    if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
1007:                        charDataInContent();
1008:                    }
1009:
1010:                    // call all active identity constraints
1011:                    int count = fMatcherStack.getMatcherCount();
1012:                    for (int i = 0; i < count; i++) {
1013:                        XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
1014:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
1015:                            String text = new String(chars, offset, length);
1016:                            System.out.println("<IC>: " + matcher.toString()
1017:                                    + "#characters(" + text + ")");
1018:                        }
1019:                        matcher.characters(chars, offset, length);
1020:                    }
1021:                    if (fGrammar != null && fValidating) {
1022:
1023:                        fGrammar.getElementDecl(fCurrentElementIndex,
1024:                                fTempElementDecl);
1025:                        fCurrentDV = fTempElementDecl.datatypeValidator;
1026:                        if (fXsiTypeValidator != null) {
1027:                            fCurrentDV = fXsiTypeValidator;
1028:                            fXsiTypeValidator = null;
1029:                        }
1030:                        if (fCurrentDV != null) {
1031:                            fWhiteSpace = fCurrentDV.getWSFacet();
1032:                        }
1033:
1034:                        if (fWhiteSpace == DatatypeValidator.PRESERVE) { //do not normalize
1035:                            fDatatypeBuffer.append(chars, offset, length);
1036:                        }
1037:
1038:                    }
1039:
1040:                    fDocumentHandler.characters(chars, offset, length);
1041:                }
1042:
1043:            } // processWhitespace(char[],int,int)
1044:
1045:            /** Process whitespace. */
1046:            public void processWhitespace(int data) throws Exception {
1047:
1048:                if (fInElementContent) {
1049:                    if (fStandaloneReader != -1 && fValidating
1050:                            && getElementDeclIsExternal(fCurrentElementIndex)) {
1051:                        reportRecoverableXMLError(
1052:                                XMLMessages.MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE,
1053:                                XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION);
1054:                    }
1055:                    fDocumentHandler.ignorableWhitespace(data);
1056:                } else {
1057:                    if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
1058:                        charDataInContent();
1059:                    }
1060:
1061:                    // call all active identity constraints
1062:                    int count = fMatcherStack.getMatcherCount();
1063:                    if (count > 0) {
1064:                        String text = fStringPool.toString(data);
1065:                        char[] chars = new char[text.length()];
1066:                        int offset = 0;
1067:                        int length = chars.length;
1068:                        text.getChars(length, length, chars, offset);
1069:                        for (int i = 0; i < count; i++) {
1070:                            XPathMatcher matcher = fMatcherStack
1071:                                    .getMatcherAt(i);
1072:                            if (DEBUG_IDENTITY_CONSTRAINTS) {
1073:                                System.out.println("<IC>: "
1074:                                        + matcher.toString() + "#characters("
1075:                                        + text + ")");
1076:                            }
1077:                            matcher.characters(chars, offset, length);
1078:                        }
1079:                    }
1080:
1081:                    if (fGrammar != null && fValidating) {
1082:                        fGrammar.getElementDecl(fCurrentElementIndex,
1083:                                fTempElementDecl);
1084:                        fCurrentDV = fTempElementDecl.datatypeValidator;
1085:                        if (fXsiTypeValidator != null) {
1086:                            fCurrentDV = fXsiTypeValidator;
1087:                            fXsiTypeValidator = null;
1088:                        }
1089:                        if (fCurrentDV != null) {
1090:                            fWhiteSpace = fCurrentDV.getWSFacet();
1091:                        }
1092:                        if (fWhiteSpace == DatatypeValidator.PRESERVE) { //no normalization done
1093:                            fDatatypeBuffer.append(fStringPool.toString(data));
1094:                        }
1095:
1096:                    }
1097:                    fDocumentHandler.characters(data);
1098:                }
1099:
1100:            } // processWhitespace(int)
1101:
1102:            //
1103:            // XMLDocumentScanner.EventHandler methods
1104:            //
1105:
1106:            /** Scans element type. */
1107:            public void scanElementType(
1108:                    XMLEntityHandler.EntityReader entityReader, char fastchar,
1109:                    QName element) throws Exception {
1110:
1111:                if (!fNamespacesEnabled) {
1112:                    element.clear();
1113:                    element.localpart = entityReader.scanName(fastchar);
1114:                    element.rawname = element.localpart;
1115:                } else {
1116:                    entityReader.scanQName(fastchar, element);
1117:                    if (entityReader.lookingAtChar(':', false)) {
1118:                        fErrorReporter.reportError(fErrorReporter.getLocator(),
1119:                                XMLMessages.XML_DOMAIN,
1120:                                XMLMessages.MSG_TWO_COLONS_IN_QNAME,
1121:                                XMLMessages.P5_INVALID_CHARACTER, null,
1122:                                XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1123:                        entityReader.skipPastNmtoken(' ');
1124:                    }
1125:                }
1126:
1127:            } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
1128:
1129:            /** Scans expected element type. */
1130:            public boolean scanExpectedElementType(
1131:                    XMLEntityHandler.EntityReader entityReader, char fastchar,
1132:                    QName element) throws Exception {
1133:
1134:                if (fCurrentElementCharArrayRange == null) {
1135:                    fCurrentElementCharArrayRange = fStringPool
1136:                            .createCharArrayRange();
1137:                }
1138:                fStringPool.getCharArrayRange(fCurrentElement.rawname,
1139:                        fCurrentElementCharArrayRange);
1140:                return entityReader.scanExpectedName(fastchar,
1141:                        fCurrentElementCharArrayRange);
1142:
1143:            } // scanExpectedElementType(XMLEntityHandler.EntityReader,char,QName)
1144:
1145:            /** Scans attribute name. */
1146:            public void scanAttributeName(
1147:                    XMLEntityHandler.EntityReader entityReader, QName element,
1148:                    QName attribute) throws Exception {
1149:
1150:                if (!fSeenRootElement) {
1151:                    fSeenRootElement = true;
1152:                    rootElementSpecified(element);
1153:                    fStringPool.resetShuffleCount();
1154:                }
1155:
1156:                if (!fNamespacesEnabled) {
1157:                    attribute.clear();
1158:                    attribute.localpart = entityReader.scanName('=');
1159:                    attribute.rawname = attribute.localpart;
1160:                } else {
1161:                    entityReader.scanQName('=', attribute);
1162:                    if (entityReader.lookingAtChar(':', false)) {
1163:                        fErrorReporter.reportError(fErrorReporter.getLocator(),
1164:                                XMLMessages.XML_DOMAIN,
1165:                                XMLMessages.MSG_TWO_COLONS_IN_QNAME,
1166:                                XMLMessages.P5_INVALID_CHARACTER, null,
1167:                                XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1168:                        entityReader.skipPastNmtoken(' ');
1169:                    }
1170:                }
1171:
1172:            } // scanAttributeName(XMLEntityHandler.EntityReader,QName,QName)
1173:
1174:            /** Call start document. */
1175:            public void callStartDocument() throws Exception {
1176:
1177:                if (!fCalledStartDocument) {
1178:                    fDocumentHandler.startDocument();
1179:                    fCalledStartDocument = true;
1180:                    if (fValidating) {
1181:                        fValueStoreCache.startDocument();
1182:                    }
1183:                }
1184:            }
1185:
1186:            /** Call end document. */
1187:            public void callEndDocument() throws Exception {
1188:
1189:                if (fCalledStartDocument) {
1190:                    if (fValidating) {
1191:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
1192:                            System.out
1193:                                    .println("<IC>: ValueStoreCache#endDocument()");
1194:                        }
1195:                        fValueStoreCache.endDocument();
1196:                    }
1197:                    fDocumentHandler.endDocument();
1198:                }
1199:            }
1200:
1201:            /** Call XML declaration. */
1202:            public void callXMLDecl(int version, int encoding, int standalone)
1203:                    throws Exception {
1204:                fDocumentHandler.xmlDecl(version, encoding, standalone);
1205:            }
1206:
1207:            public void callStandaloneIsYes() throws Exception {
1208:                // standalone = "yes". said XMLDocumentScanner.
1209:                fStandaloneReader = fEntityHandler.getReaderId();
1210:
1211:            }
1212:
1213:            /** Call text declaration. */
1214:            public void callTextDecl(int version, int encoding)
1215:                    throws Exception {
1216:                fDocumentHandler.textDecl(version, encoding);
1217:            }
1218:
1219:            /**
1220:             * Signal the scanning of an element name in a start element tag.
1221:             *
1222:             * @param element Element name scanned.
1223:             */
1224:            public void element(QName element) throws Exception {
1225:                fAttrListHandle = -1;
1226:            }
1227:
1228:            /**
1229:             * Signal the scanning of an attribute associated to the previous
1230:             * start element tag.
1231:             *
1232:             * @param element Element name scanned.
1233:             * @param attrName Attribute name scanned.
1234:             * @param attrValue The string pool index of the attribute value.
1235:             */
1236:            public boolean attribute(QName element, QName attrName,
1237:                    int attrValue) throws Exception {
1238:                if (fAttrListHandle == -1) {
1239:                    fAttrListHandle = fAttrList.startAttrList();
1240:                }
1241:
1242:                // if fAttrList.addAttr returns -1, indicates duplicate att in start tag of an element.
1243:                // specified: true, search : true
1244:                return fAttrList.addAttr(attrName, attrValue, fCDATASymbol,
1245:                        true, true) == -1;
1246:            }
1247:
1248:            /** Call start element. */
1249:            public void callStartElement(QName element) throws Exception {
1250:
1251:                if (DEBUG_SCHEMA_VALIDATION)
1252:                    System.out.println("\n=======StartElement : "
1253:                            + fStringPool.toString(element.localpart));
1254:
1255:                //
1256:                // Check after all specified attrs are scanned
1257:                // (1) report error for REQUIRED attrs that are missing (V_TAGc)
1258:                // (2) report error for PROHIBITED attrs that are present (V_TAGc)
1259:                // (3) add default attrs (FIXED and NOT_FIXED)
1260:                //
1261:
1262:                if (!fSeenRootElement) {
1263:                    rootElementSpecified(element);
1264:                    fStringPool.resetShuffleCount();
1265:                }
1266:
1267:                if (fGrammar != null && fGrammarIsDTDGrammar) {
1268:                    fAttrListHandle = addDTDDefaultAttributes(element,
1269:                            fAttrList, fAttrListHandle, fValidating,
1270:                            fStandaloneReader != -1);
1271:                }
1272:
1273:                fCheckedForSchema = true;
1274:                if (fNamespacesEnabled) {
1275:                    bindNamespacesToElementAndAttributes(element, fAttrList);
1276:                }
1277:
1278:                if (fDynamicValidation && fGrammar == null) {
1279:                    fValidating = false;
1280:                }
1281:
1282:                if (!fSeenRootElement) {
1283:                    fSeenRootElement = true;
1284:                }
1285:
1286:                validateElementAndAttributes(element, fAttrList);
1287:                if (fAttrListHandle != -1) {
1288:                    //fAttrList.endAttrList();
1289:                    int dupAttrs[];
1290:                    if ((dupAttrs = fAttrList.endAttrList()) != null) {
1291:                        Object[] args = {
1292:                                fStringPool.toString(element.rawname), null };
1293:                        for (int i = 0; i < dupAttrs.length; i++) {
1294:                            args[1] = fStringPool.toString(dupAttrs[i]);
1295:                            fErrorReporter
1296:                                    .reportError(
1297:                                            fErrorReporter.getLocator(),
1298:                                            XMLMessages.XMLNS_DOMAIN,
1299:                                            XMLMessages.MSG_ATTRIBUTE_NOT_UNIQUE,
1300:                                            XMLMessages.WFC_UNIQUE_ATT_SPEC,
1301:                                            args,
1302:                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1303:                        }
1304:                    }
1305:                }
1306:
1307:                // activate identity constraints
1308:                if (fValidating && fGrammar != null && fGrammarIsSchemaGrammar) {
1309:                    if (DEBUG_IDENTITY_CONSTRAINTS) {
1310:                        System.out.println("<IC>: pushing context - element: "
1311:                                + fStringPool.toString(element.rawname));
1312:                    }
1313:                    fValueStoreCache.startElement();
1314:                    fMatcherStack.pushContext();
1315:                    int eindex = fGrammar.getElementDeclIndex(element, -1);
1316:                    if (eindex != -1) {
1317:                        fGrammar.getElementDecl(eindex, fTempElementDecl);
1318:                        fValueStoreCache.initValueStoresFor(fTempElementDecl);
1319:                        int uCount = fTempElementDecl.unique.size();
1320:                        for (int i = 0; i < uCount; i++) {
1321:                            activateSelectorFor((IdentityConstraint) fTempElementDecl.unique
1322:                                    .elementAt(i));
1323:                        }
1324:                        int kCount = fTempElementDecl.key.size();
1325:                        for (int i = 0; i < kCount; i++) {
1326:                            activateSelectorFor((IdentityConstraint) fTempElementDecl.key
1327:                                    .elementAt(i));
1328:                        }
1329:                        int krCount = fTempElementDecl.keyRef.size();
1330:                        for (int i = 0; i < krCount; i++) {
1331:                            activateSelectorFor((IdentityConstraint) fTempElementDecl.keyRef
1332:                                    .elementAt(i));
1333:                        }
1334:                    }
1335:
1336:                    // call all active identity constraints
1337:                    int count = fMatcherStack.getMatcherCount();
1338:                    for (int i = 0; i < count; i++) {
1339:                        XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
1340:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
1341:                            System.out.println("<IC>: " + matcher.toString()
1342:                                    + "#startElement("
1343:                                    + fStringPool.toString(element.rawname)
1344:                                    + ")");
1345:                        }
1346:                        matcher.startElement(element, fAttrList,
1347:                                fAttrListHandle, fCurrentElementIndex,
1348:                                (SchemaGrammar) fGrammar);
1349:                    }
1350:                }
1351:
1352:                // call handler
1353:                fDocumentHandler.startElement(element, fAttrList,
1354:                        fAttrListHandle);
1355:                fElementDepth++;
1356:                fAttrListHandle = -1;
1357:
1358:                //if (fElementDepth >= 0) {
1359:                // REVISIT: Why are doing anything if the grammar is null? -Ac
1360:                if (fValidating) {
1361:                    // push current length onto stack
1362:                    if (fElementChildrenOffsetStack.length <= fElementDepth) {
1363:                        int newarray[] = new int[fElementChildrenOffsetStack.length * 2];
1364:                        System
1365:                                .arraycopy(fElementChildrenOffsetStack, 0,
1366:                                        newarray, 0,
1367:                                        fElementChildrenOffsetStack.length);
1368:                        fElementChildrenOffsetStack = newarray;
1369:                    }
1370:                    fElementChildrenOffsetStack[fElementDepth] = fElementChildrenLength;
1371:
1372:                    // add this element to children
1373:                    if (fElementChildren.length <= fElementChildrenLength) {
1374:                        QName[] newarray = new QName[fElementChildrenLength * 2];
1375:                        System.arraycopy(fElementChildren, 0, newarray, 0,
1376:                                fElementChildren.length);
1377:                        fElementChildren = newarray;
1378:                    }
1379:                    QName qname = fElementChildren[fElementChildrenLength];
1380:                    if (qname == null) {
1381:                        for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
1382:                            fElementChildren[i] = new QName();
1383:                        }
1384:                        qname = fElementChildren[fElementChildrenLength];
1385:                    }
1386:                    qname.setValues(element);
1387:                    fElementChildrenLength++;
1388:
1389:                    if (DEBUG_ELEMENT_CHILDREN) {
1390:                        printChildren();
1391:                        printStack();
1392:                    }
1393:
1394:                }
1395:
1396:                ensureStackCapacity(fElementDepth);
1397:                fCurrentElement.setValues(element);
1398:                fCurrentElementEntity = fEntityHandler.getReaderId();
1399:
1400:                fElementQNamePartsStack[fElementDepth]
1401:                        .setValues(fCurrentElement);
1402:
1403:                fElementEntityStack[fElementDepth] = fCurrentElementEntity;
1404:                fElementIndexStack[fElementDepth] = fCurrentElementIndex;
1405:                fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
1406:
1407:                if (fNeedValidationOff) {
1408:                    fValidating = false;
1409:                    fNeedValidationOff = false;
1410:                }
1411:
1412:                if (fValidating && fGrammarIsSchemaGrammar) {
1413:                    pushContentLeafStack();
1414:                } else {
1415:                    fContentModelStateStack[fElementDepth] = -2;
1416:                }
1417:
1418:                fValidationFlagStack[fElementDepth] = fValidating ? 0 : -1;
1419:
1420:                fScopeStack[fElementDepth] = fCurrentScope;
1421:                fGrammarNameSpaceIndexStack[fElementDepth] = fGrammarNameSpaceIndex;
1422:
1423:            } // callStartElement(QName)
1424:
1425:            private void activateSelectorFor(IdentityConstraint ic)
1426:                    throws Exception {
1427:                Selector selector = ic.getSelector();
1428:                if (DEBUG_IDENTITY_CONSTRAINTS) {
1429:                    System.out
1430:                            .println("<IC>: XMLValidator#activateSelectorFor("
1431:                                    + selector + ')');
1432:                }
1433:                FieldActivator activator = this ;
1434:                if (selector == null)
1435:                    return;
1436:                XPathMatcher matcher = selector.createMatcher(activator);
1437:                fMatcherStack.addMatcher(matcher);
1438:                if (DEBUG_IDENTITY_CONSTRAINTS) {
1439:                    System.out.println("<IC>: " + matcher
1440:                            + "#startDocumentFragment()");
1441:                }
1442:                matcher.startDocumentFragment(fStringPool);
1443:            }
1444:
1445:            private void pushContentLeafStack() throws Exception {
1446:                int contentType = getContentSpecType(fCurrentElementIndex);
1447:                if (contentType == XMLElementDecl.TYPE_CHILDREN
1448:                        || contentType == XMLElementDecl.TYPE_MIXED_COMPLEX) {
1449:                    XMLContentModel cm = getElementContentModel(fCurrentElementIndex);
1450:                    ContentLeafNameTypeVector cv = cm
1451:                            .getContentLeafNameTypeVector();
1452:                    if (cm != null) {
1453:                        fContentLeafStack[fElementDepth] = cv;
1454:                        //OTWI: on-the-way-in
1455:                        fContentModelStack[fElementDepth] = cm;
1456:                        // for DFA with wildcard, we validate on-the-way-in
1457:                        // for other content models, we do it on-the-way-out
1458:                        if (cm instanceof  DFAContentModel && cv != null)
1459:                            fContentModelStateStack[fElementDepth] = 0;
1460:                        else
1461:                            fContentModelStateStack[fElementDepth] = -2;
1462:                        fContentModelEleCount[fElementDepth] = 0;
1463:                    }
1464:                } else {
1465:                    fContentModelStateStack[fElementDepth] = -2;
1466:                }
1467:            }
1468:
1469:            private void ensureStackCapacity(int newElementDepth) {
1470:
1471:                if (newElementDepth == fElementQNamePartsStack.length) {
1472:                    int[] newStack = new int[newElementDepth * 2];
1473:                    System.arraycopy(fScopeStack, 0, newStack, 0,
1474:                            newElementDepth);
1475:                    fScopeStack = newStack;
1476:
1477:                    newStack = new int[newElementDepth * 2];
1478:                    System.arraycopy(fGrammarNameSpaceIndexStack, 0, newStack,
1479:                            0, newElementDepth);
1480:                    fGrammarNameSpaceIndexStack = newStack;
1481:
1482:                    QName[] newStackOfQueue = new QName[newElementDepth * 2];
1483:                    System.arraycopy(this .fElementQNamePartsStack, 0,
1484:                            newStackOfQueue, 0, newElementDepth);
1485:                    fElementQNamePartsStack = newStackOfQueue;
1486:
1487:                    QName qname = fElementQNamePartsStack[newElementDepth];
1488:                    if (qname == null) {
1489:                        for (int i = newElementDepth; i < fElementQNamePartsStack.length; i++) {
1490:                            fElementQNamePartsStack[i] = new QName();
1491:                        }
1492:                    }
1493:
1494:                    newStack = new int[newElementDepth * 2];
1495:                    System.arraycopy(fElementEntityStack, 0, newStack, 0,
1496:                            newElementDepth);
1497:                    fElementEntityStack = newStack;
1498:
1499:                    newStack = new int[newElementDepth * 2];
1500:                    System.arraycopy(fElementIndexStack, 0, newStack, 0,
1501:                            newElementDepth);
1502:                    fElementIndexStack = newStack;
1503:
1504:                    newStack = new int[newElementDepth * 2];
1505:                    System.arraycopy(fContentSpecTypeStack, 0, newStack, 0,
1506:                            newElementDepth);
1507:                    fContentSpecTypeStack = newStack;
1508:
1509:                    newStack = new int[newElementDepth * 2];
1510:                    System.arraycopy(fValidationFlagStack, 0, newStack, 0,
1511:                            newElementDepth);
1512:                    fValidationFlagStack = newStack;
1513:
1514:                    ContentLeafNameTypeVector[] newStackV = new ContentLeafNameTypeVector[newElementDepth * 2];
1515:                    System.arraycopy(fContentLeafStack, 0, newStackV, 0,
1516:                            newElementDepth);
1517:                    fContentLeafStack = newStackV;
1518:
1519:                    //OTWI: on-the-way-in
1520:                    XMLContentModel[] newStackCM = new XMLContentModel[newElementDepth * 2];
1521:                    System.arraycopy(fContentModelStack, 0, newStackCM, 0,
1522:                            newElementDepth);
1523:                    fContentModelStack = newStackCM;
1524:                    newStack = new int[newElementDepth * 2];
1525:                    System.arraycopy(fContentModelStateStack, 0, newStack, 0,
1526:                            newElementDepth);
1527:                    fContentModelStateStack = newStack;
1528:                    newStack = new int[newElementDepth * 2];
1529:                    System.arraycopy(fContentModelEleCount, 0, newStack, 0,
1530:                            newElementDepth);
1531:                    fContentModelEleCount = newStack;
1532:                }
1533:            }
1534:
1535:            /** Call end element. */
1536:            public void callEndElement(int readerId) throws Exception {
1537:                if (DEBUG_SCHEMA_VALIDATION)
1538:                    System.out.println("=======EndElement : "
1539:                            + fStringPool.toString(fCurrentElement.localpart)
1540:                            + "\n");
1541:
1542:                int prefixIndex = fCurrentElement.prefix;
1543:                int elementType = fCurrentElement.rawname;
1544:
1545:                if (fCurrentElementEntity != readerId) {
1546:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
1547:                            XMLMessages.XML_DOMAIN,
1548:                            XMLMessages.MSG_ELEMENT_ENTITY_MISMATCH,
1549:                            XMLMessages.P78_NOT_WELLFORMED,
1550:                            new Object[] { fStringPool.toString(elementType) },
1551:                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1552:                }
1553:
1554:                fElementDepth--;
1555:                if (fValidating) {
1556:                    int elementIndex = fCurrentElementIndex;
1557:                    if (elementIndex != -1 && fCurrentContentSpecType != -1) {
1558:                        QName children[] = fElementChildren;
1559:                        int childrenOffset = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
1560:                        int childrenLength = fElementChildrenLength
1561:                                - childrenOffset;
1562:                        if (DEBUG_ELEMENT_CHILDREN) {
1563:                            System.out.println("endElement("
1564:                                    + fStringPool
1565:                                            .toString(fCurrentElement.rawname)
1566:                                    + ')');
1567:                            System.out.println("fCurrentContentSpecType : "
1568:                                    + fCurrentContentSpecType);
1569:                            System.out.print("offset: ");
1570:                            System.out.print(childrenOffset);
1571:                            System.out.print(", length: ");
1572:                            System.out.print(childrenLength);
1573:                            System.out.println();
1574:                            printChildren();
1575:                            printStack();
1576:                        }
1577:                        int result = checkContent(elementIndex, children,
1578:                                childrenOffset, childrenLength);
1579:                        fCurrentDV = null;
1580:
1581:                        if (DEBUG_SCHEMA_VALIDATION)
1582:                            System.out
1583:                                    .println("!!!!!!!!In XMLValidator, the return value from checkContent : "
1584:                                            + result);
1585:
1586:                        if (result != -1) {
1587:                            int majorCode = result != childrenLength ? XMLMessages.MSG_CONTENT_INVALID
1588:                                    : XMLMessages.MSG_CONTENT_INCOMPLETE;
1589:                            fGrammar.getElementDecl(elementIndex,
1590:                                    fTempElementDecl);
1591:                            if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
1592:                                reportRecoverableXMLError(majorCode, 0,
1593:                                        fStringPool.toString(elementType),
1594:                                        "EMPTY");
1595:                            } else
1596:                                reportRecoverableXMLError(
1597:                                        majorCode,
1598:                                        0,
1599:                                        fStringPool.toString(elementType),
1600:                                        XMLContentSpec
1601:                                                .toString(
1602:                                                        fGrammar,
1603:                                                        fStringPool,
1604:                                                        fTempElementDecl.contentSpecIndex));
1605:                        }
1606:                    }
1607:                    fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
1608:
1609:                    // call matchers and de-activate context
1610:                    if (fGrammarIsSchemaGrammar) {
1611:                        int oldCount = fMatcherStack.getMatcherCount();
1612:                        for (int i = oldCount - 1; i >= 0; i--) {
1613:                            XPathMatcher matcher = fMatcherStack
1614:                                    .getMatcherAt(i);
1615:                            if (DEBUG_IDENTITY_CONSTRAINTS) {
1616:                                System.out
1617:                                        .println("<IC>: "
1618:                                                + matcher
1619:                                                + "#endElement("
1620:                                                + fStringPool
1621:                                                        .toString(fCurrentElement.rawname)
1622:                                                + ")");
1623:                            }
1624:                            matcher.endElement(fCurrentElement,
1625:                                    fCurrentElementIndex,
1626:                                    (SchemaGrammar) fGrammar);
1627:                        }
1628:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
1629:                            System.out
1630:                                    .println("<IC>: popping context - element: "
1631:                                            + fStringPool
1632:                                                    .toString(fCurrentElement.rawname));
1633:                        }
1634:                        if (fMatcherStack.size() > 0) {
1635:                            fMatcherStack.popContext();
1636:                        }
1637:                        int newCount = fMatcherStack.getMatcherCount();
1638:                        // handle everything *but* keyref's.
1639:                        for (int i = oldCount - 1; i >= newCount; i--) {
1640:                            XPathMatcher matcher = fMatcherStack
1641:                                    .getMatcherAt(i);
1642:                            IdentityConstraint id;
1643:                            if ((id = matcher.getIDConstraint()) != null
1644:                                    && id.getType() != IdentityConstraint.KEYREF) {
1645:                                if (DEBUG_IDENTITY_CONSTRAINTS) {
1646:                                    System.out.println("<IC>: " + matcher
1647:                                            + "#endDocumentFragment()");
1648:                                }
1649:                                matcher.endDocumentFragment();
1650:                                fValueStoreCache.transplant(id);
1651:                            } else if (id == null)
1652:                                matcher.endDocumentFragment();
1653:                        }
1654:                        // now handle keyref's/...
1655:                        for (int i = oldCount - 1; i >= newCount; i--) {
1656:                            XPathMatcher matcher = fMatcherStack
1657:                                    .getMatcherAt(i);
1658:                            IdentityConstraint id;
1659:                            if ((id = matcher.getIDConstraint()) != null
1660:                                    && id.getType() == IdentityConstraint.KEYREF) {
1661:                                if (DEBUG_IDENTITY_CONSTRAINTS) {
1662:                                    System.out.println("<IC>: " + matcher
1663:                                            + "#endDocumentFragment()");
1664:                                }
1665:                                ValueStoreBase values = fValueStoreCache
1666:                                        .getValueStoreFor(id);
1667:                                if (values != null) // nothing to do if nothing matched!
1668:                                    values.endDocumentFragment();
1669:                                matcher.endDocumentFragment();
1670:                            }
1671:                        }
1672:                        fValueStoreCache.endElement();
1673:                    }
1674:                }
1675:                fDocumentHandler.endElement(fCurrentElement);
1676:                if (fNamespacesEnabled) {
1677:                    fNamespacesScope.decreaseDepth();
1678:                }
1679:
1680:                // now pop this element off the top of the element stack
1681:                //if (fElementDepth-- < 0) {
1682:                if (fElementDepth < -1) {
1683:                    throw new RuntimeException("FWK008 Element stack underflow");
1684:                }
1685:                if (fElementDepth < 0) {
1686:                    fCurrentElement.clear();
1687:                    fCurrentElementEntity = -1;
1688:                    fCurrentElementIndex = -1;
1689:                    fCurrentContentSpecType = -1;
1690:                    fInElementContent = false;
1691:                    //
1692:                    // Check after document is fully parsed
1693:                    // (1) check that there was an element with a matching id for every
1694:                    //   IDREF and IDREFS attr (V_IDREF0)
1695:                    //
1696:                    if (fValidating) {
1697:                        try {
1698:                            this .fValIDRef.validate(null, this .fCheckIDRef); //Do final IDREF validation round
1699:                            this .fIdDefs.clear();
1700:                            this .fIdREFDefs.clear();
1701:                        } catch (InvalidDatatypeValueException ex) {
1702:                            reportRecoverableXMLError(ex.getMajorCode(), ex
1703:                                    .getMinorCode(), ex.getMessage());
1704:                        }
1705:                    }
1706:                    return;
1707:                }
1708:
1709:                //restore enclosing element to all the "current" variables
1710:                // REVISIT: Validation. This information needs to be stored.
1711:                fCurrentElement.prefix = -1;
1712:
1713:                if (fNamespacesEnabled) { //If Namespace enable then localName != rawName
1714:                    fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].localpart;
1715:                } else {//REVISIT - jeffreyr - This is so we still do old behavior when namespace is off
1716:                    fCurrentElement.localpart = fElementQNamePartsStack[fElementDepth].rawname;
1717:                }
1718:                fCurrentElement.rawname = fElementQNamePartsStack[fElementDepth].rawname;
1719:                fCurrentElement.uri = fElementQNamePartsStack[fElementDepth].uri;
1720:                fCurrentElement.prefix = fElementQNamePartsStack[fElementDepth].prefix;
1721:
1722:                fCurrentElementEntity = fElementEntityStack[fElementDepth];
1723:                fCurrentElementIndex = fElementIndexStack[fElementDepth];
1724:                fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
1725:
1726:                fValidating = fValidationFlagStack[fElementDepth] == 0 ? true
1727:                        : false;
1728:
1729:                fCurrentScope = fScopeStack[fElementDepth];
1730:
1731:                if (DEBUG_SCHEMA_VALIDATION) {
1732:
1733:                    System.out
1734:                            .println("+++++ currentElement : "
1735:                                    + fStringPool.toString(elementType)
1736:                                    + "\n fCurrentElementIndex : "
1737:                                    + fCurrentElementIndex
1738:                                    + "\n fCurrentScope : "
1739:                                    + fCurrentScope
1740:                                    + "\n fCurrentContentSpecType : "
1741:                                    + fCurrentContentSpecType
1742:                                    + "\n++++++++++++++++++++++++++++++++++++++++++++++++");
1743:                }
1744:
1745:                // if enclosing element's Schema is different, need to switch "context"
1746:                if (fGrammarNameSpaceIndex != fGrammarNameSpaceIndexStack[fElementDepth]) {
1747:
1748:                    fGrammarNameSpaceIndex = fGrammarNameSpaceIndexStack[fElementDepth];
1749:                    if (fValidating && fGrammarIsSchemaGrammar)
1750:                        if (fGrammarNameSpaceIndex < StringPool.EMPTY_STRING) {
1751:                            fGrammar = null;
1752:                            fGrammarIsSchemaGrammar = false;
1753:                            fGrammarIsDTDGrammar = false;
1754:                        } else if (!switchGrammar(fGrammarNameSpaceIndex)) {
1755:                            reportRecoverableXMLError(
1756:                                    XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
1757:                                    XMLMessages.SCHEMA_GENERIC_ERROR,
1758:                                    "Grammar with uri: "
1759:                                            + fStringPool
1760:                                                    .toString(fGrammarNameSpaceIndex)
1761:                                            + " , can not be found; possible mismatch between instance document's namespace and that of schema");
1762:                        }
1763:                }
1764:
1765:                if (fValidating) {
1766:                    fBufferDatatype = false;
1767:                }
1768:                fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
1769:
1770:            } // callEndElement(int)
1771:
1772:            /** Call start CDATA section. */
1773:            public void callStartCDATA() throws Exception {
1774:                if (fValidating && fInElementContent) {
1775:                    charDataInContent();
1776:                }
1777:                fDocumentHandler.startCDATA();
1778:            }
1779:
1780:            /** Call end CDATA section. */
1781:            public void callEndCDATA() throws Exception {
1782:                fDocumentHandler.endCDATA();
1783:            }
1784:
1785:            /** Call characters. */
1786:            public void callCharacters(int ch) throws Exception {
1787:
1788:                if (fCharRefData == null) {
1789:                    fCharRefData = new char[2];
1790:                }
1791:                int count = (ch < 0x10000) ? 1 : 2;
1792:                if (count == 1) {
1793:                    fCharRefData[0] = (char) ch;
1794:                } else {
1795:                    fCharRefData[0] = (char) (((ch - 0x00010000) >> 10) + 0xd800);
1796:                    fCharRefData[1] = (char) (((ch - 0x00010000) & 0x3ff) + 0xdc00);
1797:                }
1798:                if (fValidating
1799:                        && (fInElementContent || fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY)) {
1800:                    charDataInContent();
1801:                }
1802:                if (fValidating) {
1803:                    if (fBufferDatatype) {
1804:                        fDatatypeBuffer.append(fCharRefData, 0, 1);
1805:                    }
1806:                }
1807:
1808:                // call all active identity constraints
1809:                int matcherCount = fMatcherStack.getMatcherCount();
1810:                for (int i = 0; i < matcherCount; i++) {
1811:                    XPathMatcher matcher = fMatcherStack.getMatcherAt(i);
1812:                    if (DEBUG_IDENTITY_CONSTRAINTS) {
1813:                        String text = new String(fCharRefData, 0, count);
1814:                        System.out.println("<IC>: " + matcher.toString()
1815:                                + "#characters(" + text + ")");
1816:                    }
1817:                    matcher.characters(fCharRefData, 0, count);
1818:                }
1819:
1820:                if (fSendCharDataAsCharArray) {
1821:                    fDocumentHandler.characters(fCharRefData, 0, count);
1822:                } else {
1823:                    int index = fStringPool.addString(new String(fCharRefData,
1824:                            0, count));
1825:                    fDocumentHandler.characters(index);
1826:                }
1827:            } // callCharacters(int)
1828:
1829:            /** Call processing instruction. */
1830:            public void callProcessingInstruction(int target, int data)
1831:                    throws Exception {
1832:                fDocumentHandler.processingInstruction(target, data);
1833:            }
1834:
1835:            /** Call comment. */
1836:            public void callComment(int comment) throws Exception {
1837:                fDocumentHandler.comment(comment);
1838:            }
1839:
1840:            //
1841:            // NamespacesScope.NamespacesHandler methods
1842:            //
1843:
1844:            /** Start a new namespace declaration scope. */
1845:            public void startNamespaceDeclScope(int prefix, int uri)
1846:                    throws Exception {
1847:                fDocumentHandler.startNamespaceDeclScope(prefix, uri);
1848:            }
1849:
1850:            /** End a namespace declaration scope. */
1851:            public void endNamespaceDeclScope(int prefix) throws Exception {
1852:                fDocumentHandler.endNamespaceDeclScope(prefix);
1853:            }
1854:
1855:            // attributes
1856:
1857:            // other
1858:
1859:            /** Sets the root element. */
1860:            public void setRootElementType(QName rootElement) {
1861:                fRootElement.setValues(rootElement);
1862:            }
1863:
1864:            /**
1865:             * Returns true if the element declaration is external.
1866:             * <p>
1867:             * <strong>Note:</strong> This method is primarilly useful for
1868:             * DTDs with internal and external subsets.
1869:             */
1870:            private boolean getElementDeclIsExternal(int elementIndex) {
1871:                /*if (elementIndex < 0 || elementIndex >= fElementCount) {
1872:                    return false;
1873:                }
1874:                int chunk = elementIndex >> CHUNK_SHIFT;
1875:                int index = elementIndex & CHUNK_MASK;
1876:                return (fElementDeclIsExternal[chunk][index] != 0);
1877:                 */
1878:
1879:                if (fGrammarIsDTDGrammar) {
1880:                    return ((DTDGrammar) fGrammar)
1881:                            .getElementDeclIsExternal(elementIndex);
1882:                }
1883:                return false;
1884:            }
1885:
1886:            /** Returns the content spec type for an element index. */
1887:            public int getContentSpecType(int elementIndex) {
1888:
1889:                int contentSpecType = -1;
1890:                if (elementIndex > -1) {
1891:                    if (fGrammar.getElementDecl(elementIndex, fTempElementDecl)) {
1892:                        contentSpecType = fTempElementDecl.type;
1893:                    }
1894:                }
1895:                return contentSpecType;
1896:            }
1897:
1898:            /** Returns the content spec handle for an element index. */
1899:            public int getContentSpecHandle(int elementIndex) {
1900:                int contentSpecHandle = -1;
1901:                if (elementIndex > -1) {
1902:                    if (fGrammar.getElementDecl(elementIndex, fTempElementDecl)) {
1903:                        contentSpecHandle = fTempElementDecl.contentSpecIndex;
1904:                    }
1905:                }
1906:                return contentSpecHandle;
1907:            }
1908:
1909:            //
1910:            // Protected methods
1911:            //
1912:
1913:            // error reporting
1914:
1915:            /** Report a recoverable schema error. */
1916:            private void reportSchemaError(int code, Object[] args)
1917:                    throws Exception {
1918:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1919:                        SchemaMessageProvider.SCHEMA_DOMAIN, code,
1920:                        SchemaMessageProvider.MSG_NONE, args,
1921:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1922:            } // reportSchemaError(int,Object)
1923:
1924:            /** Report a recoverable xml error. */
1925:            protected void reportRecoverableXMLError(int majorCode,
1926:                    int minorCode) throws Exception {
1927:
1928:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1929:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, null,
1930:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1931:
1932:            } // reportRecoverableXMLError(int,int)
1933:
1934:            /** Report a recoverable xml error. */
1935:            protected void reportRecoverableXMLError(int majorCode,
1936:                    int minorCode, int stringIndex1) throws Exception {
1937:
1938:                Object[] args = { fStringPool.toString(stringIndex1) };
1939:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1940:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
1941:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1942:
1943:            } // reportRecoverableXMLError(int,int,int)
1944:
1945:            /** Report a recoverable xml error. */
1946:            protected void reportRecoverableXMLError(int majorCode,
1947:                    int minorCode, String string1) throws Exception {
1948:
1949:                Object[] args = { string1 };
1950:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1951:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
1952:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1953:
1954:            } // reportRecoverableXMLError(int,int,String)
1955:
1956:            /** Report a recoverable xml error. */
1957:            protected void reportRecoverableXMLError(int majorCode,
1958:                    int minorCode, int stringIndex1, int stringIndex2)
1959:                    throws Exception {
1960:
1961:                Object[] args = { fStringPool.toString(stringIndex1),
1962:                        fStringPool.toString(stringIndex2) };
1963:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1964:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
1965:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1966:
1967:            } // reportRecoverableXMLError(int,int,int,int)
1968:
1969:            /** Report a recoverable xml error. */
1970:            protected void reportRecoverableXMLError(int majorCode,
1971:                    int minorCode, String string1, String string2)
1972:                    throws Exception {
1973:
1974:                Object[] args = { string1, string2 };
1975:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1976:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
1977:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1978:
1979:            } // reportRecoverableXMLError(int,int,String,String)
1980:
1981:            /** Report a recoverable xml error. */
1982:            protected void reportRecoverableXMLError(int majorCode,
1983:                    int minorCode, String string1, String string2,
1984:                    String string3) throws Exception {
1985:
1986:                Object[] args = { string1, string2, string3 };
1987:                fErrorReporter.reportError(fErrorReporter.getLocator(),
1988:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
1989:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1990:
1991:            } // reportRecoverableXMLError(int,int,String,String,String)
1992:
1993:            // content spec
1994:
1995:            /**
1996:             * Returns information about which elements can be placed at a particular point
1997:             * in the passed element's content model.
1998:             * <p>
1999:             * Note that the incoming content model to test must be valid at least up to
2000:             * the insertion point. If not, then -1 will be returned and the info object
2001:             * will not have been filled in.
2002:             * <p>
2003:             * If, on return, the info.isValidEOC flag is set, then the 'insert after'
2004:             * elemement is a valid end of content, i.e. nothing needs to be inserted
2005:             * after it to make the parent element's content model valid.
2006:             *
2007:             * @param elementIndex The index within the <code>ElementDeclPool</code> of the
2008:             *                     element which is being querying.
2009:             * @param fullyValid Only return elements that can be inserted and still
2010:             *                   maintain the validity of subsequent elements past the
2011:             *                   insertion point (if any).  If the insertion point is at
2012:             *                   the end, and this is true, then only elements that can
2013:             *                   be legal final states will be returned.
2014:             * @param info An object that contains the required input data for the method,
2015:             *             and which will contain the output information if successful.
2016:             *
2017:             * @return The value -1 if fully valid, else the 0 based index of the child
2018:             *         that first failed before the insertion point. If the value
2019:             *         returned is equal to the number of children, then the specified
2020:             *         children are valid but additional content is required to reach a
2021:             *         valid ending state.
2022:             *
2023:             * @exception Exception Thrown on error.
2024:             *
2025:             * @see InsertableElementsInfo
2026:             */
2027:            protected int whatCanGoHere(int elementIndex, boolean fullyValid,
2028:                    InsertableElementsInfo info) throws Exception {
2029:
2030:                //
2031:                //  Do some basic sanity checking on the info packet. First, make sure
2032:                //  that insertAt is not greater than the child count. It can be equal,
2033:                //  which means to get appendable elements, but not greater. Or, if
2034:                //  the current children array is null, that's bad too.
2035:                //
2036:                //  Since the current children array must have a blank spot for where
2037:                //  the insert is going to be, the child count must always be at least
2038:                //  one.
2039:                //
2040:                //  Make sure that the child count is not larger than the current children
2041:                //  array. It can be equal, which means get appendable elements, but not
2042:                //  greater.
2043:                //
2044:                if (info.insertAt > info.childCount || info.curChildren == null
2045:                        || info.childCount < 1
2046:                        || info.childCount > info.curChildren.length) {
2047:                    fErrorReporter
2048:                            .reportError(
2049:                                    fErrorReporter.getLocator(),
2050:                                    ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
2051:                                    ImplementationMessages.VAL_WCGHI, 0, null,
2052:                                    XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
2053:                }
2054:
2055:                int retVal = 0;
2056:                try {
2057:                    // Get the content model for this element
2058:                    final XMLContentModel cmElem = getElementContentModel(elementIndex);
2059:
2060:                    // And delegate this call to it
2061:                    retVal = cmElem.whatCanGoHere(fullyValid, info);
2062:                } catch (CMException excToCatch) {
2063:                    // REVISIT - Translate caught error to the protected error handler interface
2064:                    int majorCode = excToCatch.getErrorCode();
2065:                    fErrorReporter
2066:                            .reportError(
2067:                                    fErrorReporter.getLocator(),
2068:                                    ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
2069:                                    majorCode, 0, null,
2070:                                    XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
2071:                    throw excToCatch;
2072:                }
2073:                return retVal;
2074:
2075:            } // whatCanGoHere(int,boolean,InsertableElementsInfo):int
2076:
2077:            // attribute information
2078:
2079:            /** Protected for use by AttributeValidator classes. */
2080:            protected boolean getAttDefIsExternal(QName element, QName attribute) {
2081:                int attDefIndex = getAttDef(element, attribute);
2082:                if (fGrammarIsDTDGrammar) {
2083:                    return ((DTDGrammar) fGrammar)
2084:                            .getAttributeDeclIsExternal(attDefIndex);
2085:                }
2086:                return false;
2087:            }
2088:
2089:            //
2090:            // Private methods
2091:            //
2092:
2093:            // other
2094:
2095:            /** Returns true if using a standalone reader. */
2096:            private boolean usingStandaloneReader() {
2097:                return fStandaloneReader == -1
2098:                        || fEntityHandler.getReaderId() == fStandaloneReader;
2099:            }
2100:
2101:            /** Returns a locator implementation. */
2102:            private LocatorImpl getLocatorImpl(LocatorImpl fillin) {
2103:
2104:                Locator here = fErrorReporter.getLocator();
2105:                if (fillin == null)
2106:                    return new LocatorImpl(here);
2107:                fillin.setPublicId(here.getPublicId());
2108:                fillin.setSystemId(here.getSystemId());
2109:                fillin.setLineNumber(here.getLineNumber());
2110:                fillin.setColumnNumber(here.getColumnNumber());
2111:                return fillin;
2112:
2113:            } // getLocatorImpl(LocatorImpl):LocatorImpl
2114:
2115:            // initialization
2116:
2117:            /** Reset pool. */
2118:            private void poolReset() {
2119:                if (fValidating) { // - el
2120:                    this .fIdDefs.clear();
2121:                    this .fIdREFDefs.clear();
2122:                }
2123:            } // poolReset()
2124:
2125:            /** Reset common. */
2126:            private void resetCommon(StringPool stringPool) throws Exception {
2127:
2128:                fStringPool = stringPool;
2129:                fValidateEntity.setDatatypeObject(new Object[] {
2130:                        fEntityHandler, stringPool });
2131:                fValidating = fValidationEnabled;
2132:                fValidationEnabledByDynamic = false;
2133:                fDynamicDisabledByValidation = false;
2134:                fNormalizeContents = false;
2135:                poolReset();
2136:                fCalledStartDocument = false;
2137:                fStandaloneReader = -1;
2138:                fElementChildrenLength = 0;
2139:                fElementDepth = -1;
2140:                fSeenRootElement = false;
2141:                fSeenDoctypeDecl = false;
2142:                fNamespacesScope = null;
2143:                fNamespacesPrefix = -1;
2144:                fRootElement.clear();
2145:                fAttrListHandle = -1;
2146:                fCheckedForSchema = false;
2147:
2148:                fCurrentScope = TOP_LEVEL_SCOPE;
2149:                fCurrentSchemaURI = StringPool.EMPTY_STRING;
2150:                fEmptyURI = StringPool.EMPTY_STRING;
2151:                fXsiPrefix = -1;
2152:                fXsiTypeValidator = null;
2153:
2154:                // xsi:nill
2155:                fNil = false;
2156:
2157:                fGrammar = null;
2158:                fGrammarNameSpaceIndex = StringPool.EMPTY_STRING;
2159:
2160:                // we reset fGrammarResolver in XMLParser before passing it to Validator
2161:                fSGComparator = null;
2162:                fGrammarIsDTDGrammar = false;
2163:                fGrammarIsSchemaGrammar = false;
2164:
2165:                //Normalization
2166:                fCurrentDV = null;
2167:                fFirstChunk = true;
2168:                fTrailing = false;
2169:                fWhiteSpace = DatatypeValidator.COLLAPSE;
2170:
2171:                fMatcherStack.clear();
2172:
2173:                UPACheckedGrammarURIs.clear();
2174:                //REVISIT: fExternalSchemas/fExternalNoNamespaceSchema is not reset 'cause we don't have grammar cashing in Xerces-J
2175:                //         reconsider implementation when we have grammar chashing
2176:                //
2177:                init();
2178:
2179:            } // resetCommon(StringPool)
2180:
2181:            /** Initialize. */
2182:            private void init() {
2183:
2184:                fEmptyURI = fStringPool.addSymbol("");
2185:                fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
2186:
2187:                fEMPTYSymbol = fStringPool.addSymbol("EMPTY");
2188:                fANYSymbol = fStringPool.addSymbol("ANY");
2189:                fMIXEDSymbol = fStringPool.addSymbol("MIXED");
2190:                fCHILDRENSymbol = fStringPool.addSymbol("CHILDREN");
2191:
2192:                fCDATASymbol = fStringPool.addSymbol("CDATA");
2193:                fIDSymbol = fStringPool.addSymbol("ID");
2194:                fIDREFSymbol = fStringPool.addSymbol("IDREF");
2195:                fIDREFSSymbol = fStringPool.addSymbol("IDREFS");
2196:                fENTITYSymbol = fStringPool.addSymbol("ENTITY");
2197:                fENTITIESSymbol = fStringPool.addSymbol("ENTITIES");
2198:                fNMTOKENSymbol = fStringPool.addSymbol("NMTOKEN");
2199:                fNMTOKENSSymbol = fStringPool.addSymbol("NMTOKENS");
2200:                fNOTATIONSymbol = fStringPool.addSymbol("NOTATION");
2201:                fENUMERATIONSymbol = fStringPool.addSymbol("ENUMERATION");
2202:                fREQUIREDSymbol = fStringPool.addSymbol("#REQUIRED");
2203:                fFIXEDSymbol = fStringPool.addSymbol("#FIXED");
2204:                fDATATYPESymbol = fStringPool.addSymbol("<<datatype>>");
2205:                fEpsilonIndex = fStringPool.addSymbol("<<CMNODE_EPSILON>>");
2206:                fXMLLang = fStringPool.addSymbol("xml:lang");
2207:
2208:            } // init()
2209:
2210:            /**
2211:             * This method should only be invoked when validation
2212:             * is turn on.
2213:             * fDataTypeReg object of type DatatypeValidatorFactoryImpl
2214:             * needs to be initialized.
2215:             * In the XMLValidator the table will be by default
2216:             * first initialized to 9 validators used by DTD
2217:             * validation.
2218:             * These Validators are known.
2219:             * Later on if we ever find a Schema and need to do
2220:             * Schema validation then we will expand this
2221:             * registry table of fDataTypeReg.
2222:             */
2223:            private void initDataTypeValidators() {
2224:
2225:                if (fGrammarResolver != null) {
2226:                    fDataTypeReg = (DatatypeValidatorFactoryImpl) fGrammarResolver
2227:                            .getDatatypeRegistry();
2228:                    fDataTypeReg.initializeDTDRegistry();
2229:                }
2230:                if (fDataTypeReg != null) {
2231:                    fValID = fDataTypeReg.getDatatypeValidator("ID");
2232:                    fValIDRef = fDataTypeReg.getDatatypeValidator("IDREF");
2233:                    fValIDRefs = fDataTypeReg.getDatatypeValidator("IDREFS");
2234:                    fValENTITY = fDataTypeReg.getDatatypeValidator("ENTITY");
2235:                    fValENTITIES = fDataTypeReg
2236:                            .getDatatypeValidator("ENTITIES");
2237:                    fValNMTOKEN = fDataTypeReg.getDatatypeValidator("NMTOKEN");
2238:                    fValNMTOKENS = fDataTypeReg
2239:                            .getDatatypeValidator("NMTOKENS");
2240:                    fValNOTATION = fDataTypeReg
2241:                            .getDatatypeValidator("NOTATION");
2242:                }
2243:            }
2244:
2245:            // other
2246:
2247:            // default attribute
2248:
2249:            /** addDefaultAttributes. */
2250:            private int addDefaultAttributes(int elementIndex,
2251:                    XMLAttrList attrList, int attrIndex,
2252:                    boolean validationEnabled, boolean standalone)
2253:                    throws Exception {
2254:
2255:                //System.out.println("XMLValidator#addDefaultAttributes");
2256:                //System.out.print("  ");
2257:                //fGrammar.printAttributes(elementIndex);
2258:
2259:                //
2260:                // Check after all specified attrs are scanned
2261:                // (1) report error for REQUIRED attrs that are missing (V_TAGc)
2262:                // (2) report error for PROHIBITED attrs that are present (V_TAGc)
2263:                // (3) check that FIXED attrs have matching value (V_TAGd)
2264:                // (4) add default attrs (FIXED and NOT_FIXED)
2265:                //
2266:                fGrammar.getElementDecl(elementIndex, fTempElementDecl);
2267:
2268:                int elementNameIndex = fTempElementDecl.name.localpart;
2269:                int attlistIndex = fGrammar
2270:                        .getFirstAttributeDeclIndex(elementIndex);
2271:                int firstCheck = attrIndex;
2272:                int lastCheck = -1;
2273:                while (attlistIndex != -1) {
2274:                    fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
2275:
2276:                    int attPrefix = fTempAttDecl.name.prefix;
2277:                    int attName = fTempAttDecl.name.localpart;
2278:                    int attType = attributeTypeName(fTempAttDecl);
2279:                    int attDefType = fTempAttDecl.defaultType;
2280:                    int attValue = -1;
2281:                    if (fTempAttDecl.defaultValue != null) {
2282:                        attValue = fStringPool
2283:                                .addSymbol(fTempAttDecl.defaultValue);
2284:                    }
2285:
2286:                    boolean specified = false;
2287:                    boolean required = (attDefType & XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) > 0;
2288:                    boolean prohibited = (attDefType & XMLAttributeDecl.DEFAULT_TYPE_PROHIBITED) > 0;
2289:                    boolean fixed = (attDefType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0;
2290:
2291:                    if (firstCheck != -1) {
2292:                        boolean cdata = attType == fCDATASymbol;
2293:                        if (!cdata || required || prohibited || attValue != -1) {
2294:                            int i = attrList.getFirstAttr(firstCheck);
2295:                            while (i != -1
2296:                                    && (lastCheck == -1 || i <= lastCheck)) {
2297:
2298:                                if ((fGrammarIsDTDGrammar && (attrList
2299:                                        .getAttrName(i) == fTempAttDecl.name.rawname))
2300:                                        || (fStringPool.equalNames(attrList
2301:                                                .getAttrLocalpart(i), attName) && fStringPool
2302:                                                .equalNames(attrList
2303:                                                        .getAttrURI(i),
2304:                                                        fTempAttDecl.name.uri))) {
2305:
2306:                                    if (prohibited && validationEnabled) {
2307:                                        Object[] args = {
2308:                                                fStringPool
2309:                                                        .toString(elementNameIndex),
2310:                                                fStringPool.toString(attName) };
2311:                                        fErrorReporter
2312:                                                .reportError(
2313:                                                        fErrorReporter
2314:                                                                .getLocator(),
2315:                                                        SchemaMessageProvider.SCHEMA_DOMAIN,
2316:                                                        SchemaMessageProvider.ProhibitedAttributePresent,
2317:                                                        SchemaMessageProvider.MSG_NONE,
2318:                                                        args,
2319:                                                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2320:                                    }
2321:                                    specified = true;
2322:                                    break;
2323:                                }
2324:                                i = attrList.getNextAttr(i);
2325:                            }
2326:                        }
2327:                    }
2328:
2329:                    if (!specified) {
2330:                        if (required) {
2331:                            if (validationEnabled) {
2332:                                Object[] args = {
2333:                                        fStringPool.toString(elementNameIndex),
2334:                                        fStringPool.toString(attName) };
2335:                                fErrorReporter
2336:                                        .reportError(
2337:                                                fErrorReporter.getLocator(),
2338:                                                XMLMessages.XML_DOMAIN,
2339:                                                XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
2340:                                                XMLMessages.VC_REQUIRED_ATTRIBUTE,
2341:                                                args,
2342:                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2343:                            }
2344:                        } else if (attValue != -1) {
2345:                            if (validationEnabled && standalone) {
2346:                                if (fGrammarIsDTDGrammar
2347:                                        && ((DTDGrammar) fGrammar)
2348:                                                .getAttributeDeclIsExternal(attlistIndex)) {
2349:
2350:                                    Object[] args = {
2351:                                            fStringPool
2352:                                                    .toString(elementNameIndex),
2353:                                            fStringPool.toString(attName) };
2354:                                    fErrorReporter
2355:                                            .reportError(
2356:                                                    fErrorReporter.getLocator(),
2357:                                                    XMLMessages.XML_DOMAIN,
2358:                                                    XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
2359:                                                    XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
2360:                                                    args,
2361:                                                    XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2362:                                }
2363:                            }
2364:                            if (validationEnabled) {
2365:                                // default value should have been already normalized
2366:                                validateUsingDV(fTempAttDecl.datatypeValidator,
2367:                                        fStringPool.toString(attValue), true);
2368:                            }
2369:                            if (attrIndex == -1) {
2370:                                attrIndex = attrList.startAttrList();
2371:                            }
2372:                            // REVISIT: Validation. What should the prefix be?
2373:                            fTempQName.setValues(attPrefix, attName, attName,
2374:                                    fTempAttDecl.name.uri);
2375:                            int newAttr = attrList.addAttr(fTempQName,
2376:                                    attValue, attType, false, false);
2377:                            if (lastCheck == -1) {
2378:                                lastCheck = newAttr;
2379:                            }
2380:                        }
2381:                    }
2382:                    attlistIndex = fGrammar
2383:                            .getNextAttributeDeclIndex(attlistIndex);
2384:                }
2385:                return attrIndex;
2386:
2387:            } // addDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
2388:
2389:            /** addDTDDefaultAttributes. */
2390:            private int addDTDDefaultAttributes(QName element,
2391:                    XMLAttrList attrList, int attrIndex,
2392:                    boolean validationEnabled, boolean standalone)
2393:                    throws Exception {
2394:
2395:                //
2396:                // Check after all specified attrs are scanned
2397:                // (1) report error for REQUIRED attrs that are missing (V_TAGc)
2398:                // (2) check that FIXED attrs have matching value (V_TAGd)
2399:                // (3) add default attrs (FIXED and NOT_FIXED)
2400:                //
2401:
2402:                int elementIndex = fGrammar.getElementDeclIndex(element, -1);
2403:
2404:                if (elementIndex == -1) {
2405:                    return attrIndex;
2406:                }
2407:
2408:                fGrammar.getElementDecl(elementIndex, fTempElementDecl);
2409:
2410:                int elementNameIndex = fTempElementDecl.name.rawname;
2411:                int attlistIndex = fGrammar
2412:                        .getFirstAttributeDeclIndex(elementIndex);
2413:                int firstCheck = attrIndex;
2414:                int lastCheck = -1;
2415:                while (attlistIndex != -1) {
2416:
2417:                    fGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
2418:
2419:                    // TO DO: For ericye Debug only
2420:                    /***
2421:                    if (fTempAttDecl != null) {
2422:                        XMLElementDecl element = new XMLElementDecl();
2423:                        fGrammar.getElementDecl(elementIndex, element);
2424:                        System.out.println("element: "+fStringPool.toString(element.name.localpart));
2425:                        System.out.println("attlistIndex " + attlistIndex + "\n"+
2426:                            "attName : '"+fStringPool.toString(fTempAttDecl.name.localpart) + "'\n"
2427:                                           + "attType : "+fTempAttDecl.type + "\n"
2428:                                           + "attDefaultType : "+fTempAttDecl.defaultType + "\n"
2429:                                           + "attDefaultValue : '"+fTempAttDecl.defaultValue + "'\n"
2430:                                           + attrList.getLength() +"\n"
2431:                                           );
2432:                    }
2433:                    /***/
2434:
2435:                    int attPrefix = fTempAttDecl.name.prefix;
2436:                    int attName = fTempAttDecl.name.rawname;
2437:                    int attLocalpart = fTempAttDecl.name.localpart;
2438:                    int attType = attributeTypeName(fTempAttDecl);
2439:                    int attDefType = fTempAttDecl.defaultType;
2440:                    int attValue = -1;
2441:                    if (fTempAttDecl.defaultValue != null) {
2442:                        attValue = fStringPool
2443:                                .addSymbol(fTempAttDecl.defaultValue);
2444:                    }
2445:                    boolean specified = false;
2446:                    boolean required = (attDefType & XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) > 0;
2447:
2448:                    /****
2449:                    if (fValidating && fGrammar != null && fGrammarIsDTDGrammar && attValue != -1) {
2450:                        normalizeAttValue(null, fTempAttDecl.name,
2451:                                          attValue,attType,fTempAttDecl.list,
2452:                                          fTempAttDecl.enumeration);
2453:                    }
2454:                    /****/
2455:
2456:                    if (firstCheck != -1) {
2457:                        boolean cdata = attType == fCDATASymbol;
2458:                        if (!cdata || required || attValue != -1) {
2459:                            int i = attrList.getFirstAttr(firstCheck);
2460:                            while (i != -1
2461:                                    && (lastCheck == -1 || i <= lastCheck)) {
2462:
2463:                                if (attrList.getAttrName(i) == fTempAttDecl.name.rawname) {
2464:
2465:                                    if (validationEnabled
2466:                                            && (attDefType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0) {
2467:                                        int alistValue = attrList
2468:                                                .getAttValue(i);
2469:                                        if (alistValue != attValue
2470:                                                && !fStringPool
2471:                                                        .toString(alistValue)
2472:                                                        .equals(
2473:                                                                fStringPool
2474:                                                                        .toString(attValue))) {
2475:                                            Object[] args = {
2476:                                                    fStringPool
2477:                                                            .toString(elementNameIndex),
2478:                                                    fStringPool
2479:                                                            .toString(attName),
2480:                                                    fStringPool
2481:                                                            .toString(alistValue),
2482:                                                    fStringPool
2483:                                                            .toString(attValue) };
2484:                                            fErrorReporter
2485:                                                    .reportError(
2486:                                                            fErrorReporter
2487:                                                                    .getLocator(),
2488:                                                            XMLMessages.XML_DOMAIN,
2489:                                                            XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
2490:                                                            XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
2491:                                                            args,
2492:                                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2493:                                        }
2494:                                    }
2495:                                    specified = true;
2496:                                    break;
2497:                                }
2498:                                i = attrList.getNextAttr(i);
2499:                            }
2500:                        }
2501:                    }
2502:
2503:                    if (!specified) {
2504:                        if (required) {
2505:                            if (validationEnabled) {
2506:                                Object[] args = {
2507:                                        fStringPool.toString(elementNameIndex),
2508:                                        fStringPool.toString(attName) };
2509:                                fErrorReporter
2510:                                        .reportError(
2511:                                                fErrorReporter.getLocator(),
2512:                                                XMLMessages.XML_DOMAIN,
2513:                                                XMLMessages.MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED,
2514:                                                XMLMessages.VC_REQUIRED_ATTRIBUTE,
2515:                                                args,
2516:                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2517:                            }
2518:                        } else if (attValue != -1) {
2519:                            if (validationEnabled && standalone) {
2520:                                if (fGrammarIsDTDGrammar
2521:                                        && ((DTDGrammar) fGrammar)
2522:                                                .getAttributeDeclIsExternal(attlistIndex)) {
2523:
2524:                                    Object[] args = {
2525:                                            fStringPool
2526:                                                    .toString(elementNameIndex),
2527:                                            fStringPool.toString(attName) };
2528:                                    fErrorReporter
2529:                                            .reportError(
2530:                                                    fErrorReporter.getLocator(),
2531:                                                    XMLMessages.XML_DOMAIN,
2532:                                                    XMLMessages.MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED,
2533:                                                    XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
2534:                                                    args,
2535:                                                    XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2536:                                }
2537:                            }
2538:                            if (validationEnabled) {
2539:                                validateUsingDV(fTempAttDecl.datatypeValidator,
2540:                                        fStringPool.toString(attValue), true);
2541:                            }
2542:                            if (attrIndex == -1) {
2543:                                attrIndex = attrList.startAttrList();
2544:                            }
2545:
2546:                            fTempQName.setValues(attPrefix, attLocalpart,
2547:                                    attName, fTempAttDecl.name.uri);
2548:                            int newAttr = attrList.addAttr(fTempQName,
2549:                                    attValue, attType, false, false);
2550:                            if (lastCheck == -1) {
2551:                                lastCheck = newAttr;
2552:                            }
2553:                        }
2554:                    }
2555:                    attlistIndex = fGrammar
2556:                            .getNextAttributeDeclIndex(attlistIndex);
2557:                }
2558:                return attrIndex;
2559:
2560:            } // addDTDDefaultAttributes(int,XMLAttrList,int,boolean,boolean):int
2561:
2562:            // content models
2563:
2564:            /** Queries the content model for the specified element index. */
2565:            private XMLContentModel getElementContentModel(int elementIndex)
2566:                    throws Exception {
2567:                XMLContentModel contentModel = null;
2568:                if (elementIndex > -1) {
2569:                    if (fGrammar.getElementDecl(elementIndex, fTempElementDecl)) {
2570:                        if (fSGComparator == null) {
2571:                            fSGComparator = new SubstitutionGroupComparator(
2572:                                    fGrammarResolver, fStringPool,
2573:                                    fErrorReporter);
2574:                        }
2575:                        contentModel = fGrammar.getElementContentModel(
2576:                                elementIndex, fSGComparator);
2577:                    }
2578:                }
2579:                //return fGrammar.getElementContentModel(elementIndex);
2580:                return contentModel;
2581:            }
2582:
2583:            // query attribute information
2584:
2585:            /** Returns an attribute definition for an element type. */
2586:            // this is only used by DTD validation.
2587:            private int getAttDef(QName element, QName attribute) {
2588:                if (fGrammar != null) {
2589:                    int scope = fCurrentScope;
2590:                    if (element.uri > -1) {
2591:                        scope = TOP_LEVEL_SCOPE;
2592:                    }
2593:                    int elementIndex = fGrammar.getElementDeclIndex(element,
2594:                            scope);
2595:                    if (elementIndex == -1) {
2596:                        return -1;
2597:                    }
2598:                    int attDefIndex = fGrammar
2599:                            .getFirstAttributeDeclIndex(elementIndex);
2600:                    while (attDefIndex != -1) {
2601:                        fGrammar.getAttributeDecl(attDefIndex,
2602:                                fTempAttributeDecl);
2603:                        if (fTempAttributeDecl.name.localpart == attribute.localpart
2604:                                && fTempAttributeDecl.name.uri == attribute.uri) {
2605:                            return attDefIndex;
2606:                        }
2607:                        attDefIndex = fGrammar
2608:                                .getNextAttributeDeclIndex(attDefIndex);
2609:                    }
2610:                }
2611:                return -1;
2612:
2613:            } // getAttDef(QName,QName)
2614:
2615:            /** Returns an attribute definition for an element type. */
2616:            private int getAttDefByElementIndex(int elementIndex,
2617:                    QName attribute) {
2618:                if (fGrammar != null && elementIndex > -1) {
2619:                    if (elementIndex == -1) {
2620:                        return -1;
2621:                    }
2622:                    int attDefIndex = fGrammar
2623:                            .getFirstAttributeDeclIndex(elementIndex);
2624:                    while (attDefIndex != -1) {
2625:                        fGrammar.getAttributeDecl(attDefIndex, fTempAttDecl);
2626:
2627:                        if (fGrammarIsDTDGrammar) {
2628:                            if (fTempAttDecl.name.rawname == attribute.rawname)
2629:                                return attDefIndex;
2630:                        } else if (fTempAttDecl.name.localpart == attribute.localpart
2631:                                && fTempAttDecl.name.uri == attribute.uri) {
2632:                            return attDefIndex;
2633:                        }
2634:
2635:                        if (fGrammarIsSchemaGrammar) {
2636:                            if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY) {
2637:                                return attDefIndex;
2638:                            } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
2639:                                if (attribute.uri != fTempAttDecl.name.uri) {
2640:                                    return attDefIndex;
2641:                                }
2642:                            } else if (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST) {
2643:                                if (fStringPool
2644:                                        .stringInList(fTempAttDecl.enumeration,
2645:                                                attribute.uri)) {
2646:                                    return attDefIndex;
2647:                                }
2648:                            }
2649:                        }
2650:
2651:                        attDefIndex = fGrammar
2652:                                .getNextAttributeDeclIndex(attDefIndex);
2653:                    }
2654:                }
2655:                return -1;
2656:
2657:            } // getAttDef(QName,QName)
2658:
2659:            // validation
2660:
2661:            /** Root element specified. */
2662:            private void rootElementSpecified(QName rootElement)
2663:                    throws Exception {
2664:
2665:                if (fLoadDTDGrammar)
2666:                    // initialize the grammar to be the default one,
2667:                    // it definitely should be a DTD Grammar at this case;
2668:                    if (fGrammar == null) {
2669:
2670:                        fGrammar = fGrammarResolver.getGrammar("");
2671:
2672:                        if (fGrammar != null) {
2673:                            if (fGrammar instanceof  DTDGrammar) {
2674:                                fGrammarIsDTDGrammar = true;
2675:                                fGrammarIsSchemaGrammar = false;
2676:                            } else if (fGrammar instanceof  SchemaGrammar) {
2677:                                fGrammarIsSchemaGrammar = true;
2678:                                fGrammarIsDTDGrammar = false;
2679:                            }
2680:
2681:                            fGrammarNameSpaceIndex = fEmptyURI;
2682:                        }
2683:                    }
2684:
2685:                if (fValidating) {
2686:                    if (fGrammarIsDTDGrammar
2687:                            && ((DTDGrammar) fGrammar)
2688:                                    .getRootElementQName(fRootElement)) {
2689:
2690:                        String root1 = fStringPool
2691:                                .toString(fRootElement.rawname);
2692:                        String root2 = fStringPool
2693:                                .toString(rootElement.rawname);
2694:                        if (!root1.equals(root2)) {
2695:                            reportRecoverableXMLError(
2696:                                    XMLMessages.MSG_ROOT_ELEMENT_TYPE,
2697:                                    XMLMessages.VC_ROOT_ELEMENT_TYPE,
2698:                                    fRootElement.rawname, rootElement.rawname);
2699:                        }
2700:                    }
2701:                }
2702:
2703:                if (fNamespacesEnabled) {
2704:                    if (fNamespacesScope == null) {
2705:                        fNamespacesScope = new NamespacesScope(this );
2706:                        fNamespacesPrefix = fStringPool.addSymbol("xmlns");
2707:                        //fNamespacesScope.setNamespaceForPrefix(fNamespacesPrefix, StringPool.EMPTY_STRING);
2708:                        // xxxxx
2709:                        fNamespacesScope.setNamespaceForPrefix(
2710:                                fNamespacesPrefix, -1);
2711:                        int xmlSymbol = fStringPool.addSymbol("xml");
2712:                        int xmlNamespace = fStringPool
2713:                                .addSymbol("http://www.w3.org/XML/1998/namespace");
2714:                        fNamespacesScope.setNamespaceForPrefix(xmlSymbol,
2715:                                xmlNamespace);
2716:                    }
2717:                }
2718:
2719:            } // rootElementSpecified(QName)
2720:
2721:            /** Switchs to correct validating symbol tables when Schema changes.*/
2722:
2723:            private boolean switchGrammar(int newGrammarNameSpaceIndex)
2724:                    throws Exception {
2725:                Grammar tempGrammar = fGrammarResolver.getGrammar(fStringPool
2726:                        .toString(newGrammarNameSpaceIndex));
2727:                if (tempGrammar == null) {
2728:                    // This is a case where namespaces is on with a DTD grammar.
2729:                    tempGrammar = fGrammarResolver.getGrammar("");
2730:                }
2731:                if (tempGrammar == null) {
2732:                    return false;
2733:                } else {
2734:                    fGrammar = tempGrammar;
2735:                    if (fGrammar instanceof  DTDGrammar) {
2736:                        fGrammarIsDTDGrammar = true;
2737:                        fGrammarIsSchemaGrammar = false;
2738:                    } else if (fGrammar instanceof  SchemaGrammar) {
2739:                        fGrammarIsSchemaGrammar = true;
2740:                        fGrammarIsDTDGrammar = false;
2741:                    }
2742:
2743:                    return true;
2744:                }
2745:            }
2746:
2747:            /** Binds namespaces to the element and attributes. */
2748:            private void bindNamespacesToElementAndAttributes(QName element,
2749:                    XMLAttrList attrList) throws Exception {
2750:
2751:                fNamespacesScope.increaseDepth();
2752:
2753:                if (fAttrListHandle != -1 || !fSeenRootElement) {
2754:                    int index = attrList.getFirstAttr(fAttrListHandle);
2755:                    while (index != -1) {
2756:                        int attName = attrList.getAttrName(index);
2757:                        int attPrefix = attrList.getAttrPrefix(index);
2758:                        if (fStringPool.equalNames(attName, fXMLLang)) {
2759:                            /*  No check: http://www.w3.org/XML/xml-19980210-errata#E73 and bug 2793 */
2760:                        } else if (fStringPool.equalNames(attName,
2761:                                fNamespacesPrefix)) {
2762:                            int uri = fStringPool.addSymbol(attrList
2763:                                    .getAttValue(index));
2764:                            fNamespacesScope.setNamespaceForPrefix(
2765:                                    StringPool.EMPTY_STRING, uri);
2766:                        } else {
2767:                            if (attPrefix == fNamespacesPrefix) {
2768:                                int nsPrefix = attrList.getAttrLocalpart(index);
2769:                                int uri = fStringPool.addSymbol(attrList
2770:                                        .getAttValue(index));
2771:                                if (uri == StringPool.EMPTY_STRING) {
2772:                                    Object[] args = { fStringPool
2773:                                            .toString(nsPrefix) };
2774:                                    fErrorReporter
2775:                                            .reportError(
2776:                                                    fErrorReporter.getLocator(),
2777:                                                    XMLMessages.XMLNS_DOMAIN,
2778:                                                    XMLMessages.MSG_NAMESPACE_NAME_EMPTY,
2779:                                                    XMLMessages.NC_NAMESPACE_NAME_EMPTY,
2780:                                                    args,
2781:                                                    XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2782:                                }
2783:                                fNamespacesScope.setNamespaceForPrefix(
2784:                                        nsPrefix, uri);
2785:
2786:                                if (fValidating && fSchemaValidation) {
2787:                                    boolean seeXsi = false;
2788:                                    String attrValue = fStringPool
2789:                                            .toString(attrList
2790:                                                    .getAttValue(index));
2791:
2792:                                    if (attrValue.equals(SchemaSymbols.URI_XSI)) {
2793:                                        fXsiPrefix = nsPrefix;
2794:                                        seeXsi = true;
2795:                                    }
2796:                                }
2797:                            }
2798:                        }
2799:                        index = attrList.getNextAttr(index);
2800:                    }
2801:
2802:                    String location = null;
2803:                    String uri = null;
2804:
2805:                    // if validating, walk through the list again to deal with "xsi:...."
2806:                    if (fValidating && fSchemaValidation) {
2807:
2808:                        fLocationUriPairs.clear();
2809:                        if (!fSeenRootElement) {
2810:                            // we are at the root element
2811:                            // and user set property on the parser to include external schemas
2812:                            //
2813:                            if (fExternalSchemas != null
2814:                                    && fExternalSchemas.length() != 0) {
2815:
2816:                                parseSchemaLocation(fExternalSchemas);
2817:                            }
2818:                            if (fExternalNoNamespaceSchema != null
2819:                                    && fExternalNoNamespaceSchema.length() != 0) {
2820:
2821:                                fLocationUriPairs.put(
2822:                                        fExternalNoNamespaceSchema, "");
2823:
2824:                                //REVISIT: wrong solution  (see AndyC note below)
2825:                                if (fNamespacesScope != null) {
2826:                                    //bind prefix "" to URI "" in this case
2827:                                    fNamespacesScope.setNamespaceForPrefix(
2828:                                            fStringPool.addSymbol(""),
2829:                                            fStringPool.addSymbol(""));
2830:                                }
2831:                            }
2832:                            parseSchemas();
2833:                            fLocationUriPairs.clear();
2834:                        }
2835:
2836:                        fXsiTypeAttValue = -1;
2837:                        fNil = false;
2838:                        index = attrList.getFirstAttr(fAttrListHandle);
2839:                        int attName;
2840:                        int attPrefix;
2841:                        while (index != -1) {
2842:
2843:                            attName = attrList.getAttrName(index);
2844:                            attPrefix = attrList.getAttrPrefix(index);
2845:
2846:                            if (fStringPool.equalNames(attName,
2847:                                    fNamespacesPrefix)) {
2848:                                // REVISIT
2849:                            } else {
2850:                                if (DEBUG_SCHEMA_VALIDATION) {
2851:                                    System.out.println("deal with XSI");
2852:                                    System.out.println("before find XSI: "
2853:                                            + fStringPool.toString(attPrefix)
2854:                                            + ","
2855:                                            + fStringPool.toString(fXsiPrefix));
2856:                                }
2857:                                if (fXsiPrefix != -1 && attPrefix == fXsiPrefix) {
2858:
2859:                                    if (DEBUG_SCHEMA_VALIDATION) {
2860:                                        System.out
2861:                                                .println("find XSI: "
2862:                                                        + fStringPool
2863:                                                                .toString(attPrefix)
2864:                                                        + ","
2865:                                                        + fStringPool
2866:                                                                .toString(attName));
2867:                                    }
2868:
2869:                                    int localpart = attrList
2870:                                            .getAttrLocalpart(index);
2871:                                    if (localpart == fStringPool
2872:                                            .addSymbol(SchemaSymbols.XSI_SCHEMALOCACTION)) {
2873:                                        parseSchemaLocation(fStringPool
2874:                                                .toString(attrList
2875:                                                        .getAttValue(index)));
2876:                                    } else if (localpart == fStringPool
2877:                                            .addSymbol(SchemaSymbols.XSI_NONAMESPACESCHEMALOCACTION)) {
2878:                                        fLocationUriPairs.put(fStringPool
2879:                                                .toString(attrList
2880:                                                        .getAttValue(index)),
2881:                                                "");
2882:
2883:                                        /***/
2884:                                        // NOTE: This is the *wrong* solution to the problem
2885:                                        //       of finding the grammar associated to elements
2886:                                        //       when the grammar does *not* have a target
2887:                                        //       namespace!!! -Ac
2888:                                        if (fNamespacesScope != null) {
2889:                                            //bind prefix "" to URI "" in this case
2890:                                            fNamespacesScope
2891:                                                    .setNamespaceForPrefix(
2892:                                                            fStringPool
2893:                                                                    .addSymbol(""),
2894:                                                            fStringPool
2895:                                                                    .addSymbol(""));
2896:                                        }
2897:                                        /***/
2898:                                    } else if (localpart == fStringPool
2899:                                            .addSymbol(SchemaSymbols.XSI_TYPE)) {
2900:                                        fXsiTypeAttValue = attrList
2901:                                                .getAttValue(index);
2902:                                    } else if (localpart == fStringPool
2903:                                            .addSymbol(SchemaSymbols.ATT_NIL)) {
2904:                                        fNil = (fStringPool.toString(attrList
2905:                                                .getAttValue(index))
2906:                                                .equals("true")) ? true : false;
2907:
2908:                                    }
2909:                                    // REVISIT: should we break here?
2910:                                    //break;
2911:                                }
2912:                            }
2913:                            index = attrList.getNextAttr(index);
2914:                        }
2915:                        parseSchemas();
2916:                    }
2917:
2918:                }
2919:
2920:                // bind element to URI
2921:                int prefix = element.prefix != -1 ? element.prefix : 0;
2922:                int uri = fNamespacesScope.getNamespaceForPrefix(prefix);
2923:                if (element.prefix != -1 || uri != StringPool.EMPTY_STRING) {
2924:                    element.uri = uri;
2925:                    if (element.uri == StringPool.EMPTY_STRING) {
2926:                        Object[] args = { fStringPool.toString(element.prefix) };
2927:                        fErrorReporter.reportError(fErrorReporter.getLocator(),
2928:                                XMLMessages.XMLNS_DOMAIN,
2929:                                XMLMessages.MSG_PREFIX_DECLARED,
2930:                                XMLMessages.NC_PREFIX_DECLARED, args,
2931:                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2932:                    }
2933:                }
2934:
2935:                if (fAttrListHandle != -1) {
2936:                    int index = attrList.getFirstAttr(fAttrListHandle);
2937:                    while (index != -1) {
2938:                        int attName = attrList.getAttrName(index);
2939:                        if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
2940:                            int attPrefix = attrList.getAttrPrefix(index);
2941:                            if (attPrefix != fNamespacesPrefix) {
2942:                                if (attPrefix != -1) {
2943:                                    int attrUri = fNamespacesScope
2944:                                            .getNamespaceForPrefix(attPrefix);
2945:                                    if (attrUri == -1) {
2946:                                        Object[] args = { fStringPool
2947:                                                .toString(attPrefix) };
2948:                                        fErrorReporter
2949:                                                .reportError(
2950:                                                        fErrorReporter
2951:                                                                .getLocator(),
2952:                                                        XMLMessages.XMLNS_DOMAIN,
2953:                                                        XMLMessages.MSG_PREFIX_DECLARED,
2954:                                                        XMLMessages.NC_PREFIX_DECLARED,
2955:                                                        args,
2956:                                                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2957:                                    }
2958:                                    attrList.setAttrURI(index, attrUri);
2959:                                }
2960:                            }
2961:                        }
2962:                        index = attrList.getNextAttr(index);
2963:                    }
2964:                }
2965:
2966:            } // bindNamespacesToElementAndAttributes(QName,XMLAttrList)
2967:
2968:            private void parseSchemas() throws Exception {
2969:
2970:                // try to resolve all the grammars here
2971:                Enumeration locations = fLocationUriPairs.keys();
2972:                String location = null;
2973:                String uri = null;
2974:                while (locations.hasMoreElements()) {
2975:                    location = (String) locations.nextElement();
2976:                    uri = (String) fLocationUriPairs.get(location);
2977:                    resolveSchemaGrammar(location, uri);
2978:                }
2979:            }
2980:
2981:            private void parseSchemaLocation(String schemaLocationStr)
2982:                    throws Exception {
2983:                StringTokenizer tokenizer = new StringTokenizer(
2984:                        schemaLocationStr, " \n\t\r", false);
2985:                int tokenTotal = tokenizer.countTokens();
2986:                if (tokenTotal % 2 != 0) {
2987:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
2988:                            SchemaMessageProvider.SCHEMA_DOMAIN,
2989:                            SchemaMessageProvider.SchemaLocation,
2990:                            SchemaMessageProvider.MSG_NONE,
2991:                            new Object[] { schemaLocationStr },
2992:                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2993:
2994:                } else {
2995:                    String uri = null;
2996:                    String location = null;
2997:                    while (tokenizer.hasMoreTokens()) {
2998:                        uri = tokenizer.nextToken();
2999:                        location = tokenizer.nextToken();
3000:                        fLocationUriPairs.put(location, uri);
3001:                    }
3002:                }
3003:
3004:            }// parseSchemaLocation(String, Hashtable)
3005:
3006:            private void resolveSchemaGrammar( String loc, String uri) throws Exception {
3007:       Grammar grammar = null;
3008:       if (uri!=null) {
3009:           if (fGrammarIsDTDGrammar && uri.length()==0) {
3010:               fErrorReporter.reportError(fErrorReporter.getLocator(),
3011:                                          XMLMessages.XML_DOMAIN,
3012:                                          XMLMessages.MSG_DTD_SCHEMA_ERROR,
3013:                                          XMLMessages.MSG_DTD_SCHEMA_ERROR,
3014:                                          null,
3015:                                          fErrorReporter.ERRORTYPE_WARNING);
3016:           }  else {
3017:                grammar = fGrammarResolver.getGrammar(uri);
3018:           }
3019:       }
3020:
3021:       if (grammar == null) {
3022:
3023:          if (fSchemaGrammarParser == null) {
3024:              //
3025:              // creating a parser for schema only once per parser instance
3026:              // leads to less objects, but increases time we spend in reset()
3027:              //
3028:              fSchemaGrammarParser = new DOMParser();
3029:              fSchemaGrammarParser.setEntityResolver( new Resolver(fEntityHandler) );
3030:              fSchemaGrammarParser.setErrorHandler(  new ErrorHandler() );
3031:
3032:              try {
3033:                fSchemaGrammarParser.setFeature("http://xml.org/sax/features/validation", false);
3034:                fSchemaGrammarParser.setFeature("http://xml.org/sax/features/namespaces", true);
3035:                fSchemaGrammarParser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
3036:              } catch (  org.xml.sax.SAXNotRecognizedException e ) {
3037:                e.printStackTrace();
3038:              } catch ( org.xml.sax.SAXNotSupportedException e ) {
3039:                e.printStackTrace();
3040:              }
3041:          }
3042:         // expand it before passing it to the parser
3043:         InputSource source = null;
3044:         EntityResolver currentER = fSchemaGrammarParser.getEntityResolver();
3045:         if (currentER != null) {
3046:            source = currentER.resolveEntity("", loc);
3047:         }
3048:         if (source == null) {
3049:            loc = fEntityHandler.expandSystemId(loc);
3050:            source = new InputSource(loc);
3051:         }
3052:
3053:         try {
3054:            fSchemaGrammarParser.parse( source );
3055:         } catch ( IOException e ) {
3056:            e.printStackTrace();
3057:         } catch ( SAXException e ) {
3058:            reportRecoverableXMLError( XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3059:                                       XMLMessages.SCHEMA_GENERIC_ERROR, e.getMessage() );
3060:         }
3061:
3062:         Document     document   = fSchemaGrammarParser.getDocument(); //Our Grammar
3063:
3064:         TraverseSchema tst = null;
3065:         if (DEBUG_SCHEMA_VALIDATION) {
3066:            System.out.println("I am geting the Schema Document");
3067:         }
3068:
3069:         Element root   = null;
3070:         if (document != null) {
3071:             root = document.getDocumentElement();// This is what we pass to TraverserSchema
3072:         }
3073:         if (root == null) {
3074:            reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Can't get back Schema document's root element :" + loc);
3075:         } else {
3076:            if (uri!=null && !uri.equals(root.getAttribute(SchemaSymbols.ATT_TARGETNAMESPACE)) ) {
3077:               reportRecoverableXMLError(XMLMessages.MSG_GENERIC_SCHEMA_ERROR, XMLMessages.SCHEMA_GENERIC_ERROR, "Schema in " + loc + " has a different target namespace " +
3078:                                         "from the one specified in the instance document :" + uri);
3079:            }
3080:
3081:            grammar = new SchemaGrammar();
3082:            grammar.setGrammarDocument(document);
3083:
3084:            // Since we've just constructed a schema grammar, we should make sure we know what we've done.
3085:            fGrammarIsSchemaGrammar = true;
3086:            fGrammarIsDTDGrammar = false;
3087:
3088:            //At this point we should expand the registry table.
3089:            // pass parser's entity resolver (local Resolver), which also has reference to user's
3090:            // entity resolver, and also can fall-back to entityhandler's expandSystemId()
3091:            GeneralAttrCheck generalAttrCheck = new GeneralAttrCheck(fErrorReporter, fDataTypeReg);
3092:            tst = new TraverseSchema( root, fStringPool, (SchemaGrammar)grammar, fGrammarResolver, fErrorReporter, source.getSystemId(), currentER, getSchemaFullCheckingEnabled(), generalAttrCheck, fExternalSchemas, fExternalNoNamespaceSchema);
3093:            generalAttrCheck.checkNonSchemaAttributes(fGrammarResolver);
3094:
3095:            //allowing xsi:schemaLocation to appear on any element
3096:
3097:            String targetNS =   root.getAttribute("targetNamespace");
3098:            fGrammarNameSpaceIndex = fStringPool.addSymbol(targetNS);
3099:            fGrammarResolver.putGrammar(targetNS, grammar);
3100:            fGrammar = (SchemaGrammar)grammar;
3101:
3102:            // when in full checking, we need to do UPA stuff here
3103:            // by constructing all content models
3104:            if (fSchemaValidationFullChecking) {
3105:               try {
3106:                 // get all grammar URIs
3107:                 Enumeration grammarURIs = fGrammarResolver.nameSpaceKeys();
3108:                 String grammarURI;
3109:                 Grammar gGrammar;
3110:                 SchemaGrammar sGrammar;
3111:                 // for each grammar
3112:                 while (grammarURIs.hasMoreElements()) {
3113:                     grammarURI = (String)grammarURIs.nextElement();
3114:                     // if we checked UPA on this grammar, just skip
3115:                     if (UPACheckedGrammarURIs.get(grammarURI) != null)
3116:                        continue;
3117:                     // otherwise, mark this one as checked
3118:                     UPACheckedGrammarURIs.put(grammarURI, fgNullObject);
3119:                     gGrammar = fGrammarResolver.getGrammar(grammarURI);
3120:                     if (!(gGrammar instanceof  SchemaGrammar))
3121:                        continue;
3122:                     sGrammar = (SchemaGrammar)gGrammar;
3123:
3124:                     // get all registered complex type in this grammar
3125:                     Hashtable complexTypeRegistry = sGrammar.getComplexTypeRegistry();
3126:                     int count = complexTypeRegistry.size();
3127:                     Enumeration enum = complexTypeRegistry.elements();
3128:
3129:                     TraverseSchema.ComplexTypeInfo typeInfo;
3130:                     if (fSGComparator == null) {
3131:                         fSGComparator = new SubstitutionGroupComparator(fGrammarResolver, fStringPool, fErrorReporter);
3132:                     }
3133:                     while (enum.hasMoreElements ()) {
3134:                         typeInfo = (TraverseSchema.ComplexTypeInfo)enum.nextElement();
3135:                         // for each type, we construct a corresponding content model
3136:                         sGrammar.getContentModel(typeInfo.contentSpecHandle,
3137:                                                  typeInfo.contentType,
3138:                                                  fSGComparator);
3139:                     }
3140:                 }
3141:               } catch (CMException excToCatch) {
3142:                  // REVISIT - Translate caught error to the protected error handler interface
3143:                  int majorCode = excToCatch.getErrorCode();
3144:                  fErrorReporter.reportError(fErrorReporter.getLocator(),
3145:                                             ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
3146:                                             majorCode,
3147:                                             0,
3148:                                             null,
3149:                                             XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3150:               }
3151:            }
3152:         }
3153:      }
3154:
3155:   }
3156:
3157:            /*
3158:             * for <notation> must resolve values "b:myNotation"
3159:             *
3160:             * @param value  string value of element or attribute
3161:             * @return
3162:             * @exception Exception
3163:             */
3164:            private String bindNotationURI(String value) throws Exception {
3165:                int colonP = value.indexOf(":");
3166:                String prefix = "";
3167:                String localpart = value;
3168:                if (colonP > -1) {
3169:                    prefix = value.substring(0, colonP);
3170:                    localpart = value.substring(colonP + 1);
3171:                }
3172:
3173:                String uri = "";
3174:                int uriIndex = StringPool.EMPTY_STRING;
3175:                if (fNamespacesScope != null) {
3176:                    //if prefix.equals("") it would bing to xmlns URI
3177:                    uriIndex = fNamespacesScope
3178:                            .getNamespaceForPrefix(fStringPool
3179:                                    .addSymbol(prefix));
3180:                    if (uriIndex > 0) {
3181:                        return fStringPool.toString(uriIndex) + ":" + localpart;
3182:                    } else if (fGrammarNameSpaceIndex != -1) {
3183:                        // REVISIT: try binding to current namespace
3184:                        // trying to solve the case:
3185:                        //  <v01:root xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
3186:                        //           xmlns:my         ="http://www.schemaTest.org/my"
3187:                        // might not work in all cases (need clarification from schema?)
3188:                        return fStringPool.toString(fGrammarNameSpaceIndex)
3189:                                + ":" + localpart;
3190:                    }
3191:
3192:                }
3193:                return value;
3194:            }
3195:
3196:            static class Resolver implements  EntityResolver {
3197:
3198:                //
3199:                // Constants
3200:                //
3201:
3202:                private static final String SYSTEM[] = {
3203:                        "http://www.w3.org/2001/XMLSchema.dtd",
3204:                        "http://www.w3.org/XMLSchema/datatypes.dtd",
3205:                        "http://www.w3.org/XMLSchema/versionInfo.ent", };
3206:                private static final String PATH[] = { "structures.dtd",
3207:                        "datatypes.dtd", "versionInfo.ent", };
3208:
3209:                //
3210:                // Data
3211:                //
3212:
3213:                private DefaultEntityHandler fEntityHandler;
3214:
3215:                //
3216:                // Constructors
3217:                //
3218:
3219:                public Resolver(DefaultEntityHandler handler) {
3220:                    fEntityHandler = handler;
3221:                }
3222:
3223:                //
3224:                // EntityResolver methods
3225:                //
3226:
3227:                public InputSource resolveEntity(String publicId,
3228:                        String systemId) throws IOException, SAXException {
3229:
3230:                    // looking for the schema DTDs?
3231:                    for (int i = 0; i < SYSTEM.length; i++) {
3232:                        if (systemId.equals(SYSTEM[i])) {
3233:                            InputSource source = new InputSource(getClass()
3234:                                    .getResourceAsStream(PATH[i]));
3235:                            source.setPublicId(publicId);
3236:                            source.setSystemId(systemId);
3237:                            return source;
3238:                        }
3239:                    }
3240:
3241:                    // first try to resolve using user's entity resolver
3242:                    EntityResolver resolver = fEntityHandler
3243:                            .getEntityResolver();
3244:                    if (resolver != null) {
3245:                        InputSource source = resolver.resolveEntity(publicId,
3246:                                systemId);
3247:                        if (source != null) {
3248:                            return source;
3249:                        }
3250:                    }
3251:
3252:                    // use default resolution
3253:                    return new InputSource(fEntityHandler
3254:                            .expandSystemId(systemId));
3255:
3256:                } // resolveEntity(String,String):InputSource
3257:
3258:            } // class Resolver
3259:
3260:            static class ErrorHandler implements  org.xml.sax.ErrorHandler {
3261:
3262:                /** Warning. */
3263:                public void warning(SAXParseException ex) {
3264:                    System.err.println("[Warning] " + getLocationString(ex)
3265:                            + ": " + ex.getMessage());
3266:                }
3267:
3268:                /** Error. */
3269:                public void error(SAXParseException ex) {
3270:                    System.err.println("[Error] " + getLocationString(ex)
3271:                            + ": " + ex.getMessage());
3272:                }
3273:
3274:                /** Fatal error. */
3275:                public void fatalError(SAXParseException ex) {
3276:                    System.err.println("[Fatal Error] " + getLocationString(ex)
3277:                            + ": " + ex.getMessage());
3278:                    //throw ex;
3279:                }
3280:
3281:                //
3282:                // Private methods
3283:                //
3284:
3285:                /** Returns a string of the location. */
3286:                private String getLocationString(SAXParseException ex) {
3287:                    StringBuffer str = new StringBuffer();
3288:
3289:                    String systemId_ = ex.getSystemId();
3290:                    if (systemId_ != null) {
3291:                        int index = systemId_.lastIndexOf('/');
3292:                        if (index != -1)
3293:                            systemId_ = systemId_.substring(index + 1);
3294:                        str.append(systemId_);
3295:                    }
3296:                    str.append(':');
3297:                    str.append(ex.getLineNumber());
3298:                    str.append(':');
3299:                    str.append(ex.getColumnNumber());
3300:
3301:                    return str.toString();
3302:
3303:                } // getLocationString(SAXParseException):String
3304:            }
3305:
3306:            private int attributeTypeName(XMLAttributeDecl attrDecl) {
3307:                switch (attrDecl.type) {
3308:                case XMLAttributeDecl.TYPE_ENTITY: {
3309:                    return attrDecl.list ? fENTITIESSymbol : fENTITYSymbol;
3310:                }
3311:                case XMLAttributeDecl.TYPE_ENUMERATION: {
3312:                    String enumeration = fStringPool
3313:                            .stringListAsString(attrDecl.enumeration);
3314:                    return fStringPool.addSymbol(enumeration);
3315:                }
3316:                case XMLAttributeDecl.TYPE_ID: {
3317:                    return fIDSymbol;
3318:                }
3319:                case XMLAttributeDecl.TYPE_IDREF: {
3320:                    return attrDecl.list ? fIDREFSSymbol : fIDREFSymbol;
3321:                }
3322:                case XMLAttributeDecl.TYPE_NMTOKEN: {
3323:                    return attrDecl.list ? fNMTOKENSSymbol : fNMTOKENSymbol;
3324:                }
3325:                case XMLAttributeDecl.TYPE_NOTATION: {
3326:                    return fNOTATIONSymbol;
3327:                }
3328:                }
3329:                return fCDATASymbol;
3330:            }
3331:
3332:            /** Validates element and attributes. */
3333:            private void validateElementAndAttributes(QName element,
3334:                    XMLAttrList attrList) throws Exception {
3335:
3336:                if ((fGrammarIsSchemaGrammar && fElementDepth >= 0 && fValidationFlagStack[fElementDepth] != 0)
3337:                        || (fGrammar == null && !fValidating && !fNamespacesEnabled)) {
3338:                    fCurrentElementIndex = -1;
3339:                    fCurrentContentSpecType = -1;
3340:                    fInElementContent = false;
3341:                    if (fAttrListHandle != -1) {
3342:                        //fAttrList.endAttrList();
3343:                        int dupAttrs[];
3344:                        if ((dupAttrs = fAttrList.endAttrList()) != null) {
3345:                            Object[] args = {
3346:                                    fStringPool.toString(element.rawname), null };
3347:                            for (int i = 0; i < dupAttrs.length; i++) {
3348:                                args[1] = fStringPool.toString(dupAttrs[i]);
3349:                                fErrorReporter
3350:                                        .reportError(
3351:                                                fErrorReporter.getLocator(),
3352:                                                XMLMessages.XMLNS_DOMAIN,
3353:                                                XMLMessages.MSG_ATTRIBUTE_NOT_UNIQUE,
3354:                                                XMLMessages.WFC_UNIQUE_ATT_SPEC,
3355:                                                args,
3356:                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
3357:                            }
3358:                        }
3359:                    }
3360:                    return;
3361:                }
3362:
3363:                int elementIndex = -1;
3364:                int contentSpecType = -1;
3365:
3366:                boolean skipThisOne = false;
3367:                boolean laxThisOne = false;
3368:
3369:                if (fGrammarIsSchemaGrammar && fElementDepth > -1
3370:                        && fContentLeafStack[fElementDepth] != null) {
3371:                    ContentLeafNameTypeVector cv = fContentLeafStack[fElementDepth];
3372:
3373:                    //OTWI: on-the-way-in
3374:                    if (fContentModelStateStack[fElementDepth] >= 0) {
3375:                        // get the position of the current element in the content model
3376:                        int pos = ((DFAContentModel) fContentModelStack[fElementDepth])
3377:                                .oneTransition(element,
3378:                                        fContentModelStateStack, fElementDepth);
3379:                        // if it's a valid child, increase succeful count
3380:                        // and check whether we need to lax or skip this one
3381:                        if (pos >= 0) {
3382:                            fContentModelEleCount[fElementDepth]++;
3383:                            switch (cv.leafTypes[pos]) {
3384:                            case XMLContentSpec.CONTENTSPECNODE_ANY_SKIP:
3385:                            case XMLContentSpec.CONTENTSPECNODE_ANY_NS_SKIP:
3386:                            case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP:
3387:                                skipThisOne = true;
3388:                                break;
3389:                            case XMLContentSpec.CONTENTSPECNODE_ANY_LAX:
3390:                            case XMLContentSpec.CONTENTSPECNODE_ANY_NS_LAX:
3391:                            case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX:
3392:                                laxThisOne = true;
3393:                                break;
3394:                            }
3395:                        }
3396:                    }
3397:                    /*
3398:                     QName[] fElemMap = cv.leafNames;
3399:                     for (int i=0; i<cv.leafCount; i++) {
3400:                     int type = cv.leafTypes[i]  ;
3401:                     //System.out.println("******* see a ANY_OTHER_SKIP, "+type+","+element+","+fElemMap[i]+"\n*******");
3402:
3403:                     if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
3404:                     if (fElemMap[i].uri==element.uri
3405:                     && fElemMap[i].localpart == element.localpart)
3406:                     break;
3407:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY) {
3408:                     break;
3409:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
3410:                     if (element.uri == fElemMap[i].uri) {
3411:                     break;
3412:                     }
3413:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
3414:                     if (fElemMap[i].uri != element.uri) {
3415:                     break;
3416:                     }
3417:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_SKIP) {
3418:                     skipThisOne = true;
3419:                     break;
3420:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_NS_SKIP) {
3421:                     if (element.uri == fElemMap[i].uri) {
3422:                     skipThisOne = true;
3423:                     break;
3424:                     }
3425:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP) {
3426:                     if (fElemMap[i].uri != element.uri) {
3427:                     skipThisOne = true;
3428:                     break;
3429:                     }
3430:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_LAX) {
3431:                     laxThisOne = true;
3432:                     break;
3433:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_NS_LAX) {
3434:                     if (element.uri == fElemMap[i].uri) {
3435:                     laxThisOne = true;
3436:                     break;
3437:                     }
3438:                     } else if (type == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX) {
3439:                     if (fElemMap[i].uri != element.uri) {
3440:                     laxThisOne = true;
3441:                     break;
3442:                     }
3443:                     }
3444:
3445:                     }
3446:                     */
3447:                }
3448:
3449:                if (skipThisOne) {
3450:                    fNeedValidationOff = true;
3451:                } else {
3452:                    //REVISIT: is this the right place to check on if the Schema has changed?
3453:                    TraverseSchema.ComplexTypeInfo baseTypeInfo = null;
3454:                    if (fGrammarIsSchemaGrammar && fCurrentElementIndex != -1)
3455:                        baseTypeInfo = ((SchemaGrammar) fGrammar)
3456:                                .getElementComplexTypeInfo(fCurrentElementIndex);
3457:
3458:                    if (fNamespacesEnabled && fValidating
3459:                            && element.uri != fGrammarNameSpaceIndex
3460:                            && element.uri != StringPool.EMPTY_STRING) {
3461:                        fGrammarNameSpaceIndex = element.uri;
3462:
3463:                        boolean success = switchGrammar(fGrammarNameSpaceIndex);
3464:
3465:                        if (!success && !laxThisOne) {
3466:                            reportRecoverableXMLError(
3467:                                    XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3468:                                    XMLMessages.SCHEMA_GENERIC_ERROR,
3469:                                    "Grammar with uri: "
3470:                                            + fStringPool
3471:                                                    .toString(fGrammarNameSpaceIndex)
3472:                                            + " , can not be found; schema namespace may be wrong:  Xerces supports schemas from the \"http://www.w3.org/2001/XMLSchema\" namespace"
3473:                                            + " or the instance document's namespace may not match the targetNamespace of the schema");
3474:                        }
3475:                    }
3476:
3477:                    if (fGrammar != null) {
3478:                        if (DEBUG_SCHEMA_VALIDATION) {
3479:                            System.out.println("*******Lookup element: uri: "
3480:                                    + fStringPool.toString(element.uri)
3481:                                    + " localpart: '"
3482:                                    + fStringPool.toString(element.localpart)
3483:                                    + "' and scope : " + fCurrentScope + "\n");
3484:                        }
3485:
3486:                        elementIndex = fGrammar.getElementDeclIndex(element,
3487:                                fCurrentScope);
3488:
3489:                        if (elementIndex == -1) {
3490:                            elementIndex = fGrammar.getElementDeclIndex(
3491:                                    element, TOP_LEVEL_SCOPE);
3492:                        }
3493:
3494:                        if (elementIndex == -1) {
3495:                            // if validating based on a Schema, try to resolve the element again by searching in its type's ancestor types
3496:                            if (fGrammarIsSchemaGrammar
3497:                                    && fCurrentElementIndex != -1) {
3498:                                int aGrammarNSIndex = fGrammarNameSpaceIndex;
3499:                                while (baseTypeInfo != null) {
3500:                                    String baseTName = baseTypeInfo.typeName;
3501:                                    if (!baseTName.startsWith("#")) {
3502:                                        int comma = baseTName.indexOf(',');
3503:                                        aGrammarNSIndex = fStringPool
3504:                                                .addSymbol(baseTName.substring(
3505:                                                        0, comma).trim());
3506:                                        if (aGrammarNSIndex != fGrammarNameSpaceIndex) {
3507:                                            if (!switchGrammar(aGrammarNSIndex)) {
3508:                                                break; //exit the loop in this case
3509:                                            }
3510:                                            fGrammarNameSpaceIndex = aGrammarNSIndex;
3511:                                        }
3512:                                    }
3513:                                    elementIndex = fGrammar
3514:                                            .getElementDeclIndex(element,
3515:                                                    baseTypeInfo.scopeDefined);
3516:                                    if (elementIndex > -1) {
3517:                                        //System.out.println("found element index for " + fStringPool.toString(element.localpart));
3518:                                        // update the current Grammar NS index if resolving element succeed.
3519:                                        break;
3520:                                    }
3521:                                    baseTypeInfo = baseTypeInfo.baseComplexTypeInfo;
3522:                                }
3523:                                // if *still* can't find it, try a grammar with no targetNamespace
3524:                                if (elementIndex == -1
3525:                                        && element.uri == StringPool.EMPTY_STRING) {
3526:                                    boolean success = switchGrammar(element.uri);
3527:                                    if (success) {
3528:                                        fGrammarNameSpaceIndex = element.uri;
3529:                                        elementIndex = fGrammar
3530:                                                .getElementDeclIndex(
3531:                                                        element.localpart,
3532:                                                        TOP_LEVEL_SCOPE);
3533:                                    }
3534:                                }
3535:                            }
3536:                            //if still can't resolve it, try TOP_LEVEL_SCOPE AGAIN
3537:                            /****/
3538:                            if (element.uri == StringPool.EMPTY_STRING
3539:                                    && elementIndex == -1
3540:                                    && fNamespacesScope != null) {
3541:                                elementIndex = fGrammar.getElementDeclIndex(
3542:                                        element.localpart, TOP_LEVEL_SCOPE);
3543:                                // REVISIT:
3544:                                // this is a hack to handle the situation where namespace prefix "" is bound to nothing, and there
3545:                                // is a "noNamespaceSchemaLocation" specified, and element
3546:                                element.uri = StringPool.EMPTY_STRING;
3547:                            }
3548:                            /****/
3549:
3550:                            /****/
3551:                            if (elementIndex == -1) {
3552:                                if (laxThisOne) {
3553:                                    fNeedValidationOff = true;
3554:                                } else if (DEBUG_SCHEMA_VALIDATION)
3555:                                    System.out
3556:                                            .println("!!! can not find elementDecl in the grammar, "
3557:                                                    + " the element localpart: "
3558:                                                    + element.localpart
3559:                                                    + "["
3560:                                                    + fStringPool
3561:                                                            .toString(element.localpart)
3562:                                                    + "]"
3563:                                                    + " the element uri: "
3564:                                                    + element.uri
3565:                                                    + "["
3566:                                                    + fStringPool
3567:                                                            .toString(element.uri)
3568:                                                    + "]"
3569:                                                    + " and the current enclosing scope: "
3570:                                                    + fCurrentScope);
3571:                            }
3572:                            /****/
3573:                        }
3574:
3575:                        if (DEBUG_SCHEMA_VALIDATION) {
3576:                            fGrammar.getElementDecl(elementIndex,
3577:                                    fTempElementDecl);
3578:                            System.out
3579:                                    .println("elementIndex: "
3580:                                            + elementIndex
3581:                                            + " \n and itsName : '"
3582:                                            + fStringPool
3583:                                                    .toString(fTempElementDecl.name.localpart)
3584:                                            + "' \n its ContentType:"
3585:                                            + fTempElementDecl.type
3586:                                            + "\n its ContentSpecIndex : "
3587:                                            + fTempElementDecl.contentSpecIndex
3588:                                            + "\n"
3589:                                            + " and the current enclosing scope: "
3590:                                            + fCurrentScope);
3591:                        }
3592:                    }
3593:
3594:                    final int oldElementIndex = elementIndex;
3595:
3596:                    contentSpecType = getContentSpecType(elementIndex);
3597:                    int elementNameLocalPart = StringPool.NULL_STRING;
3598:                    DatatypeValidator elementDatatypeValidator = null;
3599:
3600:                    if (elementIndex != -1) {
3601:                        fGrammar.getElementDecl(elementIndex, fTempElementDecl);
3602:                        elementNameLocalPart = fTempElementDecl.name.localpart;
3603:                        elementDatatypeValidator = fTempElementDecl.datatypeValidator;
3604:                    }
3605:
3606:                    if (fGrammarIsSchemaGrammar) {
3607:
3608:                        // handle "xsi:type" right here
3609:                        if (fXsiTypeAttValue > -1) {
3610:                            String xsiType = fStringPool
3611:                                    .toString(fXsiTypeAttValue);
3612:                            int colonP = xsiType.indexOf(":");
3613:                            String prefix = "";
3614:                            String localpart = xsiType;
3615:                            if (colonP > -1) {
3616:                                prefix = xsiType.substring(0, colonP);
3617:                                localpart = xsiType.substring(colonP + 1);
3618:                            }
3619:
3620:                            String uri = "";
3621:                            int uriIndex = StringPool.EMPTY_STRING;
3622:                            if (fNamespacesScope != null) {
3623:                                uriIndex = fNamespacesScope
3624:                                        .getNamespaceForPrefix(fStringPool
3625:                                                .addSymbol(prefix));
3626:                                if (uriIndex > 0) {
3627:                                    uri = fStringPool.toString(uriIndex);
3628:                                    if (uriIndex != fGrammarNameSpaceIndex) {
3629:                                        fGrammarNameSpaceIndex = fCurrentSchemaURI = uriIndex;
3630:                                        boolean success = switchGrammar(fCurrentSchemaURI);
3631:                                        if (!success && !fNeedValidationOff) {
3632:                                            // only report an error if the new namespace is not
3633:                                            // the schema namespace
3634:                                            if (!uri
3635:                                                    .equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))
3636:                                                reportRecoverableXMLError(
3637:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3638:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3639:                                                        "Grammar with uri: "
3640:                                                                + fStringPool
3641:                                                                        .toString(fCurrentSchemaURI)
3642:                                                                + " , can not be found");
3643:                                        }
3644:                                    }
3645:                                }
3646:                            }
3647:
3648:                            Hashtable complexRegistry = ((SchemaGrammar) fGrammar)
3649:                                    .getComplexTypeRegistry();
3650:                            DatatypeValidatorFactoryImpl dataTypeReg = ((SchemaGrammar) fGrammar)
3651:                                    .getDatatypeRegistry();
3652:                            if (complexRegistry == null || dataTypeReg == null) {
3653:                                reportRecoverableXMLError(
3654:                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3655:                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3656:                                        fErrorReporter.getLocator()
3657:                                                .getSystemId()
3658:                                                + " line"
3659:                                                + fErrorReporter.getLocator()
3660:                                                        .getLineNumber()
3661:                                                + ", canot resolve xsi:type = "
3662:                                                + xsiType + "  ---2");
3663:                            } else {
3664:                                TraverseSchema.ComplexTypeInfo typeInfo = (TraverseSchema.ComplexTypeInfo) complexRegistry
3665:                                        .get(uri + "," + localpart);
3666:
3667:                                if (typeInfo == null) {
3668:                                    if (uri
3669:                                            .equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
3670:                                        fXsiTypeValidator = dataTypeReg
3671:                                                .getDatatypeValidator(localpart);
3672:                                    } else
3673:                                        fXsiTypeValidator = dataTypeReg
3674:                                                .getDatatypeValidator(uri + ","
3675:                                                        + localpart);
3676:                                    if (fXsiTypeValidator == null)
3677:                                        reportRecoverableXMLError(
3678:                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3679:                                                XMLMessages.SCHEMA_GENERIC_ERROR,
3680:                                                "unresolved type : "
3681:                                                        + uri
3682:                                                        + ","
3683:                                                        + localpart
3684:                                                        + " found  in xsi:type handling");
3685:                                    else if (elementIndex != -1) {
3686:                                        // make sure the new type is related to the
3687:                                        // type of the expected element
3688:                                        DatatypeValidator ancestorValidator = elementDatatypeValidator;
3689:                                        DatatypeValidator tempVal = fXsiTypeValidator;
3690:                                        for (; tempVal != null; tempVal = tempVal
3691:                                                .getBaseValidator())
3692:                                            // WARNING!!!  Comparison by reference.
3693:                                            if (tempVal == ancestorValidator)
3694:                                                break;
3695:                                        if (tempVal == null) {
3696:                                            // now if ancestorValidator is a union, then we must
3697:                                            // look through its members to see whether we derive from any of them.
3698:                                            if (ancestorValidator instanceof  UnionDatatypeValidator) {
3699:                                                // fXsiTypeValidator must derive from one of its members...
3700:                                                Vector subUnionMemberDV = ((UnionDatatypeValidator) ancestorValidator)
3701:                                                        .getBaseValidators();
3702:                                                int subUnionSize = subUnionMemberDV
3703:                                                        .size();
3704:                                                boolean found = false;
3705:                                                for (int i = 0; i < subUnionSize
3706:                                                        && !found; i++) {
3707:                                                    DatatypeValidator dTempSub = (DatatypeValidator) subUnionMemberDV
3708:                                                            .elementAt(i);
3709:                                                    DatatypeValidator dTemp = fXsiTypeValidator;
3710:                                                    for (; dTemp != null; dTemp = dTemp
3711:                                                            .getBaseValidator()) {
3712:                                                        // WARNING!!!  This uses comparison by reference andTemp is thus inherently suspect!
3713:                                                        if (dTempSub == dTemp) {
3714:                                                            found = true;
3715:                                                            break;
3716:                                                        }
3717:                                                    }
3718:                                                    if (!found) {
3719:                                                        // if dTempSub is anySimpleType,
3720:                                                        // then the derivation is ok.
3721:                                                        if (dTempSub instanceof  AnySimpleType) {
3722:                                                            found = true;
3723:                                                        }
3724:                                                    }
3725:                                                }
3726:                                                if (!found) {
3727:                                                    reportRecoverableXMLError(
3728:                                                            XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3729:                                                            XMLMessages.SCHEMA_GENERIC_ERROR,
3730:                                                            "Type : "
3731:                                                                    + uri
3732:                                                                    + ","
3733:                                                                    + localpart
3734:                                                                    + " does not derive from the type of element "
3735:                                                                    + fStringPool
3736:                                                                            .toString(elementNameLocalPart));
3737:                                                }
3738:                                            } else if ((ancestorValidator == null && ((SchemaGrammar) fGrammar)
3739:                                                    .getElementComplexTypeInfo(elementIndex) == null)
3740:                                                    || (ancestorValidator instanceof  AnySimpleType)) {
3741:                                                // if ancestorValidator is anyType or anySimpleType,
3742:                                                // then the derivation is ok.
3743:                                            } else {
3744:                                                reportRecoverableXMLError(
3745:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3746:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3747:                                                        "Type : "
3748:                                                                + uri
3749:                                                                + ","
3750:                                                                + localpart
3751:                                                                + " does not derive from the type of element "
3752:                                                                + fStringPool
3753:                                                                        .toString(elementNameLocalPart));
3754:                                            }
3755:                                        } else {
3756:                                            // if we have an attribute but xsi:type's type is simple, we have a problem...
3757:                                            if (tempVal != null
3758:                                                    && fXsiTypeValidator != null
3759:                                                    && (fGrammar
3760:                                                            .getFirstAttributeDeclIndex(elementIndex) != -1)) {
3761:                                                reportRecoverableXMLError(
3762:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3763:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3764:                                                        "Type : "
3765:                                                                + uri
3766:                                                                + ","
3767:                                                                + localpart
3768:                                                                + " does not derive from the type of element "
3769:                                                                + fStringPool
3770:                                                                        .toString(elementNameLocalPart));
3771:                                            }
3772:                                            // check if element has block set
3773:                                            if ((((SchemaGrammar) fGrammar)
3774:                                                    .getElementDeclBlockSet(elementIndex) & SchemaSymbols.RESTRICTION) != 0) {
3775:                                                reportRecoverableXMLError(
3776:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3777:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3778:                                                        "Element "
3779:                                                                + fStringPool
3780:                                                                        .toString(elementNameLocalPart)
3781:                                                                + "does not permit substitution by a type such as "
3782:                                                                + uri + ","
3783:                                                                + localpart);
3784:                                            }
3785:                                        }
3786:                                    }
3787:                                } else {
3788:
3789:                                    //
3790:                                    // The type must not be abstract
3791:                                    //
3792:                                    if (typeInfo.isAbstractType()) {
3793:                                        reportRecoverableXMLError(
3794:                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3795:                                                XMLMessages.SCHEMA_GENERIC_ERROR,
3796:                                                "Abstract type "
3797:                                                        + xsiType
3798:                                                        + " should not be used in xsi:type");
3799:                                    }
3800:                                    if (elementIndex != -1) {
3801:                                        // now we look at whether there is a type
3802:                                        // relation and whether the type (and element) allow themselves to be substituted for.
3803:
3804:                                        TraverseSchema.ComplexTypeInfo tempType = typeInfo;
3805:                                        TraverseSchema.ComplexTypeInfo destType = ((SchemaGrammar) fGrammar)
3806:                                                .getElementComplexTypeInfo(elementIndex);
3807:                                        for (; tempType != null
3808:                                                && destType != null; tempType = tempType.baseComplexTypeInfo) {
3809:                                            if (tempType.typeName
3810:                                                    .equals(destType.typeName))
3811:                                                break;
3812:                                        }
3813:                                        if (tempType == null) {
3814:                                            reportRecoverableXMLError(
3815:                                                    XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3816:                                                    XMLMessages.SCHEMA_GENERIC_ERROR,
3817:                                                    "Type : "
3818:                                                            + uri
3819:                                                            + ","
3820:                                                            + localpart
3821:                                                            + " does not derive from the type "
3822:                                                            + destType.typeName);
3823:                                        } else if (destType == null
3824:                                                && elementDatatypeValidator != null) {
3825:                                            // if the original type is a simple type, check derivation ok.
3826:                                            DatatypeValidator ancestorValidator = elementDatatypeValidator;
3827:                                            DatatypeValidator tempVal = fXsiTypeValidator;
3828:                                            for (; tempVal != null; tempVal = tempVal
3829:                                                    .getBaseValidator())
3830:                                                // WARNING!!!  Comparison by reference.
3831:                                                if (tempVal == ancestorValidator)
3832:                                                    break;
3833:                                            if (tempVal == null) {
3834:                                                // if ancestorValidator is anyType or anySimpleType,
3835:                                                // then the derivation is ok.
3836:                                                if (ancestorValidator instanceof  AnySimpleType) {
3837:                                                    tempVal = fXsiTypeValidator;
3838:                                                }
3839:                                            }
3840:                                            if (tempVal == null) {
3841:                                                // now if ancestorValidator is a union, then we must
3842:                                                // look through its members to see whether we derive from any of them.
3843:                                                if (ancestorValidator instanceof  UnionDatatypeValidator) {
3844:                                                    // fXsiTypeValidator must derive from one of its members...
3845:                                                    Vector subUnionMemberDV = ((UnionDatatypeValidator) ancestorValidator)
3846:                                                            .getBaseValidators();
3847:                                                    int subUnionSize = subUnionMemberDV
3848:                                                            .size();
3849:                                                    boolean found = false;
3850:                                                    for (int i = 0; i < subUnionSize
3851:                                                            && !found; i++) {
3852:                                                        DatatypeValidator dTempSub = (DatatypeValidator) subUnionMemberDV
3853:                                                                .elementAt(i);
3854:                                                        DatatypeValidator dTemp = fXsiTypeValidator;
3855:                                                        for (; dTemp != null; dTemp = dTemp
3856:                                                                .getBaseValidator()) {
3857:                                                            // WARNING!!!  This uses comparison by reference andTemp is thus inherently suspect!
3858:                                                            if (dTempSub == dTemp) {
3859:                                                                found = true;
3860:                                                                break;
3861:                                                            }
3862:                                                        }
3863:                                                        if (!found) {
3864:                                                            // if dTempSub is anySimpleType,
3865:                                                            // then the derivation is ok.
3866:                                                            if (dTempSub instanceof  AnySimpleType) {
3867:                                                                found = true;
3868:                                                            }
3869:                                                        }
3870:                                                    }
3871:                                                    if (!found) {
3872:                                                        reportRecoverableXMLError(
3873:                                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3874:                                                                XMLMessages.SCHEMA_GENERIC_ERROR,
3875:                                                                "Type : "
3876:                                                                        + uri
3877:                                                                        + ","
3878:                                                                        + localpart
3879:                                                                        + " does not derive from the type of element "
3880:                                                                        + fStringPool
3881:                                                                                .toString(elementNameLocalPart));
3882:                                                    }
3883:                                                } else {
3884:                                                    reportRecoverableXMLError(
3885:                                                            XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3886:                                                            XMLMessages.SCHEMA_GENERIC_ERROR,
3887:                                                            "Type : "
3888:                                                                    + uri
3889:                                                                    + ","
3890:                                                                    + localpart
3891:                                                                    + " does not derive from the type of element "
3892:                                                                    + fStringPool
3893:                                                                            .toString(elementNameLocalPart));
3894:                                                }
3895:                                            }
3896:                                        } else if (typeInfo != destType) { // now check whether the element or typeInfo's baseType blocks us.
3897:                                            int derivationMethod = typeInfo.derivedBy;
3898:                                            if ((((SchemaGrammar) fGrammar)
3899:                                                    .getElementDeclBlockSet(elementIndex) & derivationMethod) != 0) {
3900:                                                reportRecoverableXMLError(
3901:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3902:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3903:                                                        "Element "
3904:                                                                + fStringPool
3905:                                                                        .toString(elementNameLocalPart)
3906:                                                                + " does not permit xsi:type substitution in the manner required by type "
3907:                                                                + uri + ","
3908:                                                                + localpart);
3909:                                            } else if (typeInfo.baseComplexTypeInfo != null
3910:                                                    && (typeInfo.baseComplexTypeInfo.blockSet & derivationMethod) != 0) {
3911:                                                reportRecoverableXMLError(
3912:                                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3913:                                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3914:                                                        "Type "
3915:                                                                + typeInfo.baseComplexTypeInfo.typeName
3916:                                                                + " does not permit other types, such as "
3917:                                                                + uri
3918:                                                                + ","
3919:                                                                + localpart
3920:                                                                + " to be substituted for itself using xsi:type");
3921:                                            }
3922:                                        }
3923:                                    }
3924:                                    elementIndex = typeInfo.templateElementIndex;
3925:                                }
3926:                            }
3927:
3928:                            fXsiTypeAttValue = -1;
3929:                        }
3930:
3931:                        else if (elementIndex != -1) {
3932:                            //
3933:                            // xsi:type was not specified...
3934:                            // If the corresponding type is abstract, detect an error
3935:                            //
3936:                            TraverseSchema.ComplexTypeInfo typeInfo = ((SchemaGrammar) fGrammar)
3937:                                    .getElementComplexTypeInfo(elementIndex);
3938:
3939:                            if (typeInfo != null && typeInfo.isAbstractType()) {
3940:                                reportRecoverableXMLError(
3941:                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3942:                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3943:                                        "Element "
3944:                                                + fStringPool
3945:                                                        .toString(element.rawname)
3946:                                                + " is declared with a type that is abstract.  Use xsi:type to specify a non-abstract type");
3947:                            }
3948:                        }
3949:
3950:                        if (elementIndex != -1) {
3951:                            //
3952:                            // Check whether this element is abstract.  If so, an error
3953:                            //
3954:                            int miscFlags = ((SchemaGrammar) fGrammar)
3955:                                    .getElementDeclMiscFlags(elementIndex);
3956:                            if ((miscFlags & SchemaSymbols.ABSTRACT) != 0) {
3957:                                reportRecoverableXMLError(
3958:                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3959:                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3960:                                        "A member of abstract element "
3961:                                                + fStringPool
3962:                                                        .toString(element.rawname)
3963:                                                + "'s substitution group must be specified");
3964:                            }
3965:                            if (fNil
3966:                                    && (miscFlags & SchemaSymbols.NILLABLE) == 0) {
3967:                                fNil = false;
3968:                                reportRecoverableXMLError(
3969:                                        XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
3970:                                        XMLMessages.SCHEMA_GENERIC_ERROR,
3971:                                        "xsi:nil must not be specified for the element "
3972:                                                + fStringPool
3973:                                                        .toString(element.rawname)
3974:                                                + " with {nillable} equals 'false'");
3975:                            }
3976:                            //Change the current scope to be the one defined by this element.
3977:                            fCurrentScope = ((SchemaGrammar) fGrammar)
3978:                                    .getElementDefinedScope(elementIndex);
3979:
3980:                            //       here need to check if we need to switch Grammar by asking SchemaGrammar whether
3981:                            //       this element actually is of a type in another Schema.
3982:                            String anotherSchemaURI = ((SchemaGrammar) fGrammar)
3983:                                    .getElementFromAnotherSchemaURI(elementIndex);
3984:                            if (anotherSchemaURI != null) {
3985:                                //before switch Grammar, set the elementIndex to be the template elementIndex of its type
3986:                                if (contentSpecType != -1) {
3987:                                    TraverseSchema.ComplexTypeInfo typeInfo = ((SchemaGrammar) fGrammar)
3988:                                            .getElementComplexTypeInfo(elementIndex);
3989:                                    if (typeInfo != null) {
3990:                                        elementIndex = typeInfo.templateElementIndex;
3991:                                    }
3992:
3993:                                    // now switch the grammar
3994:                                    fGrammarNameSpaceIndex = fCurrentSchemaURI = fStringPool
3995:                                            .addSymbol(anotherSchemaURI);
3996:                                    boolean success = switchGrammar(fCurrentSchemaURI);
3997:                                    if (!success && !fNeedValidationOff) {
3998:                                        reportRecoverableXMLError(
3999:                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
4000:                                                XMLMessages.SCHEMA_GENERIC_ERROR,
4001:                                                "Grammar with uri: "
4002:                                                        + fStringPool
4003:                                                                .toString(fCurrentSchemaURI)
4004:                                                        + " , can not be found");
4005:                                    }
4006:                                }
4007:                            }
4008:
4009:                        }
4010:                    }
4011:                    // If the elementIndex changed since last time
4012:                    // we queried the content type, query it again.
4013:                    if (elementIndex != oldElementIndex)
4014:                        contentSpecType = getContentSpecType(elementIndex);
4015:
4016:                    if (contentSpecType == -1 && fValidating
4017:                            && !fNeedValidationOff) {
4018:                        reportRecoverableXMLError(
4019:                                XMLMessages.MSG_ELEMENT_NOT_DECLARED,
4020:                                XMLMessages.VC_ELEMENT_VALID, element.rawname);
4021:                    }
4022:                    if (fGrammar != null && fGrammarIsSchemaGrammar
4023:                            && elementIndex != -1) {
4024:                        fAttrListHandle = addDefaultAttributes(elementIndex,
4025:                                attrList, fAttrListHandle, fValidating,
4026:                                fStandaloneReader != -1);
4027:                    }
4028:                    if (fAttrListHandle != -1) {
4029:                        //fAttrList.endAttrList();
4030:                        int dupAttrs[];
4031:                        if ((dupAttrs = fAttrList.endAttrList()) != null) {
4032:                            Object[] args = {
4033:                                    fStringPool.toString(element.rawname), null };
4034:                            for (int i = 0; i < dupAttrs.length; i++) {
4035:                                args[1] = fStringPool.toString(dupAttrs[i]);
4036:                                fErrorReporter
4037:                                        .reportError(
4038:                                                fErrorReporter.getLocator(),
4039:                                                XMLMessages.XMLNS_DOMAIN,
4040:                                                XMLMessages.MSG_ATTRIBUTE_NOT_UNIQUE,
4041:                                                XMLMessages.WFC_UNIQUE_ATT_SPEC,
4042:                                                args,
4043:                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4044:                            }
4045:                        }
4046:                    }
4047:
4048:                    if (DEBUG_PRINT_ATTRIBUTES) {
4049:                        String elementStr = fStringPool
4050:                                .toString(element.rawname);
4051:                        System.out.print("startElement: <" + elementStr);
4052:                        if (fAttrListHandle != -1) {
4053:                            int index = attrList.getFirstAttr(fAttrListHandle);
4054:                            while (index != -1) {
4055:                                System.out.print(" "
4056:                                        + fStringPool.toString(attrList
4057:                                                .getAttrName(index))
4058:                                        + "=\""
4059:                                        + fStringPool.toString(attrList
4060:                                                .getAttValue(index)) + "\"");
4061:                                index = attrList.getNextAttr(index);
4062:                            }
4063:                        }
4064:                        System.out.println(">");
4065:                    }
4066:                    if (fAttrListHandle != -1 && !fNeedValidationOff) {
4067:                        int index = fAttrList.getFirstAttr(fAttrListHandle);
4068:                        while (index != -1) {
4069:                            int attrNameIndex = attrList.getAttrName(index);
4070:
4071:                            // here, we validate every "user-defined" attributes
4072:                            int _xmlns = fStringPool.addSymbol("xmlns");
4073:
4074:                            if (attrNameIndex != _xmlns
4075:                                    && attrList.getAttrPrefix(index) != _xmlns)
4076:                                if (fGrammar != null) {
4077:                                    fTempQName.setValues(attrList
4078:                                            .getAttrPrefix(index), attrList
4079:                                            .getAttrLocalpart(index), attrList
4080:                                            .getAttrName(index), attrList
4081:                                            .getAttrURI(index));
4082:                                    int attDefIndex = getAttDefByElementIndex(
4083:                                            elementIndex, fTempQName);
4084:
4085:                                    if (fTempQName.uri != fXsiURI)
4086:                                        if (attDefIndex == -1) {
4087:                                            if (fValidating) {
4088:                                                // REVISIT - cache the elem/attr tuple so that we only give
4089:                                                //  this error once for each unique occurrence
4090:                                                Object[] args = {
4091:                                                        fStringPool
4092:                                                                .toString(element.rawname),
4093:                                                        fStringPool
4094:                                                                .toString(attrList
4095:                                                                        .getAttrName(index)) };
4096:
4097:                                                /*****/
4098:                                                fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
4099:
4100:                                                fErrorReporter
4101:                                                        .reportError(
4102:                                                                fAttrNameLocator,
4103:                                                                XMLMessages.XML_DOMAIN,
4104:                                                                XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
4105:                                                                XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
4106:                                                                args,
4107:                                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4108:                                                /******/
4109:                                            }
4110:                                        } else {
4111:
4112:                                            fGrammar.getAttributeDecl(
4113:                                                    attDefIndex, fTempAttDecl);
4114:
4115:                                            int attributeType = attributeTypeName(fTempAttDecl);
4116:                                            attrList.setAttType(index,
4117:                                                    attributeType);
4118:
4119:                                            if (fGrammarIsDTDGrammar) {
4120:                                                int normalizedValue = validateDTDattribute(
4121:                                                        element,
4122:                                                        attrList
4123:                                                                .getAttValue(index),
4124:                                                        fTempAttDecl);
4125:                                                attrList.setAttValue(index,
4126:                                                        normalizedValue);
4127:
4128:                                            }
4129:                                            if (fValidating) {
4130:                                                // check to see if this attribute matched an attribute wildcard
4131:                                                if (fGrammarIsDTDGrammar) {
4132:                                                    //do nothing
4133:                                                } else if (fGrammarIsSchemaGrammar
4134:                                                        && (fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_ANY
4135:                                                                || fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_LIST || fTempAttDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER)) {
4136:
4137:                                                    if ((fTempAttDecl.defaultType & XMLAttributeDecl.PROCESSCONTENTS_SKIP) > 0) {
4138:                                                        // attribute should just be bypassed,
4139:                                                    } else if ((fTempAttDecl.defaultType & XMLAttributeDecl.PROCESSCONTENTS_STRICT) > 0
4140:                                                            || (fTempAttDecl.defaultType & XMLAttributeDecl.PROCESSCONTENTS_LAX) > 0) {
4141:
4142:                                                        boolean reportError = false;
4143:                                                        boolean processContentStrict = (fTempAttDecl.defaultType & XMLAttributeDecl.PROCESSCONTENTS_STRICT) > 0;
4144:
4145:                                                        // ??? REVISIT: can't tell whether it's a local attribute
4146:                                                        //     or a global one with empty namespace
4147:                                                        //if (fTempQName.uri == StringPool.EMPTY_STRING) {
4148:                                                        //   if (processContentStrict) {
4149:                                                        //      reportError = true;
4150:                                                        //   }
4151:                                                        //} else {
4152:                                                        {
4153:                                                            Grammar aGrammar = fGrammarResolver
4154:                                                                    .getGrammar(fStringPool
4155:                                                                            .toString(fTempQName.uri));
4156:
4157:                                                            if (aGrammar == null
4158:                                                                    || !(aGrammar instanceof  SchemaGrammar)) {
4159:                                                                if (processContentStrict) {
4160:                                                                    reportError = true;
4161:                                                                }
4162:                                                            } else {
4163:                                                                SchemaGrammar sGrammar = (SchemaGrammar) aGrammar;
4164:                                                                Hashtable attRegistry = sGrammar
4165:                                                                        .getAttributeDeclRegistry();
4166:                                                                if (attRegistry == null) {
4167:                                                                    if (processContentStrict) {
4168:                                                                        reportError = true;
4169:                                                                    }
4170:                                                                } else {
4171:                                                                    XMLAttributeDecl attDecl = (XMLAttributeDecl) attRegistry
4172:                                                                            .get(fStringPool
4173:                                                                                    .toString(fTempQName.localpart));
4174:                                                                    if (attDecl == null) {
4175:                                                                        if (processContentStrict) {
4176:                                                                            reportError = true;
4177:                                                                        }
4178:                                                                    } else {
4179:                                                                        DatatypeValidator attDV = attDecl.datatypeValidator;
4180:                                                                        if (attDV == null) {
4181:                                                                            if (processContentStrict) {
4182:                                                                                reportError = true;
4183:                                                                            }
4184:                                                                        } else {
4185:                                                                            try {
4186:                                                                                String value = fStringPool
4187:                                                                                        .toString(attrList
4188:                                                                                                .getAttValue(index));
4189:                                                                                fWhiteSpace = attDV
4190:                                                                                        .getWSFacet();
4191:                                                                                if (fWhiteSpace != DatatypeValidator.PRESERVE) {
4192:                                                                                    value = normalizeValue(value);
4193:                                                                                }
4194:                                                                                validateUsingDV(
4195:                                                                                        attDV,
4196:                                                                                        value,
4197:                                                                                        false);
4198:                                                                                if (fNormalizeContents) {
4199:                                                                                    int normalizedValue = fStringPool
4200:                                                                                            .addString(value);
4201:                                                                                    attrList
4202:                                                                                            .setAttValue(
4203:                                                                                                    index,
4204:                                                                                                    normalizedValue);
4205:                                                                                }
4206:                                                                            } catch (InvalidDatatypeValueException idve) {
4207:                                                                                fErrorReporter
4208:                                                                                        .reportError(
4209:                                                                                                fErrorReporter
4210:                                                                                                        .getLocator(),
4211:                                                                                                SchemaMessageProvider.SCHEMA_DOMAIN,
4212:                                                                                                SchemaMessageProvider.DatatypeError,
4213:                                                                                                SchemaMessageProvider.MSG_NONE,
4214:                                                                                                new Object[] { idve
4215:                                                                                                        .getMessage() },
4216:                                                                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4217:                                                                            }
4218:                                                                        }
4219:                                                                    }
4220:                                                                }
4221:                                                            }
4222:                                                        }
4223:                                                        if (reportError) {
4224:                                                            Object[] args = {
4225:                                                                    fStringPool
4226:                                                                            .toString(element.rawname),
4227:                                                                    "ANY---"
4228:                                                                            + fStringPool
4229:                                                                                    .toString(attrList
4230:                                                                                            .getAttrName(index)) };
4231:
4232:                                                            fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
4233:
4234:                                                            fErrorReporter
4235:                                                                    .reportError(
4236:                                                                            fAttrNameLocator,
4237:                                                                            XMLMessages.XML_DOMAIN,
4238:                                                                            XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
4239:                                                                            XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
4240:                                                                            args,
4241:                                                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4242:
4243:                                                        }
4244:                                                    }
4245:                                                } else if (fTempAttDecl.datatypeValidator == null) {
4246:                                                    Object[] args = {
4247:                                                            fStringPool
4248:                                                                    .toString(element.rawname),
4249:                                                            fStringPool
4250:                                                                    .toString(attrList
4251:                                                                            .getAttrName(index)) };
4252:
4253:                                                    System.out
4254:                                                            .println("[Error] Datatypevalidator for attribute "
4255:                                                                    + fStringPool
4256:                                                                            .toString(attrList
4257:                                                                                    .getAttrName(index))
4258:                                                                    + " not found in element type "
4259:                                                                    + fStringPool
4260:                                                                            .toString(element.rawname));
4261:                                                    /****/
4262:                                                    fAttrNameLocator = getLocatorImpl(fAttrNameLocator);
4263:
4264:                                                    fErrorReporter
4265:                                                            .reportError(
4266:                                                                    fAttrNameLocator,
4267:                                                                    XMLMessages.XML_DOMAIN,
4268:                                                                    XMLMessages.MSG_ATTRIBUTE_NOT_DECLARED,
4269:                                                                    XMLMessages.VC_ATTRIBUTE_VALUE_TYPE,
4270:                                                                    args,
4271:                                                                    XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4272:                                                    /****/
4273:                                                } else {
4274:                                                    try {
4275:                                                        String value = fStringPool
4276:                                                                .toString(attrList
4277:                                                                        .getAttValue(index));
4278:                                                        DatatypeValidator tempDV = fTempAttDecl.datatypeValidator;
4279:                                                        fWhiteSpace = tempDV
4280:                                                                .getWSFacet();
4281:                                                        if (fWhiteSpace != DatatypeValidator.PRESERVE) {
4282:                                                            value = normalizeValue(value);
4283:                                                        }
4284:                                                        // if "fixed" is specified, then get the fixed string,
4285:                                                        // and compare over value space
4286:                                                        if ((fTempAttDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0
4287:                                                                && tempDV
4288:                                                                        .compare(
4289:                                                                                value,
4290:                                                                                fTempAttDecl.defaultValue) != 0) {
4291:                                                            Object[] args = {
4292:                                                                    fStringPool
4293:                                                                            .toString(element.rawname),
4294:                                                                    fStringPool
4295:                                                                            .toString(attrList
4296:                                                                                    .getAttrName(index)),
4297:                                                                    value,
4298:                                                                    fTempAttDecl.defaultValue };
4299:                                                            fErrorReporter
4300:                                                                    .reportError(
4301:                                                                            fErrorReporter
4302:                                                                                    .getLocator(),
4303:                                                                            XMLMessages.XML_DOMAIN,
4304:                                                                            XMLMessages.MSG_FIXED_ATTVALUE_INVALID,
4305:                                                                            XMLMessages.VC_FIXED_ATTRIBUTE_DEFAULT,
4306:                                                                            args,
4307:                                                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4308:                                                        }
4309:                                                        validateUsingDV(tempDV,
4310:                                                                value, false);
4311:                                                        if (fNormalizeContents) {
4312:                                                            int normalizedValue = fStringPool
4313:                                                                    .addString(value);
4314:                                                            attrList
4315:                                                                    .setAttValue(
4316:                                                                            index,
4317:                                                                            normalizedValue);
4318:                                                        }
4319:                                                    } catch (InvalidDatatypeValueException idve) {
4320:                                                        fErrorReporter
4321:                                                                .reportError(
4322:                                                                        fErrorReporter
4323:                                                                                .getLocator(),
4324:                                                                        SchemaMessageProvider.SCHEMA_DOMAIN,
4325:                                                                        SchemaMessageProvider.DatatypeError,
4326:                                                                        SchemaMessageProvider.MSG_NONE,
4327:                                                                        new Object[] { idve
4328:                                                                                .getMessage() },
4329:                                                                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4330:                                                    }
4331:                                                }
4332:                                            } // end of if (fValidating)
4333:
4334:                                        } // end of if (attDefIndex == -1) else
4335:
4336:                                }// end of if (fGrammar != null)
4337:                            index = fAttrList.getNextAttr(index);
4338:                        }
4339:                    }
4340:                }
4341:                if (fAttrListHandle != -1) {
4342:                    int index = attrList.getFirstAttr(fAttrListHandle);
4343:                    while (index != -1) {
4344:                        int attName = attrList.getAttrName(index);
4345:                        if (!fStringPool.equalNames(attName, fNamespacesPrefix)) {
4346:                            int attPrefix = attrList.getAttrPrefix(index);
4347:                            if (attPrefix != fNamespacesPrefix) {
4348:                                if (attPrefix != -1) {
4349:                                    int uri = fNamespacesScope
4350:                                            .getNamespaceForPrefix(attPrefix);
4351:                                    if (uri == StringPool.EMPTY_STRING) {
4352:                                        Object[] args = { fStringPool
4353:                                                .toString(attPrefix) };
4354:                                        fErrorReporter
4355:                                                .reportError(
4356:                                                        fErrorReporter
4357:                                                                .getLocator(),
4358:                                                        XMLMessages.XMLNS_DOMAIN,
4359:                                                        XMLMessages.MSG_PREFIX_DECLARED,
4360:                                                        XMLMessages.NC_PREFIX_DECLARED,
4361:                                                        args,
4362:                                                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4363:                                    }
4364:                                    attrList.setAttrURI(index, uri);
4365:                                }
4366:                            }
4367:                        }
4368:                        index = attrList.getNextAttr(index);
4369:                    }
4370:                }
4371:
4372:                fCurrentElementIndex = elementIndex;
4373:                fCurrentContentSpecType = contentSpecType;
4374:
4375:                if (fValidating
4376:                        && contentSpecType == XMLElementDecl.TYPE_SIMPLE) {
4377:                    fBufferDatatype = true;
4378:                    fDatatypeBuffer.setLength(0);
4379:                }
4380:
4381:                fInElementContent = (contentSpecType == XMLElementDecl.TYPE_CHILDREN);
4382:
4383:            } // validateElementAndAttributes(QName,XMLAttrList)
4384:
4385:            /**
4386:             * Validate attributes in DTD fashion.
4387:             * Validation is separated from attribute value normalization (which is required
4388:             * for non-validating parsers)
4389:             * @return normalized attribute value
4390:             */
4391:            private int validateDTDattribute(QName element, int attValue,
4392:                    XMLAttributeDecl attributeDecl) throws Exception {
4393:                AttributeValidator av = null;
4394:                switch (attributeDecl.type) {
4395:                case XMLAttributeDecl.TYPE_ENTITY: {
4396:                    boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
4397:                    String unTrimValue = fStringPool.toString(attValue);
4398:                    String value = unTrimValue.trim();
4399:                    if (fValidationEnabled) {
4400:                        if (value != unTrimValue) {
4401:                            if (invalidStandaloneAttDef(element,
4402:                                    attributeDecl.name)) {
4403:                                reportRecoverableXMLError(
4404:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
4405:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
4406:                                        fStringPool
4407:                                                .toString(attributeDecl.name.rawname),
4408:                                        unTrimValue, value);
4409:                            }
4410:                        }
4411:                        try {
4412:                            if (isAlistAttribute) {
4413:                                fValENTITIES.validate(value, fValidateEntity);
4414:                            } else {
4415:                                fValENTITY.validate(value, fValidateEntity);
4416:                            }
4417:                        } catch (InvalidDatatypeValueException ex) {
4418:                            if (ex.getMajorCode() != 1
4419:                                    && ex.getMinorCode() != -1) {
4420:                                reportRecoverableXMLError(ex.getMajorCode(), ex
4421:                                        .getMinorCode(), fStringPool
4422:                                        .toString(attributeDecl.name.rawname),
4423:                                        value);
4424:                            } else {
4425:                                reportRecoverableXMLError(
4426:                                        XMLMessages.MSG_ENTITY_INVALID,
4427:                                        XMLMessages.VC_ENTITY_NAME,
4428:                                        fStringPool
4429:                                                .toString(attributeDecl.name.rawname),
4430:                                        value);
4431:                            }
4432:                        }
4433:                    }
4434:                    if (fNormalizeAttributeValues) {
4435:                        if (attributeDecl.list) {
4436:                            attValue = normalizeListAttribute(value, attValue,
4437:                                    unTrimValue);
4438:                        } else {
4439:                            if (value != unTrimValue) {
4440:                                attValue = fStringPool.addSymbol(value);
4441:                            }
4442:                        }
4443:                    }
4444:                }
4445:                    break;
4446:                case XMLAttributeDecl.TYPE_ENUMERATION:
4447:                    av = fAttValidatorENUMERATION;
4448:                    break;
4449:                case XMLAttributeDecl.TYPE_ID: {
4450:                    String unTrimValue = fStringPool.toString(attValue);
4451:                    String value = unTrimValue.trim();
4452:                    if (fValidationEnabled) {
4453:                        if (value != unTrimValue) {
4454:                            if (invalidStandaloneAttDef(element,
4455:                                    attributeDecl.name)) {
4456:                                reportRecoverableXMLError(
4457:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
4458:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
4459:                                        fStringPool
4460:                                                .toString(attributeDecl.name.rawname),
4461:                                        unTrimValue, value);
4462:                            }
4463:                        }
4464:
4465:                        try {
4466:                            fValID.validate(value, fIdDefs);
4467:                            fValIDRef.validate(value, this .fValidateIDRef); //just in case we called id after IDREF
4468:                        } catch (InvalidDatatypeValueException ex) {
4469:                            int major = ex.getMajorCode(), minor = ex
4470:                                    .getMinorCode();
4471:                            if (major == -1) {
4472:                                major = XMLMessages.MSG_ID_INVALID;
4473:                                minor = XMLMessages.VC_ID;
4474:                            }
4475:                            reportRecoverableXMLError(major, minor, fStringPool
4476:                                    .toString(attributeDecl.name.rawname),
4477:                                    value);
4478:                        }
4479:                    }
4480:
4481:                    if (fNormalizeAttributeValues && value != unTrimValue) {
4482:                        attValue = fStringPool.addSymbol(value);
4483:                    }
4484:                }
4485:                    break;
4486:                case XMLAttributeDecl.TYPE_IDREF: {
4487:                    String unTrimValue = fStringPool.toString(attValue);
4488:                    String value = unTrimValue.trim();
4489:                    boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
4490:                    //changes fTempAttDef
4491:                    if (fValidationEnabled) {
4492:                        if (value != unTrimValue) {
4493:                            if (invalidStandaloneAttDef(element,
4494:                                    attributeDecl.name)) {
4495:                                reportRecoverableXMLError(
4496:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
4497:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
4498:                                        fStringPool
4499:                                                .toString(attributeDecl.name.rawname),
4500:                                        unTrimValue, value);
4501:                            }
4502:                        }
4503:
4504:                        if (attributeDecl.list && value.length() == 0) {
4505:                            reportRecoverableXMLError(
4506:                                    XMLMessages.MSG_IDREFS_INVALID,
4507:                                    XMLMessages.VC_IDREF,
4508:                                    fStringPool
4509:                                            .toString(attributeDecl.name.rawname));
4510:                        }
4511:
4512:                        try {
4513:                            if (isAlistAttribute) {
4514:                                fValIDRefs.validate(value, this .fValidateIDRef);
4515:                            } else {
4516:                                fValIDRef.validate(value, this .fValidateIDRef);
4517:                            }
4518:                        } catch (InvalidDatatypeValueException ex) {
4519:                            if (ex.getMajorCode() != 1
4520:                                    && ex.getMinorCode() != -1) {
4521:                                reportRecoverableXMLError(ex.getMajorCode(), ex
4522:                                        .getMinorCode(), fStringPool
4523:                                        .toString(attributeDecl.name.rawname),
4524:                                        value);
4525:                            } else {
4526:                                reportRecoverableXMLError(
4527:                                        XMLMessages.MSG_IDREFS_INVALID,
4528:                                        XMLMessages.VC_IDREF,
4529:                                        fStringPool
4530:                                                .toString(attributeDecl.name.rawname),
4531:                                        value);
4532:                            }
4533:                        }
4534:                    }
4535:                    if (fNormalizeAttributeValues) {
4536:                        if (attributeDecl.list) {
4537:                            attValue = normalizeListAttribute(value, attValue,
4538:                                    unTrimValue);
4539:                        } else {
4540:                            if (value != unTrimValue) {
4541:                                attValue = fStringPool.addSymbol(value);
4542:                            }
4543:                        }
4544:                    }
4545:                }
4546:                    break;
4547:                case XMLAttributeDecl.TYPE_NOTATION: {
4548:                    /* WIP
4549:                    String  unTrimValue = fStringPool.toString(attValue);
4550:                    String  value       = unTrimValue.trim();
4551:                    if (fValidationEnabled) {
4552:                     if (value != unTrimValue) {
4553:                         if (invalidStandaloneAttDef(element, attributeDecl.name)) {
4554:                             reportRecoverableXMLError(XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
4555:                                                       XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
4556:                                                       fStringPool.toString(attributeDecl.name.rawname), unTrimValue, value);
4557:                         }
4558:                     }
4559:                    }
4560:                    }
4561:                     */
4562:                    av = fAttValidatorNOTATION;
4563:                }
4564:                    break;
4565:                case XMLAttributeDecl.TYPE_NMTOKEN: {
4566:                    String unTrimValue = fStringPool.toString(attValue);
4567:                    String value = unTrimValue.trim();
4568:                    boolean isAlistAttribute = attributeDecl.list;//Caveat - Save this information because invalidStandaloneAttDef
4569:                    //changes fTempAttDef
4570:                    if (fValidationEnabled) {
4571:                        if (value != unTrimValue) {
4572:                            if (invalidStandaloneAttDef(element,
4573:                                    attributeDecl.name)) {
4574:                                reportRecoverableXMLError(
4575:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
4576:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
4577:                                        fStringPool
4578:                                                .toString(attributeDecl.name.rawname),
4579:                                        unTrimValue, value);
4580:                            }
4581:                        }
4582:                        if (attributeDecl.list && value.length() == 0) {
4583:                            reportRecoverableXMLError(
4584:                                    XMLMessages.MSG_NMTOKENS_INVALID,
4585:                                    XMLMessages.VC_NAME_TOKEN,
4586:                                    fStringPool
4587:                                            .toString(attributeDecl.name.rawname));
4588:                        }
4589:
4590:                        try {
4591:                            if (isAlistAttribute) {
4592:                                fValNMTOKENS.validate(value, null);
4593:                            } else {
4594:                                fValNMTOKEN.validate(value, null);
4595:                            }
4596:                        } catch (InvalidDatatypeValueException ex) {
4597:                            reportRecoverableXMLError(
4598:                                    XMLMessages.MSG_NMTOKEN_INVALID,
4599:                                    XMLMessages.VC_NAME_TOKEN,
4600:                                    fStringPool
4601:                                            .toString(attributeDecl.name.rawname),
4602:                                    value);//TODO NMTOKENS messge
4603:                        }
4604:                    }
4605:                    if (fNormalizeAttributeValues) {
4606:                        if (attributeDecl.list) {
4607:                            attValue = normalizeListAttribute(value, attValue,
4608:                                    unTrimValue);
4609:                        } else {
4610:                            if (value != unTrimValue) {
4611:                                attValue = fStringPool.addSymbol(value);
4612:                            }
4613:                        }
4614:                    }
4615:                }
4616:                    break;
4617:                }
4618:                if (av != null) {
4619:                    int newValue = av.normalize(element, attributeDecl.name,
4620:                            attValue, attributeDecl.type,
4621:                            attributeDecl.enumeration);
4622:                    if (fNormalizeAttributeValues)
4623:                        attValue = newValue;
4624:                }
4625:                return attValue;
4626:            }
4627:
4628:            /**
4629:             * @param value This is already trimmed.
4630:             */
4631:            private int normalizeListAttribute(String value, int origIndex,
4632:                    String unTrimValue) {
4633:
4634:                //REVISIT: some code might be shared: see normalizeWhitespace()
4635:                //
4636:                fNormalizedStr.setLength(0);
4637:                int length = value.length();
4638:                boolean skipSpace = true;
4639:                char c = 0;
4640:
4641:                for (int i = 0; i < length; i++) {
4642:                    c = value.charAt(i);
4643:                    if (c == 0x20) {
4644:                        if (!skipSpace) {
4645:                            // take the first whitespace as a space and skip the others
4646:                            fNormalizedStr.append(' ');
4647:                            skipSpace = true;
4648:                        }
4649:                    } else {
4650:                        fNormalizedStr.append((char) c);
4651:                        skipSpace = false;
4652:                    }
4653:                }
4654:                if (fNormalizedStr.length() == unTrimValue.length())
4655:                    return origIndex;
4656:                return fStringPool.addSymbol(fNormalizedStr.toString());
4657:            }
4658:
4659:            /** Character data in content. */
4660:            private void charDataInContent() {
4661:
4662:                if (DEBUG_ELEMENT_CHILDREN) {
4663:                    System.out.println("charDataInContent()");
4664:                }
4665:                if (fElementChildren.length <= fElementChildrenLength) {
4666:                    QName[] newarray = new QName[fElementChildren.length * 2];
4667:                    System.arraycopy(fElementChildren, 0, newarray, 0,
4668:                            fElementChildren.length);
4669:                    fElementChildren = newarray;
4670:                }
4671:                QName qname = fElementChildren[fElementChildrenLength];
4672:                if (qname == null) {
4673:                    for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
4674:                        fElementChildren[i] = new QName();
4675:                    }
4676:                    qname = fElementChildren[fElementChildrenLength];
4677:                }
4678:                qname.clear();
4679:                fElementChildrenLength++;
4680:
4681:            } // charDataInCount()
4682:
4683:            /**
4684:             * Check that the content of an element is valid.
4685:             * <p>
4686:             * This is the method of primary concern to the validator. This method is called
4687:             * upon the scanner reaching the end tag of an element. At that time, the
4688:             * element's children must be structurally validated, so it calls this method.
4689:             * The index of the element being checked (in the decl pool), is provided as
4690:             * well as an array of element name indexes of the children. The validator must
4691:             * confirm that this element can have these children in this order.
4692:             * <p>
4693:             * This can also be called to do 'what if' testing of content models just to see
4694:             * if they would be valid.
4695:             * <p>
4696:             * Note that the element index is an index into the element decl pool, whereas
4697:             * the children indexes are name indexes, i.e. into the string pool.
4698:             * <p>
4699:             * A value of -1 in the children array indicates a PCDATA node. All other
4700:             * indexes will be positive and represent child elements. The count can be
4701:             * zero, since some elements have the EMPTY content model and that must be
4702:             * confirmed.
4703:             *
4704:             * @param elementIndex The index within the <code>ElementDeclPool</code> of this
4705:             *                     element.
4706:             * @param childCount The number of entries in the <code>children</code> array.
4707:             * @param children The children of this element.  Each integer is an index within
4708:             *                 the <code>StringPool</code> of the child element name.  An index
4709:             *                 of -1 is used to indicate an occurrence of non-whitespace character
4710:             *                 data.
4711:             *
4712:             * @return The value -1 if fully valid, else the 0 based index of the child
4713:             *         that first failed. If the value returned is equal to the number
4714:             *         of children, then additional content is required to reach a valid
4715:             *         ending state.
4716:             *
4717:             * @exception Exception Thrown on error.
4718:             */
4719:            private int checkContent(int elementIndex, QName[] children,
4720:                    int childOffset, int childCount) throws Exception {
4721:
4722:                // Get the element name index from the element
4723:                // REVISIT: Validation
4724:                final int elementType = fCurrentElement.rawname;
4725:
4726:                if (DEBUG_PRINT_CONTENT) {
4727:                    String strTmp = fStringPool.toString(elementType);
4728:                    System.out.println("Name: " + strTmp + ", " + "Count: "
4729:                            + childCount + ", " + "ContentSpecType: "
4730:                            + fCurrentContentSpecType); //+getContentSpecAsString(elementIndex));
4731:                    for (int index = childOffset; index < (childOffset + childCount)
4732:                            && index < 10; index++) {
4733:                        if (index == 0) {
4734:                            System.out.print("  (");
4735:                        }
4736:                        String childName = (children[index].localpart == -1) ? "#PCDATA"
4737:                                : fStringPool
4738:                                        .toString(children[index].localpart);
4739:                        if (index + 1 == childCount) {
4740:                            System.out.println(childName + ")");
4741:                        } else if (index + 1 == 10) {
4742:                            System.out.println(childName + ",...)");
4743:                        } else {
4744:                            System.out.print(childName + ",");
4745:                        }
4746:                    }
4747:                }
4748:
4749:                // Get out the content spec for this element
4750:                final int contentType = fCurrentContentSpecType;
4751:
4752:                //
4753:                //  Deal with the possible types of content. We try to optimized here
4754:                //  by dealing specially with content models that don't require the
4755:                //  full DFA treatment.
4756:                //
4757:                if (contentType == XMLElementDecl.TYPE_EMPTY) {
4758:                    //
4759:                    //  If the child count is greater than zero, then this is
4760:                    //  an error right off the bat at index 0.
4761:                    //
4762:                    if (childCount != 0) {
4763:                        return 0;
4764:                    }
4765:                } else if (contentType == XMLElementDecl.TYPE_ANY) {
4766:                    //
4767:                    //  This one is open game so we don't pass any judgement on it
4768:                    //  at all. Its assumed to fine since it can hold anything.
4769:                    //
4770:                } else if (contentType == XMLElementDecl.TYPE_MIXED_SIMPLE
4771:                        || contentType == XMLElementDecl.TYPE_MIXED_COMPLEX
4772:                        || contentType == XMLElementDecl.TYPE_CHILDREN) {
4773:
4774:                    // XML Schema REC: Validation Rule: Element Locally Valid (Element)
4775:                    // 3.2.1 The element information item must have no
4776:                    // character or element information item [children].
4777:                    //
4778:                    if (childCount == 0 && fNil) {
4779:                        fNil = false;
4780:                        //return success
4781:                        return -1;
4782:                    }
4783:
4784:                    // Get the content model for this element, faulting it in if needed
4785:                    XMLContentModel cmElem = null;
4786:                    try {
4787:                        cmElem = getElementContentModel(elementIndex);
4788:                        int curState = fContentModelStateStack[fElementDepth + 1];
4789:                        // if state!=-2, we have validate the children
4790:                        if (curState != -2) {
4791:                            // if state==-1, there is invalid child
4792:                            // if !finalState, then the content is not complete
4793:                            // both indicate an error, we return successful element count
4794:                            if (curState == -1
4795:                                    || !((DFAContentModel) cmElem)
4796:                                            .isFinalState(curState)) {
4797:                                return fContentModelEleCount[fElementDepth + 1];
4798:                            } else {
4799:                                // otherwise -1: succeeded
4800:                                return -1;
4801:                            }
4802:                        }
4803:                        //otherwise, we need to validateContent
4804:                        int result = cmElem.validateContent(children,
4805:                                childOffset, childCount);
4806:                        if (result != -1 && fGrammarIsSchemaGrammar) {
4807:                            result = cmElem.validateContentSpecial(children,
4808:                                    childOffset, childCount);
4809:                        }
4810:                        return result;
4811:                    } catch (CMException excToCatch) {
4812:                        // REVISIT - Translate the caught exception to the protected error API
4813:                        int majorCode = excToCatch.getErrorCode();
4814:                        fErrorReporter
4815:                                .reportError(
4816:                                        fErrorReporter.getLocator(),
4817:                                        ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
4818:                                        majorCode, 0, null,
4819:                                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
4820:                    }
4821:                } else if (contentType == -1) {
4822:                    reportRecoverableXMLError(
4823:                            XMLMessages.MSG_ELEMENT_NOT_DECLARED,
4824:                            XMLMessages.VC_ELEMENT_VALID, elementType);
4825:                } else if (contentType == XMLElementDecl.TYPE_SIMPLE) {
4826:
4827:                    XMLContentModel cmElem = null;
4828:                    if (childCount > 0) {
4829:                        fErrorReporter
4830:                                .reportError(
4831:                                        fErrorReporter.getLocator(),
4832:                                        SchemaMessageProvider.SCHEMA_DOMAIN,
4833:                                        SchemaMessageProvider.DatatypeError,
4834:                                        SchemaMessageProvider.MSG_NONE,
4835:                                        new Object[] { "In element '"
4836:                                                + fStringPool
4837:                                                        .toString(elementType)
4838:                                                + "' : "
4839:                                                + "Can not have element children within a simple type content" },
4840:                                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4841:                    } else {
4842:                        try {
4843:
4844:                            if (fCurrentDV == null) { //no character data
4845:                                fGrammar.getElementDecl(elementIndex,
4846:                                        fTempElementDecl);
4847:                                fCurrentDV = fTempElementDecl.datatypeValidator;
4848:                            }
4849:
4850:                            // If there is xsi:type validator, substitute it.
4851:                            if (fXsiTypeValidator != null) {
4852:                                fCurrentDV = fXsiTypeValidator;
4853:                                fXsiTypeValidator = null;
4854:                            }
4855:                            if (fCurrentDV == null) {
4856:                                System.out
4857:                                        .println("Internal Error: this element have a simpletype "
4858:                                                + "but no datatypevalidator was found, element "
4859:                                                + fTempElementDecl.name
4860:                                                + ",locapart: "
4861:                                                + fStringPool
4862:                                                        .toString(fTempElementDecl.name.localpart));
4863:                            } else {
4864:                                String value = fDatatypeBuffer.toString();
4865:                                if (!fNormalizeContents
4866:                                        && fWhiteSpace != DatatypeValidator.PRESERVE) {
4867:                                    // normalize data before validating it
4868:                                    fUnnormalizedStr.setLength(0);
4869:                                    fUnnormalizedStr.append(value);
4870:                                    normalizeWhitespace(
4871:                                            fUnnormalizedStr,
4872:                                            (fWhiteSpace == DatatypeValidator.COLLAPSE));
4873:                                    value = fNormalizedStr.toString();
4874:                                }
4875:                                String currentElementDefault = ((SchemaGrammar) fGrammar)
4876:                                        .getElementDefaultValue(fCurrentElementIndex);
4877:                                int hasFixed = (((SchemaGrammar) fGrammar)
4878:                                        .getElementDeclMiscFlags(fCurrentElementIndex) & SchemaSymbols.FIXED);
4879:                                if (fNil) {
4880:                                    if (value.length() != 0) {
4881:                                        reportRecoverableXMLError(
4882:                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
4883:                                                XMLMessages.SCHEMA_GENERIC_ERROR,
4884:                                                "An element <"
4885:                                                        + fStringPool
4886:                                                                .toString(elementType)
4887:                                                        + "> with attribute xsi:nil=\"true\" must be empty");
4888:                                    }
4889:                                    if (hasFixed != 0) {
4890:                                        reportRecoverableXMLError(
4891:                                                XMLMessages.MSG_GENERIC_SCHEMA_ERROR,
4892:                                                XMLMessages.SCHEMA_GENERIC_ERROR,
4893:                                                "An element <"
4894:                                                        + fStringPool
4895:                                                                .toString(elementType)
4896:                                                        + "> with attribute xsi:nil=\"true\" must not have fixed value constraint");
4897:                                    }
4898:                                    fNil = false;
4899:                                    return -1;
4900:                                }
4901:                                // check for fixed/default values of elements here.
4902:                                if (currentElementDefault == null
4903:                                        || currentElementDefault.length() == 0) {
4904:                                    validateUsingDV(fCurrentDV, value, false);
4905:                                } else {
4906:                                    if (hasFixed != 0) {
4907:                                        if (value.length() == 0) { // use fixed as default value
4908:                                            // Note:  this is inefficient where the DOMParser
4909:                                            // is concerned.  However, if we used the characters(int)
4910:                                            // callback instead, this would be just as inefficient for SAX.
4911:                                            fDocumentHandler.characters(
4912:                                                    currentElementDefault
4913:                                                            .toCharArray(), 0,
4914:                                                    currentElementDefault
4915:                                                            .length());
4916:                                            validateUsingDV(fCurrentDV,
4917:                                                    currentElementDefault, true);
4918:                                        } else { // must check in valuespace!
4919:                                            if (fCurrentDV.compare(value,
4920:                                                    currentElementDefault) != 0) {
4921:                                                fErrorReporter
4922:                                                        .reportError(
4923:                                                                fErrorReporter
4924:                                                                        .getLocator(),
4925:                                                                SchemaMessageProvider.SCHEMA_DOMAIN,
4926:                                                                SchemaMessageProvider.FixedDiffersFromActual,
4927:                                                                0,
4928:                                                                null,
4929:                                                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4930:                                            }
4931:                                            validateUsingDV(fCurrentDV, value,
4932:                                                    true);
4933:                                        }
4934:                                    } else {
4935:                                        if (value.length() == 0) { // use default value
4936:                                            fDocumentHandler.characters(
4937:                                                    currentElementDefault
4938:                                                            .toCharArray(), 0,
4939:                                                    currentElementDefault
4940:                                                            .length());
4941:                                            validateUsingDV(fCurrentDV,
4942:                                                    currentElementDefault, true);
4943:                                        } else {
4944:                                            validateUsingDV(fCurrentDV, value,
4945:                                                    false);
4946:                                        }
4947:                                    }
4948:                                }
4949:                            }
4950:                        } catch (InvalidDatatypeValueException idve) {
4951:                            fErrorReporter
4952:                                    .reportError(
4953:                                            fErrorReporter.getLocator(),
4954:                                            SchemaMessageProvider.SCHEMA_DOMAIN,
4955:                                            SchemaMessageProvider.DatatypeError,
4956:                                            SchemaMessageProvider.MSG_NONE,
4957:                                            new Object[] { "In element '"
4958:                                                    + fStringPool
4959:                                                            .toString(elementType)
4960:                                                    + "' : "
4961:                                                    + idve.getMessage() },
4962:                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
4963:                        }
4964:
4965:                        fCurrentDV = null;
4966:                        fFirstChunk = true;
4967:                        fTrailing = false;
4968:                    }
4969:                } else {
4970:                    fErrorReporter
4971:                            .reportError(
4972:                                    fErrorReporter.getLocator(),
4973:                                    ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
4974:                                    ImplementationMessages.VAL_CST, 0, null,
4975:                                    XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
4976:                }
4977:
4978:                // We succeeded
4979:                return -1;
4980:
4981:            } // checkContent(int,int,int[]):int
4982:
4983:            /**
4984:             * Checks that all declared elements refer to declared elements
4985:             * in their content models. This method calls out to the error
4986:             * handler to indicate warnings.
4987:             */
4988:            /*private void checkDeclaredElements() throws Exception {
4989:
4990:                        //****DEBUG****
4991:                        if (DEBUG) print("(???) XMLValidator.checkDeclaredElements\n");
4992:                        //****DEBUG****
4993:
4994:                for (int i = 0; i < fElementCount; i++) {
4995:                    int type = fGrammar.getContentSpecType(i);
4996:                    if (type == XMLElementDecl.TYPE_MIXED_SIMPLE ||
4997:                        type == XMLElementDecl.TYPE_MIXED_COMPLEX ||
4998:                        type == XMLElementDecl.TYPE_CHILDREN) {
4999:                        int chunk = i >> CHUNK_SHIFT;
5000:                        int index = i &  CHUNK_MASK;
5001:                        int contentSpecIndex = fContentSpec[chunk][index];
5002:                        checkDeclaredElements(i, contentSpecIndex);
5003:                    }
5004:                }
5005:            }
5006:             */
5007:
5008:            private void printChildren() {
5009:                if (DEBUG_ELEMENT_CHILDREN) {
5010:                    System.out.print('[');
5011:                    for (int i = 0; i < fElementChildrenLength; i++) {
5012:                        System.out.print(' ');
5013:                        QName qname = fElementChildren[i];
5014:                        if (qname != null) {
5015:                            System.out.print(fStringPool
5016:                                    .toString(qname.rawname));
5017:                        } else {
5018:                            System.out.print("null");
5019:                        }
5020:                        if (i < fElementChildrenLength - 1) {
5021:                            System.out.print(", ");
5022:                        }
5023:                        System.out.flush();
5024:                    }
5025:                    System.out.print(" ]");
5026:                    System.out.println();
5027:                }
5028:            }
5029:
5030:            private void printStack() {
5031:                if (DEBUG_ELEMENT_CHILDREN) {
5032:                    System.out.print('{');
5033:                    for (int i = 0; i <= fElementDepth; i++) {
5034:                        System.out.print(' ');
5035:                        System.out.print(fElementChildrenOffsetStack[i]);
5036:                        if (i < fElementDepth) {
5037:                            System.out.print(", ");
5038:                        }
5039:                        System.out.flush();
5040:                    }
5041:                    System.out.print(" }");
5042:                    System.out.println();
5043:                }
5044:            }
5045:
5046:            //
5047:            // Interfaces
5048:            //
5049:
5050:            /**
5051:             * AttributeValidator.
5052:             */
5053:            public interface AttributeValidator {
5054:
5055:                //
5056:                // AttributeValidator methods
5057:                //
5058:
5059:                /** Normalize. */
5060:                public int normalize(QName element, QName attribute,
5061:                        int attValue, int attType, int enumHandle)
5062:                        throws Exception;
5063:
5064:            } // interface AttributeValidator
5065:
5066:            /** Returns true if invalid standalone attribute definition. */
5067:            boolean invalidStandaloneAttDef(QName element, QName attribute) {
5068:                if (fStandaloneReader == -1) {
5069:                    return false;
5070:                }
5071:                // we are normalizing a default att value...  this ok?
5072:                if (element.rawname == -1) {
5073:                    return false;
5074:                }
5075:                return getAttDefIsExternal(element, attribute);
5076:            }
5077:
5078:            void validateUsingDV(DatatypeValidator dv, String content,
5079:                    boolean onlyVal3Types) throws Exception,
5080:                    InvalidDatatypeValueException {
5081:                if (dv instanceof  IDDatatypeValidator) {
5082:                    dv.validate(content, fIdDefs);
5083:                } else if (dv instanceof  IDREFDatatypeValidator) {
5084:                    dv.validate(content, fValidateIDRef);
5085:                } else if (dv instanceof  ENTITYDatatypeValidator) {
5086:                    dv.validate(content, fValidateEntity);
5087:                } else if (!onlyVal3Types) {
5088:                    if (dv instanceof  NOTATIONDatatypeValidator
5089:                            && content != null) {
5090:                        content = bindNotationURI(content);
5091:                    }
5092:                    dv.validate(content, null);
5093:                }
5094:            }
5095:
5096:            //
5097:            // Classes
5098:            //
5099:
5100:            /**
5101:             * AttValidatorNOTATION.
5102:             */
5103:            final class AttValidatorNOTATION implements  AttributeValidator {
5104:
5105:                //REVISIT: it looks like a redundant class
5106:                //
5107:
5108:                //
5109:                // AttributeValidator methods
5110:                //
5111:
5112:                /** Normalize. */
5113:                public int normalize(QName element, QName attribute,
5114:                        int attValueHandle, int attType, int enumHandle)
5115:                        throws Exception {
5116:                    //
5117:                    // Normalize attribute based upon attribute type...
5118:                    //
5119:                    String attValue = fStringPool.toString(attValueHandle);
5120:                    String newAttValue = attValue.trim();
5121:                    if (fValidating) {
5122:                        // REVISIT - can we release the old string?
5123:                        if (newAttValue != attValue) {
5124:                            if (invalidStandaloneAttDef(element, attribute)) {
5125:                                reportRecoverableXMLError(
5126:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
5127:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
5128:                                        fStringPool.toString(attribute.rawname),
5129:                                        attValue, newAttValue);
5130:                            }
5131:                            attValueHandle = fStringPool.addSymbol(newAttValue);
5132:                        } else {
5133:                            attValueHandle = fStringPool
5134:                                    .addSymbol(attValueHandle);
5135:                        }
5136:                        //
5137:                        // NOTATION - check that the value is in the AttDef enumeration (V_TAGo)
5138:                        //
5139:                        if (!fStringPool.stringInList(enumHandle,
5140:                                attValueHandle)) {
5141:                            reportRecoverableXMLError(
5142:                                    XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
5143:                                    XMLMessages.VC_NOTATION_ATTRIBUTES,
5144:                                    fStringPool.toString(attribute.rawname),
5145:                                    newAttValue, fStringPool
5146:                                            .stringListAsString(enumHandle));
5147:                        }
5148:                    } else if (newAttValue != attValue) {
5149:                        // REVISIT - can we release the old string?
5150:                        attValueHandle = fStringPool.addSymbol(newAttValue);
5151:                    }
5152:                    return attValueHandle;
5153:
5154:                } // normalize(QName,QName,int,int,int):int
5155:
5156:                //
5157:                // Package methods
5158:                //
5159:
5160:                /** Returns true if invalid standalone attribute definition. */
5161:                boolean invalidStandaloneAttDef(QName element, QName attribute) {
5162:                    if (fStandaloneReader == -1) {
5163:                        return false;
5164:                    }
5165:                    // we are normalizing a default att value...  this ok?
5166:                    if (element.rawname == -1) {
5167:                        return false;
5168:                    }
5169:                    return getAttDefIsExternal(element, attribute);
5170:                }
5171:
5172:            } // class AttValidatorNOTATION
5173:
5174:            /**
5175:             * AttValidatorENUMERATION.
5176:             */
5177:            final class AttValidatorENUMERATION implements  AttributeValidator {
5178:
5179:                //REVISIT: it looks like a redundant class.
5180:                //         could be just a method. See also AttValidatorNOTATION
5181:                //
5182:                // AttributeValidator methods
5183:                //
5184:
5185:                /** Normalize. */
5186:                public int normalize(QName element, QName attribute,
5187:                        int attValueHandle, int attType, int enumHandle)
5188:                        throws Exception {
5189:                    //
5190:                    // Normalize attribute based upon attribute type...
5191:                    //
5192:                    String attValue = fStringPool.toString(attValueHandle);
5193:                    String newAttValue = attValue.trim();
5194:                    if (fValidating) {
5195:                        // REVISIT - can we release the old string?
5196:                        if (newAttValue != attValue) {
5197:                            if (invalidStandaloneAttDef(element, attribute)) {
5198:                                reportRecoverableXMLError(
5199:                                        XMLMessages.MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE,
5200:                                        XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION,
5201:                                        fStringPool.toString(attribute.rawname),
5202:                                        attValue, newAttValue);
5203:                            }
5204:                            attValueHandle = fStringPool.addSymbol(newAttValue);
5205:                        } else {
5206:                            attValueHandle = fStringPool
5207:                                    .addSymbol(attValueHandle);
5208:                        }
5209:                        //
5210:                        // ENUMERATION - check that value is in the AttDef enumeration (V_TAG9)
5211:                        //
5212:                        if (!fStringPool.stringInList(enumHandle,
5213:                                attValueHandle)) {
5214:                            reportRecoverableXMLError(
5215:                                    XMLMessages.MSG_ATTRIBUTE_VALUE_NOT_IN_LIST,
5216:                                    XMLMessages.VC_ENUMERATION, fStringPool
5217:                                            .toString(attribute.rawname),
5218:                                    newAttValue, fStringPool
5219:                                            .stringListAsString(enumHandle));
5220:                        }
5221:                    } else if (newAttValue != attValue) {
5222:                        // REVISIT - can we release the old string?
5223:                        attValueHandle = fStringPool.addSymbol(newAttValue);
5224:                    }
5225:                    return attValueHandle;
5226:
5227:                } // normalize(QName,QName,int,int,int):int
5228:
5229:                //
5230:                // Package methods
5231:                //
5232:
5233:                /** Returns true if invalid standalone attribute definition. */
5234:                boolean invalidStandaloneAttDef(QName element, QName attribute) {
5235:                    if (fStandaloneReader == -1) {
5236:                        return false;
5237:                    }
5238:                    // we are normalizing a default att value...  this ok?
5239:                    if (element.rawname == -1) {
5240:                        return false;
5241:                    }
5242:                    return getAttDefIsExternal(element, attribute);
5243:                }
5244:
5245:            } // class AttValidatorENUMERATION
5246:
5247:            // xpath matcher information
5248:
5249:            /**
5250:             * Stack of XPath matchers for identity constraints.
5251:             *
5252:             * @author Andy Clark, IBM
5253:             */
5254:            protected static class XPathMatcherStack {
5255:
5256:                //
5257:                // Data
5258:                //
5259:
5260:                /** Active matchers. */
5261:                protected XPathMatcher[] fMatchers = new XPathMatcher[4];
5262:
5263:                /** Count of active matchers. */
5264:                protected int fMatchersCount;
5265:
5266:                /** Offset stack for contexts. */
5267:                protected IntStack fContextStack = new IntStack();
5268:
5269:                //
5270:                // Constructors
5271:                //
5272:
5273:                public XPathMatcherStack() {
5274:                } // <init>()
5275:
5276:                //
5277:                // Public methods
5278:                //
5279:
5280:                /** Resets the XPath matcher stack. */
5281:                public void clear() {
5282:                    for (int i = 0; i < fMatchersCount; i++) {
5283:                        fMatchers[i] = null;
5284:                    }
5285:                    fMatchersCount = 0;
5286:                    fContextStack.clear();
5287:                } // clear()
5288:
5289:                /** Returns the size of the stack. */
5290:                public int size() {
5291:                    return fContextStack.size();
5292:                } // size():int
5293:
5294:                /** Returns the count of XPath matchers. */
5295:                public int getMatcherCount() {
5296:                    return fMatchersCount;
5297:                } // getMatcherCount():int
5298:
5299:                /** Adds a matcher. */
5300:                public void addMatcher(XPathMatcher matcher) {
5301:                    ensureMatcherCapacity();
5302:                    fMatchers[fMatchersCount++] = matcher;
5303:                } // addMatcher(XPathMatcher)
5304:
5305:                /** Returns the XPath matcher at the specified index. */
5306:                public XPathMatcher getMatcherAt(int index) {
5307:                    return fMatchers[index];
5308:                } // getMatcherAt(index):XPathMatcher
5309:
5310:                /** Pushes a new context onto the stack. */
5311:                public void pushContext() {
5312:                    fContextStack.push(fMatchersCount);
5313:                } // pushContext()
5314:
5315:                /** Pops a context off of the stack. */
5316:                public void popContext() {
5317:                    fMatchersCount = fContextStack.pop();
5318:                } // popContext()
5319:
5320:                //
5321:                // Private methods
5322:                //
5323:
5324:                /** Ensures the size of the matchers array. */
5325:                private void ensureMatcherCapacity() {
5326:                    if (fMatchersCount == fMatchers.length) {
5327:                        XPathMatcher[] array = new XPathMatcher[fMatchers.length * 2];
5328:                        System.arraycopy(fMatchers, 0, array, 0,
5329:                                fMatchers.length);
5330:                        fMatchers = array;
5331:                    }
5332:                } // ensureMatcherCapacity()
5333:
5334:            } // class XPathMatcherStack
5335:
5336:            // value store implementations
5337:
5338:            /**
5339:             * Value store implementation base class. There are specific subclasses
5340:             * for handling unique, key, and keyref.
5341:             *
5342:             * @author Andy Clark, IBM
5343:             */
5344:            protected abstract class ValueStoreBase implements  ValueStore {
5345:
5346:                //
5347:                // Constants
5348:                //
5349:
5350:                /** Not a value (Unicode: #FFFF). */
5351:                protected IDValue NOT_AN_IDVALUE = new IDValue("\uFFFF", null);
5352:
5353:                //
5354:                // Data
5355:                //
5356:
5357:                /** Identity constraint. */
5358:                protected IdentityConstraint fIdentityConstraint;
5359:
5360:                /** Current data values. */
5361:                protected final OrderedHashtable fValues = new OrderedHashtable();
5362:
5363:                /** Current data value count. */
5364:                protected int fValuesCount;
5365:
5366:                /** Data value tuples. */
5367:                protected final Vector fValueTuples = new Vector();
5368:
5369:                //
5370:                // Constructors
5371:                //
5372:
5373:                /** Constructs a value store for the specified identity constraint. */
5374:                protected ValueStoreBase(IdentityConstraint identityConstraint) {
5375:                    fIdentityConstraint = identityConstraint;
5376:                } // <init>(IdentityConstraint)
5377:
5378:                //
5379:                // Public methods
5380:                //
5381:
5382:                // destroys this ValueStore; useful when, for instanc,e a
5383:                // locally-scoped ID constraint is involved.
5384:                public void destroy() {
5385:                    fValuesCount = 0;
5386:                    fValues.clear();
5387:                    fValueTuples.removeAllElements();
5388:                } // end destroy():void
5389:
5390:                // appends the contents of one ValueStore to those of us.
5391:                public void append(ValueStoreBase newVal) {
5392:                    for (int i = 0; i < newVal.fValueTuples.size(); i++) {
5393:                        OrderedHashtable o = (OrderedHashtable) newVal.fValueTuples
5394:                                .elementAt(i);
5395:                        if (!contains(o))
5396:                            fValueTuples.addElement(o);
5397:                    }
5398:                } // append(ValueStoreBase)
5399:
5400:                /** Start scope for value store. */
5401:                public void startValueScope() throws Exception {
5402:                    if (DEBUG_VALUE_STORES) {
5403:                        System.out.println("<VS>: " + toString()
5404:                                + "#startValueScope()");
5405:                    }
5406:                    fValuesCount = 0;
5407:                    int count = fIdentityConstraint.getFieldCount();
5408:                    for (int i = 0; i < count; i++) {
5409:                        fValues.put(fIdentityConstraint.getFieldAt(i),
5410:                                NOT_AN_IDVALUE);
5411:                    }
5412:                } // startValueScope()
5413:
5414:                /** Ends scope for value store. */
5415:                public void endValueScope() throws Exception {
5416:                    if (DEBUG_VALUE_STORES) {
5417:                        System.out.println("<VS>: " + toString()
5418:                                + "#endValueScope()");
5419:                    }
5420:
5421:                    // is there anything to do?
5422:                    // REVISIT: This check solves the problem with field matchers
5423:                    //          that get activated because they are at the same
5424:                    //          level as the declaring element (e.g. selector xpath
5425:                    //          is ".") but never match.
5426:                    //          However, this doesn't help us catch the problem
5427:                    //          when we expect a field value but never see it. A
5428:                    //          better solution has to be found. -Ac
5429:                    // REVISIT: Is this a problem? -Ac
5430:                    // Yes - NG
5431:                    if (fValuesCount == 0) {
5432:                        if (fIdentityConstraint.getType() == IdentityConstraint.KEY) {
5433:                            int code = SchemaMessageProvider.AbsentKeyValue;
5434:                            String eName = fIdentityConstraint.getElementName();
5435:                            reportSchemaError(code, new Object[] { eName });
5436:                        }
5437:                        return;
5438:                    }
5439:
5440:                    // do we have enough values?
5441:                    if (fValuesCount != fIdentityConstraint.getFieldCount()) {
5442:                        switch (fIdentityConstraint.getType()) {
5443:                        case IdentityConstraint.UNIQUE: {
5444:                            int code = SchemaMessageProvider.UniqueNotEnoughValues;
5445:                            String ename = fIdentityConstraint.getElementName();
5446:                            reportSchemaError(code, new Object[] { ename });
5447:                            break;
5448:                        }
5449:                        case IdentityConstraint.KEY: {
5450:                            int code = SchemaMessageProvider.KeyNotEnoughValues;
5451:                            Key key = (Key) fIdentityConstraint;
5452:                            String ename = fIdentityConstraint.getElementName();
5453:                            String kname = key.getIdentityConstraintName();
5454:                            reportSchemaError(code,
5455:                                    new Object[] { ename, kname });
5456:                            break;
5457:                        }
5458:                        case IdentityConstraint.KEYREF: {
5459:                            int code = SchemaMessageProvider.KeyRefNotEnoughValues;
5460:                            KeyRef keyref = (KeyRef) fIdentityConstraint;
5461:                            String ename = fIdentityConstraint.getElementName();
5462:                            String kname = (keyref.getKey())
5463:                                    .getIdentityConstraintName();
5464:                            reportSchemaError(code,
5465:                                    new Object[] { ename, kname });
5466:                            break;
5467:                        }
5468:                        }
5469:                        return;
5470:                    }
5471:
5472:                } // endValueScope()
5473:
5474:                // This is needed to allow keyref's to look for matched keys
5475:                // in the correct scope.  Unique and Key may also need to
5476:                // override this method for purposes of their own.
5477:                // This method is called whenever the DocumentFragment
5478:                // of an ID Constraint goes out of scope.
5479:                public void endDocumentFragment() throws Exception {
5480:                } // endDocumentFragment():void
5481:
5482:                /**
5483:                 * Signals the end of the document. This is where the specific
5484:                 * instances of value stores can verify the integrity of the
5485:                 * identity constraints.
5486:                 */
5487:                public void endDocument() throws Exception {
5488:                    if (DEBUG_VALUE_STORES) {
5489:                        System.out.println("<VS>: " + toString()
5490:                                + "#endDocument()");
5491:                    }
5492:                } // endDocument()
5493:
5494:                //
5495:                // ValueStore methods
5496:                //
5497:
5498:                /* reports an error if an element is matched
5499:                 * has nillable true and is matched by a key.
5500:                 */
5501:
5502:                public void reportNilError(IdentityConstraint id)
5503:                        throws Exception {
5504:                    if (id.getType() == IdentityConstraint.KEY) {
5505:                        int code = SchemaMessageProvider.KeyMatchesNillable;
5506:                        reportSchemaError(code, new Object[] { id
5507:                                .getElementName() });
5508:                    }
5509:                } // reportNilError
5510:
5511:                /**
5512:                 * Adds the specified value to the value store.
5513:                 *
5514:                 * @param value The value to add.
5515:                 * @param field The field associated to the value. This reference
5516:                 *              is used to ensure that each field only adds a value
5517:                 *              once within a selection scope.
5518:                 */
5519:                public void addValue(Field field, IDValue value)
5520:                        throws Exception {
5521:                    if (!field.mayMatch()) {
5522:                        int code = SchemaMessageProvider.FieldMultipleMatch;
5523:                        reportSchemaError(code,
5524:                                new Object[] { field.toString() });
5525:                    }
5526:                    if (DEBUG_VALUE_STORES) {
5527:                        System.out.println("<VS>: " + toString() + "#addValue("
5528:                                + "field=" + field + ',' + "value=" + value
5529:                                + ")");
5530:                    }
5531:
5532:                    // do we even know this field?
5533:                    int index = fValues.indexOf(field);
5534:                    if (index == -1) {
5535:                        int code = SchemaMessageProvider.UnknownField;
5536:                        reportSchemaError(code,
5537:                                new Object[] { field.toString() });
5538:                        return;
5539:                    }
5540:
5541:                    // store value
5542:                    IDValue storedValue = fValues.valueAt(index);
5543:                    if (storedValue.isDuplicateOf(NOT_AN_IDVALUE)) {
5544:                        fValuesCount++;
5545:                    }
5546:                    fValues.put(field, value);
5547:
5548:                    if (fValuesCount == fValues.size()) {
5549:                        // is this value as a group duplicated?
5550:                        if (contains(fValues)) {
5551:                            duplicateValue(fValues);
5552:                        }
5553:
5554:                        // store values
5555:                        OrderedHashtable values = (OrderedHashtable) fValues
5556:                                .clone();
5557:                        fValueTuples.addElement(values);
5558:                    }
5559:
5560:                } // addValue(String,Field)
5561:
5562:                /**
5563:                 * Returns true if this value store contains the specified
5564:                 * values tuple.
5565:                 */
5566:                public boolean contains(OrderedHashtable tuple) {
5567:                    if (DEBUG_VALUE_STORES) {
5568:                        System.out.println("<VS>: " + this .toString()
5569:                                + "#contains(" + toString(tuple) + ")");
5570:                    }
5571:
5572:                    // do sizes match?
5573:                    int tcount = tuple.size();
5574:
5575:                    // iterate over tuples to find it
5576:                    int count = fValueTuples.size();
5577:                    LOOP: for (int i = 0; i < count; i++) {
5578:                        OrderedHashtable vtuple = (OrderedHashtable) fValueTuples
5579:                                .elementAt(i);
5580:                        // compare values
5581:                        for (int j = 0; j < tcount; j++) {
5582:                            IDValue value1 = vtuple.valueAt(j);
5583:                            IDValue value2 = tuple.valueAt(j);
5584:                            if (!(value1.isDuplicateOf(value2))) {
5585:                                continue LOOP;
5586:                            }
5587:                        }
5588:
5589:                        // found it
5590:                        return true;
5591:                    }
5592:
5593:                    // didn't find it
5594:                    return false;
5595:
5596:                } // contains(Hashtable):boolean
5597:
5598:                //
5599:                // Protected methods
5600:                //
5601:
5602:                /**
5603:                 * Called when a duplicate value is added. Subclasses should override
5604:                 * this method to perform error checking.
5605:                 *
5606:                 * @param tuple The duplicate value tuple.
5607:                 */
5608:                protected void duplicateValue(OrderedHashtable tuple)
5609:                        throws Exception {
5610:                    // no-op
5611:                } // duplicateValue(Hashtable)
5612:
5613:                /** Returns a string of the specified values. */
5614:                protected String toString(OrderedHashtable tuple) {
5615:
5616:                    // no values
5617:                    int size = tuple.size();
5618:                    if (size == 0) {
5619:                        return "";
5620:                    }
5621:
5622:                    // construct value string
5623:                    StringBuffer str = new StringBuffer();
5624:                    for (int i = 0; i < size; i++) {
5625:                        if (i > 0) {
5626:                            str.append(',');
5627:                        }
5628:                        str.append(tuple.valueAt(i));
5629:                    }
5630:                    return str.toString();
5631:
5632:                } // toString(OrderedHashtable):String
5633:
5634:                //
5635:                // Object methods
5636:                //
5637:
5638:                /** Returns a string representation of this object. */
5639:                public String toString() {
5640:                    String s = super .toString();
5641:                    int index1 = s.lastIndexOf('$');
5642:                    if (index1 != -1) {
5643:                        s = s.substring(index1 + 1);
5644:                    }
5645:                    int index2 = s.lastIndexOf('.');
5646:                    if (index2 != -1) {
5647:                        s = s.substring(index2 + 1);
5648:                    }
5649:                    return s + '[' + fIdentityConstraint + ']';
5650:                } // toString():String
5651:
5652:            } // class ValueStoreBase
5653:
5654:            /**
5655:             * Unique value store.
5656:             *
5657:             * @author Andy Clark, IBM
5658:             */
5659:            protected class UniqueValueStore extends ValueStoreBase {
5660:
5661:                //
5662:                // Constructors
5663:                //
5664:
5665:                /** Constructs a unique value store. */
5666:                public UniqueValueStore(Unique unique) {
5667:                    super (unique);
5668:                } // <init>(Unique)
5669:
5670:                //
5671:                // ValueStoreBase protected methods
5672:                //
5673:
5674:                /**
5675:                 * Called when a duplicate value is added.
5676:                 *
5677:                 * @param tuple The duplicate value tuple.
5678:                 */
5679:                protected void duplicateValue(OrderedHashtable tuple)
5680:                        throws Exception {
5681:                    int code = SchemaMessageProvider.DuplicateUnique;
5682:                    String value = toString(tuple);
5683:                    String ename = fIdentityConstraint.getElementName();
5684:                    reportSchemaError(code, new Object[] { value, ename });
5685:                } // duplicateValue(Hashtable)
5686:
5687:            } // class UniqueValueStore
5688:
5689:            /**
5690:             * Key value store.
5691:             *
5692:             * @author Andy Clark, IBM
5693:             */
5694:            protected class KeyValueStore extends ValueStoreBase {
5695:
5696:                // REVISIT: Implement a more efficient storage mechanism. -Ac
5697:
5698:                //
5699:                // Constructors
5700:                //
5701:
5702:                /** Constructs a key value store. */
5703:                public KeyValueStore(Key key) {
5704:                    super (key);
5705:                } // <init>(Key)
5706:
5707:                //
5708:                // ValueStoreBase protected methods
5709:                //
5710:
5711:                /**
5712:                 * Called when a duplicate value is added.
5713:                 *
5714:                 * @param tuple The duplicate value tuple.
5715:                 */
5716:                protected void duplicateValue(OrderedHashtable tuple)
5717:                        throws Exception {
5718:                    int code = SchemaMessageProvider.DuplicateKey;
5719:                    String value = toString(tuple);
5720:                    String ename = fIdentityConstraint.getElementName();
5721:                    reportSchemaError(code, new Object[] { value, ename });
5722:                } // duplicateValue(Hashtable)
5723:
5724:            } // class KeyValueStore
5725:
5726:            /**
5727:             * Key reference value store.
5728:             *
5729:             * @author Andy Clark, IBM
5730:             */
5731:            protected class KeyRefValueStore extends ValueStoreBase {
5732:
5733:                //
5734:                // Data
5735:                //
5736:
5737:                /** Key value store. */
5738:                protected ValueStoreBase fKeyValueStore;
5739:
5740:                //
5741:                // Constructors
5742:                //
5743:
5744:                /** Constructs a key value store. */
5745:                public KeyRefValueStore(KeyRef keyRef,
5746:                        KeyValueStore keyValueStore) {
5747:                    super (keyRef);
5748:                    fKeyValueStore = keyValueStore;
5749:                } // <init>(KeyRef)
5750:
5751:                //
5752:                // ValueStoreBase methods
5753:                //
5754:
5755:                // end the value Scope; here's where we have to tie
5756:                // up keyRef loose ends.
5757:                public void endDocumentFragment() throws Exception {
5758:
5759:                    // do all the necessary management...
5760:                    super .endDocumentFragment();
5761:
5762:                    // verify references
5763:                    // get the key store corresponding (if it exists):
5764:                    fKeyValueStore = (ValueStoreBase) fValueStoreCache.fGlobalIDConstraintMap
5765:                            .get(((KeyRef) fIdentityConstraint).getKey());
5766:
5767:                    if (fKeyValueStore == null) {
5768:                        // report error
5769:                        int code = SchemaMessageProvider.KeyRefOutOfScope;
5770:                        String value = fIdentityConstraint.toString();
5771:                        reportSchemaError(code, new Object[] { value });
5772:                        return;
5773:                    }
5774:
5775:                    int count = fValueTuples.size();
5776:                    for (int i = 0; i < count; i++) {
5777:                        OrderedHashtable values = (OrderedHashtable) fValueTuples
5778:                                .elementAt(i);
5779:                        if (!fKeyValueStore.contains(values)) {
5780:                            int code = SchemaMessageProvider.KeyNotFound;
5781:                            String value = toString(values);
5782:                            String element = fIdentityConstraint
5783:                                    .getElementName();
5784:                            reportSchemaError(code, new Object[] { value,
5785:                                    element });
5786:                        }
5787:                    }
5788:
5789:                } // endDocumentFragment()
5790:
5791:                /** End document. */
5792:                public void endDocument() throws Exception {
5793:                    super .endDocument();
5794:
5795:                } // endDocument()
5796:
5797:            } // class KeyRefValueStore
5798:
5799:            // value store management
5800:
5801:            /**
5802:             * Value store cache. This class is used to store the values for
5803:             * identity constraints.
5804:             *
5805:             * @author Andy Clark, IBM
5806:             */
5807:            protected class ValueStoreCache {
5808:
5809:                //
5810:                // Data
5811:                //
5812:
5813:                // values stores
5814:
5815:                /** stores all global Values stores. */
5816:                protected final Vector fValueStores = new Vector();
5817:
5818:                /** Values stores associated to specific identity constraints. */
5819:                protected final Hashtable fIdentityConstraint2ValueStoreMap = new Hashtable();
5820:
5821:                // sketch of algorithm:
5822:                // - when a constraint is first encountered, its
5823:                //  values are stored in the (local) fIdentityConstraint2ValueStoreMap;
5824:                // - Once it is validated (i.e., wen it goes out of scope),
5825:                //  its values are merged into the fGlobalIDConstraintMap;
5826:                // - as we encounter keyref's, we look at the global table to
5827:                //  validate them.
5828:                // the fGlobalIDMapStack has the following structure:
5829:                // - validation always occurs against the fGlobalIDConstraintMap
5830:                // (which comprises all the "eligible" id constraints);
5831:                // When an endelement is found, this Hashtable is merged with the one
5832:                // below in the stack.
5833:                // When a start tag is encountered, we create a new
5834:                // fGlobalIDConstraintMap.
5835:                // i.e., the top of the fGlobalIDMapStack always contains
5836:                // the preceding siblings' eligible id constraints;
5837:                // the fGlobalIDConstraintMap contains descendants+self.
5838:                // keyrefs can only match descendants+self.
5839:                protected final Stack fGlobalMapStack = new Stack();
5840:                protected final Hashtable fGlobalIDConstraintMap = new Hashtable();
5841:
5842:                //
5843:                // Constructors
5844:                //
5845:
5846:                /** Default constructor. */
5847:                public ValueStoreCache() {
5848:                } // <init>()
5849:
5850:                //
5851:                // Public methods
5852:                //
5853:
5854:                /** Resets the identity constraint cache. */
5855:                public void startDocument() throws Exception {
5856:                    if (DEBUG_VALUE_STORES) {
5857:                        System.out.println("<VS>: " + toString()
5858:                                + "#startDocument()");
5859:                    }
5860:                    fValueStores.removeAllElements();
5861:                    fIdentityConstraint2ValueStoreMap.clear();
5862:                    fGlobalIDConstraintMap.clear();
5863:                    fGlobalMapStack.removeAllElements();
5864:                } // startDocument()
5865:
5866:                // startElement:  pushes the current fGlobalIDConstraintMap
5867:                // onto fGlobalMapStack and clears fGlobalIDConstraint map.
5868:                public void startElement() {
5869:                    fGlobalMapStack.push(fGlobalIDConstraintMap.clone());
5870:                    fGlobalIDConstraintMap.clear();
5871:                } // startElement(void)
5872:
5873:                // endElement():  merges contents of fGlobalIDConstraintMap with the
5874:                // top of fGlobalMapStack into fGlobalIDConstraintMap.
5875:                public void endElement() {
5876:                    if (fGlobalMapStack.isEmpty())
5877:                        return; // must be an invalid doc!
5878:                    Hashtable oldMap = (Hashtable) fGlobalMapStack.pop();
5879:                    Enumeration keys = oldMap.keys();
5880:                    while (keys.hasMoreElements()) {
5881:                        IdentityConstraint id = (IdentityConstraint) keys
5882:                                .nextElement();
5883:                        ValueStoreBase oldVal = (ValueStoreBase) oldMap.get(id);
5884:                        if (oldVal != null) {
5885:                            ValueStoreBase currVal = (ValueStoreBase) fGlobalIDConstraintMap
5886:                                    .get(id);
5887:                            if (currVal == null)
5888:                                fGlobalIDConstraintMap.put(id, oldVal);
5889:                            else {
5890:                                currVal.append(oldVal);
5891:                                fGlobalIDConstraintMap.put(id, currVal);
5892:                            }
5893:                        }
5894:                    }
5895:                } // endElement()
5896:
5897:                /**
5898:                 * Initializes the value stores for the specified element
5899:                 * declaration.
5900:                 */
5901:                public void initValueStoresFor(XMLElementDecl eDecl)
5902:                        throws Exception {
5903:                    if (DEBUG_VALUE_STORES) {
5904:                        System.out.println("<VS>: " + toString()
5905:                                + "#initValueStoresFor("
5906:                                + fStringPool.toString(eDecl.name.rawname)
5907:                                + ")");
5908:                    }
5909:
5910:                    // initialize value stores for unique fields
5911:                    Vector uVector = eDecl.unique;
5912:                    int uCount = uVector.size();
5913:                    for (int i = 0; i < uCount; i++) {
5914:                        Unique unique = (Unique) uVector.elementAt(i);
5915:                        UniqueValueStore valueStore = (UniqueValueStore) fIdentityConstraint2ValueStoreMap
5916:                                .get(unique);
5917:                        if (valueStore != null) {
5918:                            // NOTE: If already initialized, don't need to
5919:                            //       do it again. -Ac
5920:                            continue;
5921:                        }
5922:                        valueStore = new UniqueValueStore(unique);
5923:                        fValueStores.addElement(valueStore);
5924:                        if (DEBUG_VALUE_STORES) {
5925:                            System.out.println("<VS>: " + unique + " -> "
5926:                                    + valueStore);
5927:                        }
5928:                        fIdentityConstraint2ValueStoreMap.put(unique,
5929:                                valueStore);
5930:                    }
5931:
5932:                    // initialize value stores for key fields
5933:                    Vector kVector = eDecl.key;
5934:                    int kCount = kVector.size();
5935:                    for (int i = 0; i < kCount; i++) {
5936:                        Key key = (Key) kVector.elementAt(i);
5937:                        KeyValueStore valueStore = (KeyValueStore) fIdentityConstraint2ValueStoreMap
5938:                                .get(key);
5939:                        if (valueStore != null) {
5940:                            // NOTE: If already initialized, don't need to
5941:                            //       do it again. -Ac
5942:                            continue;
5943:                        }
5944:                        valueStore = new KeyValueStore(key);
5945:                        fValueStores.addElement(valueStore);
5946:                        if (DEBUG_VALUE_STORES) {
5947:                            System.out.println("<VS>: " + key + " -> "
5948:                                    + valueStore);
5949:                        }
5950:                        fIdentityConstraint2ValueStoreMap.put(key, valueStore);
5951:                    }
5952:
5953:                    // initialize value stores for key reference fields
5954:                    Vector krVector = eDecl.keyRef;
5955:                    int krCount = krVector.size();
5956:                    for (int i = 0; i < krCount; i++) {
5957:                        KeyRef keyRef = (KeyRef) krVector.elementAt(i);
5958:                        KeyRefValueStore keyRefValueStore = new KeyRefValueStore(
5959:                                keyRef, null);
5960:                        fValueStores.addElement(keyRefValueStore);
5961:                        if (DEBUG_VALUE_STORES) {
5962:                            System.out.println("<VS>: " + keyRef + " -> "
5963:                                    + keyRefValueStore);
5964:                        }
5965:                        fIdentityConstraint2ValueStoreMap.put(keyRef,
5966:                                keyRefValueStore);
5967:                    }
5968:
5969:                } // initValueStoresFor(XMLElementDecl)
5970:
5971:                /** Returns the value store associated to the specified field. */
5972:                public ValueStoreBase getValueStoreFor(Field field) {
5973:                    if (DEBUG_VALUE_STORES) {
5974:                        System.out.println("<VS>: " + toString()
5975:                                + "#getValueStoreFor(" + field + ")");
5976:                    }
5977:                    IdentityConstraint identityConstraint = field
5978:                            .getIdentityConstraint();
5979:                    return (ValueStoreBase) fIdentityConstraint2ValueStoreMap
5980:                            .get(identityConstraint);
5981:                } // getValueStoreFor(Field):ValueStoreBase
5982:
5983:                /** Returns the value store associated to the specified IdentityConstraint. */
5984:                public ValueStoreBase getValueStoreFor(IdentityConstraint id) {
5985:                    if (DEBUG_VALUE_STORES) {
5986:                        System.out.println("<VS>: " + toString()
5987:                                + "#getValueStoreFor(" + id + ")");
5988:                    }
5989:                    return (ValueStoreBase) fIdentityConstraint2ValueStoreMap
5990:                            .get(id);
5991:                } // getValueStoreFor(IdentityConstraint):ValueStoreBase
5992:
5993:                /** Returns the global value store associated to the specified IdentityConstraint. */
5994:                public ValueStoreBase getGlobalValueStoreFor(
5995:                        IdentityConstraint id) {
5996:                    if (DEBUG_VALUE_STORES) {
5997:                        System.out.println("<VS>: " + toString()
5998:                                + "#getGlobalValueStoreFor(" + id + ")");
5999:                    }
6000:                    return (ValueStoreBase) fGlobalIDConstraintMap.get(id);
6001:                } // getValueStoreFor(IdentityConstraint):ValueStoreBase
6002:
6003:                // This method takes the contents of the (local) ValueStore
6004:                // associated with id and moves them into the global
6005:                // hashtable, if id is a <unique> or a <key>.
6006:                // If it's a <keyRef>, then we leave it for later.
6007:                public void transplant(IdentityConstraint id) throws Exception {
6008:                    if (id.getType() == IdentityConstraint.KEYREF)
6009:                        return;
6010:                    ValueStoreBase newVals = (ValueStoreBase) fIdentityConstraint2ValueStoreMap
6011:                            .get(id);
6012:                    fIdentityConstraint2ValueStoreMap.remove(id);
6013:                    ValueStoreBase currVals = (ValueStoreBase) fGlobalIDConstraintMap
6014:                            .get(id);
6015:                    if (currVals != null) {
6016:                        currVals.append(newVals);
6017:                        fGlobalIDConstraintMap.put(id, currVals);
6018:                    } else
6019:                        fGlobalIDConstraintMap.put(id, newVals);
6020:
6021:                } // transplant(id)
6022:
6023:                /** Check identity constraints. */
6024:                public void endDocument() throws Exception {
6025:                    if (DEBUG_VALUE_STORES) {
6026:                        System.out.println("<VS>: " + toString()
6027:                                + "#endDocument()");
6028:                    }
6029:
6030:                    int count = fValueStores.size();
6031:                    for (int i = 0; i < count; i++) {
6032:                        ValueStoreBase valueStore = (ValueStoreBase) fValueStores
6033:                                .elementAt(i);
6034:                        valueStore.endDocument();
6035:                    }
6036:
6037:                } // endDocument()
6038:
6039:                //
6040:                // Object methods
6041:                //
6042:
6043:                /** Returns a string representation of this object. */
6044:                public String toString() {
6045:                    String s = super .toString();
6046:                    int index1 = s.lastIndexOf('$');
6047:                    if (index1 != -1) {
6048:                        return s.substring(index1 + 1);
6049:                    }
6050:                    int index2 = s.lastIndexOf('.');
6051:                    if (index2 != -1) {
6052:                        return s.substring(index2 + 1);
6053:                    }
6054:                    return s;
6055:                } // toString():String
6056:
6057:            } // class ValueStoreCache
6058:
6059:            // utility classes
6060:
6061:            /**
6062:             * Ordered hashtable. This class acts as a hashtable with
6063:             * <code>put()</code> and <code>get()</code> operations but also
6064:             * allows values to be queried via the order that they were
6065:             * added to the hashtable.
6066:             * <p>
6067:             * <strong>Note:</strong> This class does not perform any error
6068:             * checking.
6069:             * <p>
6070:             * <strong>Note:</strong> This class is <em>not</em> efficient but
6071:             * is assumed to be used for a very small set of values.
6072:             *
6073:             * @author Andy Clark, IBM
6074:             */
6075:            static final class OrderedHashtable implements  Cloneable {
6076:
6077:                //
6078:                // Data
6079:                //
6080:
6081:                /** Size. */
6082:                private int fSize;
6083:
6084:                /** Hashtable entries. */
6085:                private Entry[] fEntries = null;
6086:
6087:                //
6088:                // Public methods
6089:                //
6090:
6091:                /** Returns the number of entries in the hashtable. */
6092:                public int size() {
6093:                    return fSize;
6094:                } // size():int
6095:
6096:                /** Puts an entry into the hashtable. */
6097:                public void put(Field key, IDValue value) {
6098:                    int index = indexOf(key);
6099:                    if (index == -1) {
6100:                        ensureCapacity(fSize);
6101:                        index = fSize++;
6102:                        fEntries[index].key = key;
6103:                    }
6104:                    fEntries[index].value = value;
6105:                } // put(Field,String)
6106:
6107:                /** Returns the value associated to the specified key. */
6108:                public IDValue get(Field key) {
6109:                    return fEntries[indexOf(key)].value;
6110:                } // get(Field):String
6111:
6112:                /** Returns the index of the entry with the specified key. */
6113:                public int indexOf(Field key) {
6114:                    for (int i = 0; i < fSize; i++) {
6115:                        // NOTE: Only way to be sure that the keys are the
6116:                        //       same is by using a reference comparison. In
6117:                        //       order to rely on the equals method, each
6118:                        //       field would have to take into account its
6119:                        //       position in the identity constraint, the
6120:                        //       identity constraint, the declaring element,
6121:                        //       and the grammar that it is defined in.
6122:                        //       Otherwise, you have the possibility that
6123:                        //       the equals method would return true for two
6124:                        //       fields that look *very* similar.
6125:                        //       The reference compare isn't bad, actually,
6126:                        //       because the field objects are cacheable. -Ac
6127:                        if (fEntries[i].key == key) {
6128:                            return i;
6129:                        }
6130:                    }
6131:                    return -1;
6132:                } // indexOf(Field):int
6133:
6134:                /** Returns the key at the specified index. */
6135:                public Field keyAt(int index) {
6136:                    return fEntries[index].key;
6137:                } // keyAt(int):Field
6138:
6139:                /** Returns the value at the specified index. */
6140:                public IDValue valueAt(int index) {
6141:                    return fEntries[index].value;
6142:                } // valueAt(int):String
6143:
6144:                /** Removes all of the entries from the hashtable. */
6145:                public void clear() {
6146:                    fSize = 0;
6147:                } // clear()
6148:
6149:                //
6150:                // Private methods
6151:                //
6152:
6153:                /** Ensures the capacity of the entries array. */
6154:                private void ensureCapacity(int size) {
6155:
6156:                    // sizes
6157:                    int osize = -1;
6158:                    int nsize = -1;
6159:
6160:                    // create array
6161:                    if (fEntries == null) {
6162:                        osize = 0;
6163:                        nsize = 2;
6164:                        fEntries = new Entry[nsize];
6165:                    }
6166:
6167:                    // resize array
6168:                    else if (fEntries.length <= size) {
6169:                        osize = fEntries.length;
6170:                        nsize = 2 * osize;
6171:                        Entry[] array = new Entry[nsize];
6172:                        System.arraycopy(fEntries, 0, array, 0, osize);
6173:                        fEntries = array;
6174:                    }
6175:
6176:                    // create new entries
6177:                    for (int i = osize; i < nsize; i++) {
6178:                        fEntries[i] = new Entry();
6179:                    }
6180:
6181:                } // ensureCapacity(int)
6182:
6183:                //
6184:                // Cloneable methods
6185:                //
6186:
6187:                /** Clones this object. */
6188:                public Object clone() {
6189:
6190:                    OrderedHashtable hashtable = new OrderedHashtable();
6191:                    for (int i = 0; i < fSize; i++) {
6192:                        hashtable.put(fEntries[i].key, fEntries[i].value);
6193:                    }
6194:                    return hashtable;
6195:
6196:                } // clone():Object
6197:
6198:                //
6199:                // Object methods
6200:                //
6201:
6202:                /** Returns a string representation of this object. */
6203:                public String toString() {
6204:                    if (fSize == 0) {
6205:                        return "[]";
6206:                    }
6207:                    StringBuffer str = new StringBuffer();
6208:                    str.append('[');
6209:                    for (int i = 0; i < fSize; i++) {
6210:                        if (i > 0) {
6211:                            str.append(',');
6212:                        }
6213:                        str.append('{');
6214:                        str.append(fEntries[i].key);
6215:                        str.append(',');
6216:                        str.append(fEntries[i].value);
6217:                        str.append('}');
6218:                    }
6219:                    str.append(']');
6220:                    return str.toString();
6221:                } // toString():String
6222:
6223:                //
6224:                // Classes
6225:                //
6226:
6227:                /**
6228:                 * Hashtable entry.
6229:                 */
6230:                public static final class Entry {
6231:
6232:                    //
6233:                    // Data
6234:                    //
6235:
6236:                    /** Key. */
6237:                    public Field key;
6238:
6239:                    /** Value. */
6240:                    public IDValue value;
6241:
6242:                } // class Entry
6243:
6244:            } // class OrderedHashtable
6245:
6246:        } // class XMLValidator
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.