Source Code Cross Referenced for TraverseSchema.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » xerces » validators » schema » 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.schema 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


00001:        /*
00002:         * The Apache Software License, Version 1.1
00003:         *
00004:         *
00005:         * Copyright (c) 2000,2001 The Apache Software Foundation.
00006:         * All rights reserved.
00007:         *
00008:         * Redistribution and use in source and binary forms, with or without
00009:         * modification, are permitted provided that the following conditions
00010:         * are met:
00011:         *
00012:         * 1. Redistributions of source code must retain the above copyright
00013:         *    notice, this list of conditions and the following disclaimer.
00014:         *
00015:         * 2. Redistributions in binary form must reproduce the above copyright
00016:         *    notice, this list of conditions and the following disclaimer in
00017:         *    the documentation and/or other materials provided with the
00018:         *    distribution.
00019:         *
00020:         * 3. The end-user documentation included with the redistribution,
00021:         *    if any, must include the following acknowledgment:
00022:         *       "This product includes software developed by the
00023:         *        Apache Software Foundation (http://www.apache.org/)."
00024:         *    Alternately, this acknowledgment may appear in the software itself,
00025:         *    if and wherever such third-party acknowledgments normally appear.
00026:         *
00027:         * 4. The names "Xerces" and "Apache Software Foundation" must
00028:         *    not be used to endorse or promote products derived from this
00029:         *    software without prior written permission. For written
00030:         *    permission, please contact apache@apache.org.
00031:         *
00032:         * 5. Products derived from this software may not be called "Apache",
00033:         *    nor may "Apache" appear in their name, without prior written
00034:         *    permission of the Apache Software Foundation.
00035:         *
00036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
00037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00039:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
00040:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
00043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00047:         * SUCH DAMAGE.
00048:         * ====================================================================
00049:         *
00050:         * This software consists of voluntary contributions made by many
00051:         * individuals on behalf of the Apache Software Foundation and was
00052:         * originally based on software copyright (c) 1999, International
00053:         * Business Machines, Inc., http://www.apache.org.  For more
00054:         * information on the Apache Software Foundation, please see
00055:         * <http://www.apache.org/>.
00056:         */
00057:        package org.apache.xerces.validators.schema;
00058:
00059:        import org.apache.xerces.framework.XMLErrorReporter;
00060:        import org.apache.xerces.validators.common.Grammar;
00061:        import org.apache.xerces.validators.common.GrammarResolver;
00062:        import org.apache.xerces.validators.common.GrammarResolverImpl;
00063:        import org.apache.xerces.validators.common.XMLElementDecl;
00064:        import org.apache.xerces.validators.common.XMLAttributeDecl;
00065:        import org.apache.xerces.validators.schema.SchemaSymbols;
00066:        import org.apache.xerces.validators.schema.XUtil;
00067:        import org.apache.xerces.validators.schema.identity.Field;
00068:        import org.apache.xerces.validators.schema.identity.IdentityConstraint;
00069:        import org.apache.xerces.validators.schema.identity.Key;
00070:        import org.apache.xerces.validators.schema.identity.KeyRef;
00071:        import org.apache.xerces.validators.schema.identity.Selector;
00072:        import org.apache.xerces.validators.schema.identity.Unique;
00073:        import org.apache.xerces.validators.schema.identity.XPath;
00074:        import org.apache.xerces.validators.schema.identity.XPathException;
00075:        import org.apache.xerces.validators.datatype.DatatypeValidator;
00076:        import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
00077:        import org.apache.xerces.validators.datatype.IDDatatypeValidator;
00078:        import org.apache.xerces.validators.datatype.NOTATIONDatatypeValidator;
00079:        import org.apache.xerces.validators.datatype.StringDatatypeValidator;
00080:        import org.apache.xerces.validators.datatype.ListDatatypeValidator;
00081:        import org.apache.xerces.validators.datatype.UnionDatatypeValidator;
00082:        import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
00083:        import org.apache.xerces.validators.datatype.AnySimpleType;
00084:        import org.apache.xerces.utils.StringPool;
00085:        import org.w3c.dom.Element;
00086:
00087:        import java.io.IOException;
00088:        import java.util.*;
00089:        import java.net.URL;
00090:        import java.net.MalformedURLException;
00091:
00092:        //REVISIT: for now, import everything in the DOM package
00093:        import org.w3c.dom.*;
00094:
00095:        //Unit Test
00096:        import org.apache.xerces.parsers.DOMParser;
00097:        import org.apache.xerces.validators.common.XMLValidator;
00098:        import org.apache.xerces.validators.datatype.DatatypeValidator.*;
00099:        import org.apache.xerces.validators.datatype.InvalidDatatypeValueException;
00100:        import org.apache.xerces.framework.XMLContentSpec;
00101:        import org.apache.xerces.utils.QName;
00102:        import org.apache.xerces.utils.NamespacesScope;
00103:        import org.apache.xerces.parsers.SAXParser;
00104:        import org.apache.xerces.framework.XMLParser;
00105:        import org.apache.xerces.framework.XMLDocumentScanner;
00106:
00107:        import org.xml.sax.InputSource;
00108:        import org.xml.sax.SAXParseException;
00109:        import org.xml.sax.EntityResolver;
00110:        import org.xml.sax.ErrorHandler;
00111:        import org.xml.sax.SAXException;
00112:        import org.w3c.dom.Document;
00113:        /** Don't check the following code in because it creates a dependency on
00114:         the serializer, preventing to package the parser without the serializer.
00115:         import  org.apache.xml.serialize.OutputFormat;
00116:         import  org.apache.xml.serialize.XMLSerializer;
00117:         **/
00118:        import org.apache.xerces.validators.schema.SchemaSymbols;
00119:
00120:        /**
00121:         * Instances of this class get delegated to Traverse the Schema and
00122:         * to populate the Grammar internal representation by
00123:         * instances of Grammar objects.
00124:         * Traverse a Schema Grammar:
00125:         *
00126:         * @author Eric Ye, IBM
00127:         * @author Jeffrey Rodriguez, IBM
00128:         * @author Andy Clark, IBM
00129:         *
00130:         * @see org.apache.xerces.validators.common.Grammar
00131:         *
00132:         * @version $Id: TraverseSchema.java,v 1.242.2.13 2001/11/12 21:58:43 neilg Exp $
00133:         */
00134:        public class TraverseSchema implements 
00135:                NamespacesScope.NamespacesHandler {
00136:
00137:            //CONSTANTS
00138:            private static final int TOP_LEVEL_SCOPE = -1;
00139:
00140:            /** Identity constraint keywords. */
00141:            private static final String[][] IDENTITY_CONSTRAINTS = {
00142:                    { SchemaSymbols.URI_SCHEMAFORSCHEMA,
00143:                            SchemaSymbols.ELT_UNIQUE },
00144:                    { SchemaSymbols.URI_SCHEMAFORSCHEMA, SchemaSymbols.ELT_KEY },
00145:                    { SchemaSymbols.URI_SCHEMAFORSCHEMA,
00146:                            SchemaSymbols.ELT_KEYREF }, };
00147:            // hopefully a string people will not use in their names very often...
00148:            private static final String redefIdentifier = "_fn3dktizrknc9pi";
00149:            // fields to hold application-specified schemaLocations
00150:            private String fUnparsedExternalSchemas = null;
00151:            private Hashtable fExternalSchemas = null;
00152:            private String fExternalNoNamespaceSchema = null;
00153:            // Flags for handleOccurrences to indicate any special
00154:            // restrictions on minOccurs and maxOccurs relating to "all".
00155:            //    NOT_ALL_CONTEXT    - not processing an <all>
00156:            //    PROCESSING_ALL_EL  - processing an <element> in an <all>
00157:            //    GROUP_REF_WITH_ALL - processing <group> reference that contained <all>
00158:            //    CHILD_OF_GROUP     - processing a child of a model group definition
00159:            //    PROCESSING_ALL_GP  - processing an <all> group itself
00160:            private static final int NOT_ALL_CONTEXT = 0;
00161:            private static final int PROCESSING_ALL_EL = 1;
00162:            private static final int GROUP_REF_WITH_ALL = 2;
00163:            private static final int CHILD_OF_GROUP = 4;
00164:            private static final int PROCESSING_ALL_GP = 8;
00165:
00166:            //debugging
00167:            private static final boolean DEBUGGING = false;
00168:
00169:            /** Compile to true to debug identity constraints. */
00170:            private static final boolean DEBUG_IDENTITY_CONSTRAINTS = false;
00171:            private static final boolean DEBUG_NEW_GROUP = true;
00172:
00173:            /**
00174:             * Compile to true to debug datatype validator lookup for
00175:             * identity constraint support.
00176:             */
00177:            private static final boolean DEBUG_IC_DATATYPES = false;
00178:
00179:            //private data members
00180:
00181:            private boolean fFullConstraintChecking = false;
00182:
00183:            private XMLErrorReporter fErrorReporter = null;
00184:            private StringPool fStringPool = null;
00185:
00186:            private GrammarResolver fGrammarResolver = null;
00187:            private SchemaGrammar fSchemaGrammar = null;
00188:
00189:            private Element fSchemaRootElement;
00190:            // this is always set to refer to the root of the linked list containing the root info of schemas under redefinition.
00191:            private SchemaInfo fSchemaInfoListRoot = null;
00192:            private SchemaInfo fCurrentSchemaInfo = null;
00193:            private boolean fRedefineSucceeded;
00194:
00195:            private DatatypeValidatorFactoryImpl fDatatypeRegistry = null;
00196:
00197:            private Hashtable fComplexTypeRegistry = new Hashtable();
00198:            private Hashtable fAttributeDeclRegistry = new Hashtable();
00199:
00200:            // stores the names of groups that we've traversed so we can avoid multiple traversals
00201:            // qualified group names are keys and their contentSpecIndexes are values.
00202:            private Hashtable fGroupNameRegistry = new Hashtable();
00203:            // this Hashtable keeps track of whether a given redefined group does so by restriction.
00204:            private Hashtable fRestrictedRedefinedGroupRegistry = new Hashtable();
00205:
00206:            // stores "final" values of simpleTypes--no clean way to integrate this into the existing datatype validation structure...
00207:            private Hashtable fSimpleTypeFinalRegistry = new Hashtable();
00208:
00209:            // stores <notation> decl
00210:            private Hashtable fNotationRegistry = new Hashtable();
00211:
00212:            private Vector fIncludeLocations = new Vector();
00213:            private Vector fImportLocations = new Vector();
00214:            private Hashtable fRedefineLocations = new Hashtable();
00215:            private Vector fTraversedRedefineElements = new Vector();
00216:            // Hashtable associating attributeGroups within a <redefine> which
00217:            // restrict attributeGroups in the original schema with the
00218:            // new name for those groups in the modified redefined schema.
00219:            private Hashtable fRedefineAttributeGroupMap = null;
00220:
00221:            // simpleType data
00222:            private Hashtable fFacetData = new Hashtable(10);
00223:            private Stack fSimpleTypeNameStack = new Stack();
00224:            private String fListName = "";
00225:
00226:            private int fAnonTypeCount = 0;
00227:            private int fScopeCount = 0;
00228:            private int fCurrentScope = TOP_LEVEL_SCOPE;
00229:            private int fSimpleTypeAnonCount = 0;
00230:            private Stack fCurrentTypeNameStack = new Stack();
00231:            private Stack fBaseTypeNameStack = new Stack();
00232:            private Stack fCurrentGroupNameStack = new Stack();
00233:            private Vector fElementRecurseComplex = new Vector();
00234:            private Vector fTopLevelElementsRefdFromGroup = new Vector();
00235:            private Stack fCurrentAttrGroupNameStack = new Stack();
00236:
00237:            private Vector fSubstitutionGroupRecursionRegistry = new Vector();
00238:            private boolean fElementDefaultQualified = false;
00239:            private boolean fAttributeDefaultQualified = false;
00240:            private int fBlockDefault = 0;
00241:            private int fFinalDefault = 0;
00242:
00243:            private int fTargetNSURI;
00244:            private String fTargetNSURIString = "";
00245:            private NamespacesScope fNamespacesScope = null;
00246:            private String fCurrentSchemaURL = "";
00247:            private Stack fSchemaURLStack = new Stack();
00248:
00249:            private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
00250:            private XMLAttributeDecl fTemp2AttributeDecl = new XMLAttributeDecl();
00251:            private XMLElementDecl fTempElementDecl = new XMLElementDecl();
00252:            private XMLElementDecl fTempElementDecl2 = new XMLElementDecl();
00253:            private XMLContentSpec tempContentSpec1 = new XMLContentSpec();
00254:            private XMLContentSpec tempContentSpec2 = new XMLContentSpec();
00255:
00256:            private EntityResolver fEntityResolver = null;
00257:            private SubstitutionGroupComparator fSComp = null;
00258:
00259:            private Hashtable fIdentityConstraints = new Hashtable();
00260:            // Yet one more data structure; this one associates
00261:            // <unique> and <key> QNames with their corresponding objects,
00262:            // so that <keyRef>s can find them.
00263:            private Hashtable fIdentityConstraintNames = new Hashtable();
00264:
00265:            // General Attribute Checking
00266:            private GeneralAttrCheck fGeneralAttrCheck = null;
00267:            private int fXsiURI;
00268:
00269:            // REVISIT: maybe need to be moved into SchemaGrammar class
00270:            public class ComplexTypeInfo {
00271:                public String typeName;
00272:
00273:                public DatatypeValidator baseDataTypeValidator;
00274:                public ComplexTypeInfo baseComplexTypeInfo;
00275:
00276:                public int derivedBy = 0;
00277:                public int blockSet = 0;
00278:                public int finalSet = 0;
00279:
00280:                public int miscFlags = 0;
00281:
00282:                public int scopeDefined = -1;
00283:
00284:                public int contentType;
00285:                public int contentSpecHandle = -1;
00286:                public int templateElementIndex = -1;
00287:                public int attlistHead = -1;
00288:                public DatatypeValidator datatypeValidator;
00289:
00290:                public boolean isAbstractType() {
00291:                    return ((miscFlags & CT_IS_ABSTRACT) != 0);
00292:                }
00293:
00294:                public boolean containsAttrTypeID() {
00295:                    return ((miscFlags & CT_CONTAINS_ATTR_TYPE_ID) != 0);
00296:                }
00297:
00298:                public boolean declSeen() {
00299:                    return ((miscFlags & CT_DECL_SEEN) != 0);
00300:                }
00301:
00302:                public void setIsAbstractType() {
00303:                    miscFlags |= CT_IS_ABSTRACT;
00304:                }
00305:
00306:                public void setContainsAttrTypeID() {
00307:                    miscFlags |= CT_CONTAINS_ATTR_TYPE_ID;
00308:                }
00309:
00310:                public void setDeclSeen() {
00311:                    miscFlags |= CT_DECL_SEEN;
00312:                }
00313:
00314:            }
00315:
00316:            private static final int CT_IS_ABSTRACT = 1;
00317:            private static final int CT_CONTAINS_ATTR_TYPE_ID = 2;
00318:            private static final int CT_DECL_SEEN = 4; // indicates that the declaration was
00319:
00320:            // traversed as opposed to processed due
00321:            // to a forward reference
00322:
00323:            private class ComplexTypeRecoverableError extends Exception {
00324:                ComplexTypeRecoverableError() {
00325:                    super ();
00326:                }
00327:
00328:                ComplexTypeRecoverableError(String s) {
00329:                    super (s);
00330:                }
00331:            }
00332:
00333:            private class ParticleRecoverableError extends Exception {
00334:                ParticleRecoverableError(String s) {
00335:                    super (s);
00336:                }
00337:            }
00338:
00339:            private class GroupInfo {
00340:                int contentSpecIndex = -1;
00341:                int scope = -1;
00342:            }
00343:
00344:            private class ElementInfo {
00345:                int elementIndex;
00346:                String typeName;
00347:
00348:                private ElementInfo(int i, String name) {
00349:                    elementIndex = i;
00350:                    typeName = name;
00351:                }
00352:            }
00353:
00354:            //REVISIT: verify the URI.
00355:            public final static String SchemaForSchemaURI = "http://www.w3.org/TR-1/Schema";
00356:
00357:            private TraverseSchema() {
00358:                // new TraverseSchema() is forbidden;
00359:            }
00360:
00361:            public void setFullConstraintCheckingEnabled() {
00362:                fFullConstraintChecking = true;
00363:            }
00364:
00365:            public void setGrammarResolver(GrammarResolver grammarResolver) {
00366:                fGrammarResolver = grammarResolver;
00367:            }
00368:
00369:            public void startNamespaceDeclScope(int prefix, int uri) {
00370:                //TO DO
00371:            }
00372:
00373:            public void endNamespaceDeclScope(int prefix) {
00374:                //TO DO, do we need to do anything here?
00375:            }
00376:
00377:            public boolean particleEmptiable(int contentSpecIndex) {
00378:
00379:                if (!fFullConstraintChecking) {
00380:                    return true;
00381:                }
00382:                if (minEffectiveTotalRange(contentSpecIndex) == 0)
00383:                    return true;
00384:                else
00385:                    return false;
00386:            }
00387:
00388:            public int minEffectiveTotalRange(int contentSpecIndex) {
00389:
00390:                fSchemaGrammar.getContentSpec(contentSpecIndex,
00391:                        tempContentSpec1);
00392:                int type = tempContentSpec1.type;
00393:                if (type == XMLContentSpec.CONTENTSPECNODE_SEQ
00394:                        || type == XMLContentSpec.CONTENTSPECNODE_ALL) {
00395:                    return minEffectiveTotalRangeSeq(contentSpecIndex);
00396:                } else if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
00397:                    return minEffectiveTotalRangeChoice(contentSpecIndex);
00398:                } else {
00399:                    return (fSchemaGrammar
00400:                            .getContentSpecMinOccurs(contentSpecIndex));
00401:                }
00402:
00403:            }
00404:
00405:            private int minEffectiveTotalRangeSeq(int csIndex) {
00406:
00407:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
00408:                int type = tempContentSpec1.type;
00409:                int left = tempContentSpec1.value;
00410:                int right = tempContentSpec1.otherValue;
00411:                int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
00412:
00413:                int result;
00414:                if (right == -2)
00415:                    result = min * minEffectiveTotalRange(left);
00416:                else
00417:                    result = min
00418:                            * (minEffectiveTotalRange(left) + minEffectiveTotalRange(right));
00419:                return result;
00420:
00421:            }
00422:
00423:            private int minEffectiveTotalRangeChoice(int csIndex) {
00424:
00425:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
00426:                int type = tempContentSpec1.type;
00427:                int left = tempContentSpec1.value;
00428:                int right = tempContentSpec1.otherValue;
00429:                int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
00430:
00431:                int result;
00432:                if (right == -2)
00433:                    result = min * minEffectiveTotalRange(left);
00434:                else {
00435:                    int minLeft = minEffectiveTotalRange(left);
00436:                    int minRight = minEffectiveTotalRange(right);
00437:                    result = min * ((minLeft < minRight) ? minLeft : minRight);
00438:                }
00439:                return result;
00440:            }
00441:
00442:            public int maxEffectiveTotalRange(int contentSpecIndex) {
00443:
00444:                fSchemaGrammar.getContentSpec(contentSpecIndex,
00445:                        tempContentSpec1);
00446:                int type = tempContentSpec1.type;
00447:                if (type == XMLContentSpec.CONTENTSPECNODE_SEQ
00448:                        || type == XMLContentSpec.CONTENTSPECNODE_ALL) {
00449:                    return maxEffectiveTotalRangeSeq(contentSpecIndex);
00450:                } else if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
00451:                    return maxEffectiveTotalRangeChoice(contentSpecIndex);
00452:                } else {
00453:                    return (fSchemaGrammar
00454:                            .getContentSpecMaxOccurs(contentSpecIndex));
00455:                }
00456:
00457:            }
00458:
00459:            private int maxEffectiveTotalRangeSeq(int csIndex) {
00460:
00461:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
00462:                int type = tempContentSpec1.type;
00463:                int left = tempContentSpec1.value;
00464:                int right = tempContentSpec1.otherValue;
00465:                int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
00466:
00467:                if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00468:                    return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00469:
00470:                int maxLeft = maxEffectiveTotalRange(left);
00471:                if (right == -2) {
00472:                    if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00473:                        return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00474:                    else
00475:                        return max * maxLeft;
00476:                } else {
00477:                    int maxRight = maxEffectiveTotalRange(right);
00478:                    if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED
00479:                            || maxRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00480:                        return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00481:                    else
00482:                        return max * (maxLeft + maxRight);
00483:                }
00484:            }
00485:
00486:            private int maxEffectiveTotalRangeChoice(int csIndex) {
00487:
00488:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
00489:                int type = tempContentSpec1.type;
00490:                int left = tempContentSpec1.value;
00491:                int right = tempContentSpec1.otherValue;
00492:                int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
00493:
00494:                if (max == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00495:                    return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00496:
00497:                int maxLeft = maxEffectiveTotalRange(left);
00498:                if (right == -2) {
00499:                    if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00500:                        return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00501:                    else
00502:                        return max * maxLeft;
00503:                } else {
00504:                    int maxRight = maxEffectiveTotalRange(right);
00505:                    if (maxLeft == SchemaSymbols.OCCURRENCE_UNBOUNDED
00506:                            || maxRight == SchemaSymbols.OCCURRENCE_UNBOUNDED)
00507:                        return SchemaSymbols.OCCURRENCE_UNBOUNDED;
00508:                    else
00509:                        return max
00510:                                * ((maxLeft > maxRight) ? maxLeft : maxRight);
00511:                }
00512:            }
00513:
00514:            private String resolvePrefixToURI(String prefix) throws Exception {
00515:                String uriStr = fStringPool.toString(fNamespacesScope
00516:                        .getNamespaceForPrefix(fStringPool.addSymbol(prefix)));
00517:                if (uriStr.length() == 0 && prefix.length() > 0) {
00518:                    // REVISIT: Localize
00519:                    reportGenericSchemaError("prefix : [" + prefix
00520:                            + "] cannot be resolved to a URI");
00521:                    return "";
00522:                }
00523:
00524:                return uriStr;
00525:            }
00526:
00527:            public TraverseSchema(Element root, StringPool stringPool,
00528:                    SchemaGrammar schemaGrammar,
00529:                    GrammarResolver grammarResolver,
00530:                    XMLErrorReporter errorReporter, String schemaURL,
00531:                    EntityResolver entityResolver, boolean fullChecking,
00532:                    GeneralAttrCheck generalAttrCheck,
00533:                    String externalSchemaLocations,
00534:                    String noNamespaceSchemaLocation) throws Exception {
00535:                fErrorReporter = errorReporter;
00536:                fCurrentSchemaURL = schemaURL;
00537:                fFullConstraintChecking = fullChecking;
00538:                fEntityResolver = entityResolver;
00539:                fGeneralAttrCheck = generalAttrCheck;
00540:                fUnparsedExternalSchemas = externalSchemaLocations;
00541:                if (externalSchemaLocations != null) {
00542:                    StringTokenizer tokenizer = new StringTokenizer(
00543:                            externalSchemaLocations, " \n\t\r", false);
00544:                    int tokenTotal = tokenizer.countTokens();
00545:                    if (tokenTotal % 2 == 0) {
00546:                        fExternalSchemas = new Hashtable();
00547:                        String uri = null;
00548:                        String location = null;
00549:                        while (tokenizer.hasMoreTokens()) {
00550:                            uri = tokenizer.nextToken();
00551:                            location = tokenizer.nextToken();
00552:                            fExternalSchemas.put(location, uri);
00553:                        }
00554:                    }
00555:                }
00556:                fExternalNoNamespaceSchema = noNamespaceSchemaLocation;
00557:                doTraverseSchema(root, stringPool, schemaGrammar,
00558:                        grammarResolver);
00559:            }
00560:
00561:            public TraverseSchema(Element root, StringPool stringPool,
00562:                    SchemaGrammar schemaGrammar,
00563:                    GrammarResolver grammarResolver,
00564:                    XMLErrorReporter errorReporter, String schemaURL,
00565:                    boolean fullChecking, GeneralAttrCheck generalAttrCheck)
00566:                    throws Exception {
00567:                fErrorReporter = errorReporter;
00568:                fCurrentSchemaURL = schemaURL;
00569:                fFullConstraintChecking = fullChecking;
00570:                fGeneralAttrCheck = generalAttrCheck;
00571:                doTraverseSchema(root, stringPool, schemaGrammar,
00572:                        grammarResolver);
00573:            }
00574:
00575:            public TraverseSchema(Element root, StringPool stringPool,
00576:                    SchemaGrammar schemaGrammar,
00577:                    GrammarResolver grammarResolver, boolean fullChecking,
00578:                    GeneralAttrCheck generalAttrCheck) throws Exception {
00579:                fFullConstraintChecking = fullChecking;
00580:                fGeneralAttrCheck = generalAttrCheck;
00581:                doTraverseSchema(root, stringPool, schemaGrammar,
00582:                        grammarResolver);
00583:            }
00584:
00585:            public  void doTraverseSchema(Element root, StringPool stringPool,
00586:                           SchemaGrammar schemaGrammar,
00587:                           GrammarResolver grammarResolver) throws Exception {
00588:
00589:
00590:        fSchemaRootElement = root;
00591:        fStringPool = stringPool;
00592:        fSchemaGrammar = schemaGrammar;
00593:        fNamespacesScope = new NamespacesScope(this );
00594:        fNamespacesScope.setNamespaceForPrefix(fStringPool.addSymbol("xml"), fStringPool.addSymbol("http://www.w3.org/XML/1998/namespace"));
00595:
00596:        if (fFullConstraintChecking) {
00597:          fSchemaGrammar.setDeferContentSpecExpansion();
00598:          fSchemaGrammar.setCheckUniqueParticleAttribution();
00599:        }
00600:
00601:        fGrammarResolver = grammarResolver;
00602:        fDatatypeRegistry = (DatatypeValidatorFactoryImpl) fGrammarResolver.getDatatypeRegistry();
00603:
00604:        //Expand to registry type to contain all primitive datatype
00605:        fDatatypeRegistry.expandRegistryToFullSchemaSet();
00606:
00607:        fXsiURI = fStringPool.addSymbol(SchemaSymbols.URI_XSI);
00608:
00609:        if (root == null) {
00610:            // REVISIT: Anything to do?
00611:            return;
00612:        }
00613:
00614:        // General Attribute Checking
00615:        int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
00616:        Hashtable attrValues = generalCheck(root, scope);
00617:
00618:        //Retrieve the targetNamespace URI information
00619:        fTargetNSURIString = getTargetNamespaceString(root);
00620:        fTargetNSURI = fStringPool.addSymbol(fTargetNSURIString);
00621:
00622:        if (fGrammarResolver == null) {
00623:            // REVISIT: Localize
00624:            reportGenericSchemaError("Internal error: don't have a GrammarResolver for TraverseSchema");
00625:        }
00626:        else{
00627:            // for complex type registry, attribute decl registry and
00628:            // namespace mapping, needs to check whether the passed in
00629:            // Grammar was a newly instantiated one.
00630:            if (fSchemaGrammar.getComplexTypeRegistry() == null ) {
00631:                fSchemaGrammar.setComplexTypeRegistry(fComplexTypeRegistry);
00632:            }
00633:            else {
00634:                fComplexTypeRegistry = fSchemaGrammar.getComplexTypeRegistry();
00635:            }
00636:
00637:            if (fSchemaGrammar.getAttributeDeclRegistry() == null ) {
00638:                fSchemaGrammar.setAttributeDeclRegistry(fAttributeDeclRegistry);
00639:            }
00640:            else {
00641:                fAttributeDeclRegistry = fSchemaGrammar.getAttributeDeclRegistry();
00642:            }
00643:
00644:            if (fSchemaGrammar.getNamespacesScope() == null ) {
00645:                fSchemaGrammar.setNamespacesScope(fNamespacesScope);
00646:            }
00647:            else {
00648:                fNamespacesScope = fSchemaGrammar.getNamespacesScope();
00649:            }
00650:
00651:            fSchemaGrammar.setDatatypeRegistry(fDatatypeRegistry);
00652:            fSchemaGrammar.setTargetNamespaceURI(fTargetNSURIString);
00653:            fGrammarResolver.putGrammar(fTargetNSURIString, fSchemaGrammar);
00654:        }
00655:
00656:
00657:
00658:        // Retrived the Namespace mapping from the schema element.
00659:        NamedNodeMap schemaEltAttrs = root.getAttributes();
00660:        int i = 0;
00661:        Attr sattr = null;
00662:
00663:        boolean seenXMLNS = false;
00664:        while ((sattr = (Attr)schemaEltAttrs.item(i++)) != null) {
00665:            String attName = sattr.getName();
00666:            if (attName.startsWith("xmlns:")) {
00667:                String attValue = sattr.getValue();
00668:                String prefix = attName.substring(attName.indexOf(":")+1);
00669:                fNamespacesScope.setNamespaceForPrefix( fStringPool.addSymbol(prefix),
00670:                                                        fStringPool.addSymbol(attValue) );
00671:            }
00672:            if (attName.equals("xmlns")) {
00673:
00674:                String attValue = sattr.getValue();
00675:                fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
00676:                                                        fStringPool.addSymbol(attValue) );
00677:                seenXMLNS = true;
00678:            }
00679:
00680:        }
00681:        if (!seenXMLNS && fTargetNSURIString.length() == 0 ) {
00682:            fNamespacesScope.setNamespaceForPrefix( StringPool.EMPTY_STRING,
00683:                                                    StringPool.EMPTY_STRING);
00684:        }
00685:
00686:        fElementDefaultQualified =
00687:            root.getAttribute(SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
00688:        fAttributeDefaultQualified =
00689:            root.getAttribute(SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols.ATTVAL_QUALIFIED);
00690:        Attr blockAttr = root.getAttributeNode(SchemaSymbols.ATT_BLOCKDEFAULT);
00691:        if (blockAttr == null)
00692:            fBlockDefault = 0;
00693:        else
00694:            fBlockDefault =
00695:                parseBlockSet(blockAttr.getValue());
00696:        Attr finalAttr = root.getAttributeNode(SchemaSymbols.ATT_FINALDEFAULT);
00697:        if (finalAttr == null)
00698:            fFinalDefault = 0;
00699:        else
00700:            fFinalDefault =
00701:                parseFinalSet(finalAttr.getValue());
00702:
00703:        //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
00704:        if (fTargetNSURI == StringPool.EMPTY_STRING) {
00705:            //fElementDefaultQualified = true;
00706:            //fAttributeDefaultQualified = true;
00707:        }
00708:
00709:
00710:        //fScopeCount++;
00711:        // fCurrentScope = -1;
00712:
00713:
00714:        //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
00715:        extractTopLevel3Components(root);
00716:
00717:        // process <redefine>, <include> and <import> info items.
00718:        Element child = XUtil.getFirstChildElement(root);
00719:        for (; child != null;
00720:            child = XUtil.getNextSiblingElement(child)) {
00721:
00722:            String name = child.getLocalName();
00723:            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
00724:                traverseAnnotationDecl(child);
00725:            } else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
00726:                fNamespacesScope.increaseDepth();
00727:                traverseInclude(child);
00728:                fNamespacesScope.decreaseDepth();
00729:            } else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
00730:                traverseImport(child);
00731:            } else if (name.equals(SchemaSymbols.ELT_REDEFINE)) {
00732:                fRedefineSucceeded = true; // presume worked until proven failed.
00733:                traverseRedefine(child);
00734:            } else
00735:                break;
00736:        }
00737:
00738:        // child refers to the first info item which is not <annotation> or
00739:        // one of the schema inclusion/importation declarations.
00740:        for (; child != null;
00741:            child = XUtil.getNextSiblingElement(child)) {
00742:
00743:            String name = child.getLocalName();
00744:            if (name.equals(SchemaSymbols.ELT_ANNOTATION) ) {
00745:                traverseAnnotationDecl(child);
00746:            } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE )) {
00747:                traverseSimpleTypeDecl(child);
00748:            } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE )) {
00749:                traverseComplexTypeDecl(child);
00750:            } else if (name.equals(SchemaSymbols.ELT_ELEMENT )) {
00751:                traverseElementDecl(child);
00752:            } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
00753:                traverseAttributeGroupDecl(child, null, null);
00754:            } else if (name.equals( SchemaSymbols.ELT_ATTRIBUTE ) ) {
00755:                traverseAttributeDecl( child, null, false );
00756:            } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
00757:                traverseGroupDecl(child);
00758:            } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
00759:                traverseNotationDecl(child); //TO DO
00760:            } else {
00761:                // REVISIT: Localize
00762:                reportGenericSchemaError("error in content of <schema> element information item");
00763:            }
00764:        } // for each child node
00765:
00766:        // handle identity constraints
00767:        // we must traverse <key>s and <unique>s before we tackel<keyref>s,
00768:        // since all have global scope and may be declared anywhere in the schema.
00769:        Enumeration elementIndexes = fIdentityConstraints.keys();
00770:        while (elementIndexes.hasMoreElements()) {
00771:            Integer elementIndexObj = (Integer)elementIndexes.nextElement();
00772:            if (DEBUG_IC_DATATYPES) {
00773:                System.out.println("<ICD>: traversing identity constraints for element: "+elementIndexObj);
00774:            }
00775:            Vector identityConstraints = (Vector)fIdentityConstraints.get(elementIndexObj);
00776:            if (identityConstraints != null) {
00777:                int elementIndex = elementIndexObj.intValue();
00778:                traverseIdentityNameConstraintsFor(elementIndex, identityConstraints);
00779:            }
00780:        }
00781:        elementIndexes = fIdentityConstraints.keys();
00782:        while (elementIndexes.hasMoreElements()) {
00783:            Integer elementIndexObj = (Integer)elementIndexes.nextElement();
00784:            if (DEBUG_IC_DATATYPES) {
00785:                System.out.println("<ICD>: traversing identity constraints for element: "+elementIndexObj);
00786:            }
00787:            Vector identityConstraints = (Vector)fIdentityConstraints.get(elementIndexObj);
00788:            if (identityConstraints != null) {
00789:                int elementIndex = elementIndexObj.intValue();
00790:                traverseIdentityRefConstraintsFor(elementIndex, identityConstraints);
00791:            }
00792:        }
00793:
00794:        // At this point, we can do any remaining checking for cos-element-consistent
00795:        // that involves substitution group elements
00796:
00797:        if (fFullConstraintChecking) {
00798:            // Loop thru all of the top-level elements that were ref'd from groups or
00799:            // complexTypes, and ensure that:
00800:            // 1. they have consistent type as any local element potentially declared in
00801:            //    the group/type
00802:            // 2.  any substitutable elements are consistent wrt type given any
00803:            //     similiarly named elements from the group scope
00804:            // Note: for a complexType, we don't check against base scope.   Not clear if
00805:            // we need to.
00806:
00807:            for (int j = 0; j < fTopLevelElementsRefdFromGroup.size(); j+=2) {
00808:               QName eltName = (QName)fTopLevelElementsRefdFromGroup.elementAt(j);
00809:               int groupScope = ((Integer)fTopLevelElementsRefdFromGroup.elementAt(j+1)).intValue();
00810:               checkConsistentElements(eltName, groupScope);
00811:            }
00812:
00813:            // Loop thru all of the complexTypes, and for any derived by restriction,
00814:            // do particle derivation checking
00815:            int count = fComplexTypeRegistry.size();
00816:            Enumeration enum = fComplexTypeRegistry.elements();
00817:
00818:            ComplexTypeInfo typeInfo,baseTypeInfo;
00819:            while (enum.hasMoreElements ()) {
00820:               typeInfo = (TraverseSchema.ComplexTypeInfo)enum.nextElement();
00821:               baseTypeInfo = typeInfo.baseComplexTypeInfo;
00822:
00823:               if (typeInfo.derivedBy == SchemaSymbols.RESTRICTION &&
00824:                   baseTypeInfo!=null &&
00825:                   typeInfo.contentSpecHandle>-1) {
00826:                 try {
00827:                    checkParticleDerivationOK(typeInfo.contentSpecHandle,
00828:                         typeInfo.scopeDefined, baseTypeInfo.contentSpecHandle,
00829:                         baseTypeInfo.scopeDefined,baseTypeInfo);
00830:                 }
00831:                 catch (ParticleRecoverableError e) {
00832:                    String message = e.getMessage();
00833:                    reportGenericSchemaError("ComplexType '" + typeInfo.typeName + "': " + message);
00834:                 }
00835:               }
00836:            }
00837:
00838:        }
00839:
00840:    } // traverseSchema(Element)
00841:
00842:            private void extractTopLevel3Components(Element root)
00843:                    throws Exception {
00844:
00845:                for (Element child = XUtil.getFirstChildElement(root); child != null; child = XUtil
00846:                        .getNextSiblingElement(child)) {
00847:
00848:                    String name = child.getLocalName();
00849:                    String compName = child
00850:                            .getAttribute(SchemaSymbols.ATT_NAME);
00851:                    if (name.equals(SchemaSymbols.ELT_ELEMENT)) {
00852:                        // Check if the element has already been declared
00853:                        if (fSchemaGrammar.topLevelElemDecls.get(compName) != null) {
00854:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for an element "
00855:                                    + compName);
00856:                        } else {
00857:                            fSchemaGrammar.topLevelElemDecls.put(compName,
00858:                                    child);
00859:                        }
00860:                    } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE)
00861:                            || name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
00862:                        // Check for dublicate declaration
00863:                        if (fSchemaGrammar.topLevelTypeDecls.get(compName) != null) {
00864:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for a type "
00865:                                    + compName);
00866:                        } else {
00867:                            fSchemaGrammar.topLevelTypeDecls.put(compName,
00868:                                    child);
00869:                        }
00870:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
00871:                        // Check for dublicate declaration
00872:                        if (fSchemaGrammar.topLevelAttrGrpDecls.get(compName) != null) {
00873:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for an attribute group "
00874:                                    + compName);
00875:                        } else {
00876:                            fSchemaGrammar.topLevelAttrGrpDecls.put(compName,
00877:                                    child);
00878:                        }
00879:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
00880:                        // Check for dublicate declaration
00881:                        if (fSchemaGrammar.topLevelAttrGrpDecls.get(compName) != null) {
00882:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for an attribute "
00883:                                    + compName);
00884:                        } else {
00885:                            fSchemaGrammar.topLevelAttrGrpDecls.put(compName,
00886:                                    child);
00887:                        }
00888:                    } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
00889:                        // Check if the group has already been declared
00890:                        if (fSchemaGrammar.topLevelGroupDecls.get(compName) != null) {
00891:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for a group "
00892:                                    + compName);
00893:                        } else {
00894:                            fSchemaGrammar.topLevelGroupDecls.put(compName,
00895:                                    child);
00896:                        }
00897:                    } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
00898:                        // Check for dublicate declaration
00899:                        if (fSchemaGrammar.topLevelNotationDecls.get(compName) != null) {
00900:                            reportGenericSchemaError("sch-props-correct: Duplicate declaration for a notation "
00901:                                    + compName);
00902:                        } else {
00903:                            fSchemaGrammar.topLevelNotationDecls.put(compName,
00904:                                    child);
00905:                        }
00906:                    }
00907:                } // for each child node
00908:            }
00909:
00910:            private void checkConsistentElements(QName eltName, int scope)
00911:                    throws Exception {
00912:
00913:                // See if there is a declaration of an element with the same name at the
00914:                // given scope.
00915:                // This is required because any model group cannot have more than 1
00916:                // element with the same name, but different types (even if some are
00917:                // local, and others top-level)
00918:
00919:                fTempElementDecl.clear();
00920:                int topLevelElementNdx = fSchemaGrammar.getElementDeclIndex(
00921:                        eltName, TOP_LEVEL_SCOPE);
00922:                if (topLevelElementNdx < 0)
00923:                    return;
00924:
00925:                fSchemaGrammar.getElementDecl(topLevelElementNdx,
00926:                        fTempElementDecl);
00927:                DatatypeValidator edv = fTempElementDecl.datatypeValidator;
00928:                ComplexTypeInfo eTypeInfo = fSchemaGrammar
00929:                        .getElementComplexTypeInfo(topLevelElementNdx);
00930:                int existingEltNdx = fSchemaGrammar.getElementDeclIndex(
00931:                        eltName.uri, eltName.localpart, scope);
00932:                if (existingEltNdx > -1) {
00933:                    if (!checkDuplicateElementTypes(existingEltNdx, eTypeInfo,
00934:                            edv))
00935:
00936:                        reportGenericSchemaError("duplicate element decl in the same scope with different types : "
00937:                                + fStringPool.toString(eltName.localpart));
00938:                }
00939:
00940:                Vector substitutableNames = fSchemaGrammar
00941:                        .getElementDeclAllSubstitutionGroupQNames(
00942:                                topLevelElementNdx, fGrammarResolver,
00943:                                fStringPool);
00944:
00945:                for (int i = 0; i < substitutableNames.size(); i++) {
00946:                    SchemaGrammar.OneSubGroup subGroup = (SchemaGrammar.OneSubGroup) substitutableNames
00947:                            .elementAt(i);
00948:                    QName substName = subGroup.name;
00949:                    int substEltNdx = subGroup.eleIndex;
00950:
00951:                    int localEltNdx = fSchemaGrammar.getElementDeclIndex(
00952:                            substName, scope);
00953:                    if (localEltNdx > -1) {
00954:                        fSchemaGrammar.getElementDecl(localEltNdx,
00955:                                fTempElementDecl);
00956:                        edv = fTempElementDecl.datatypeValidator;
00957:                        eTypeInfo = fSchemaGrammar
00958:                                .getElementComplexTypeInfo(localEltNdx);
00959:                        if (!checkDuplicateElementTypes(substEltNdx, eTypeInfo,
00960:                                edv))
00961:                            reportGenericSchemaError("duplicate element decl in the same scope with different types : "
00962:                                    + fStringPool.toString(substName.localpart));
00963:                    }
00964:                }
00965:
00966:            }
00967:
00968:            /**
00969:             * Expands a system id and returns the system id as a URL, if
00970:             * it can be expanded. A return value of null means that the
00971:             * identifier is already expanded. An exception thrown
00972:             * indicates a failure to expand the id.
00973:             *
00974:             * @param systemId The systemId to be expanded.
00975:             *
00976:             * @return Returns the URL object representing the expanded system
00977:             *         identifier. A null value indicates that the given
00978:             *         system identifier is already expanded.
00979:             *
00980:             */
00981:            private String expandSystemId(String systemId,
00982:                    String currentSystemId) throws Exception {
00983:                String id = systemId;
00984:
00985:                // check for bad parameters id
00986:                if (id == null || id.length() == 0) {
00987:                    return systemId;
00988:                }
00989:
00990:                // if id already expanded, return
00991:                try {
00992:                    URL url = new URL(id);
00993:                    if (url != null) {
00994:                        return systemId;
00995:                    }
00996:                } catch (MalformedURLException e) {
00997:                    // continue on...
00998:                }
00999:
01000:                // normalize id
01001:                id = fixURI(id);
01002:
01003:                // normalize base
01004:                URL base = null;
01005:                URL url = null;
01006:                try {
01007:                    if (currentSystemId == null) {
01008:                        String dir;
01009:                        try {
01010:                            dir = fixURI(System.getProperty("user.dir"));
01011:                        } catch (SecurityException se) {
01012:                            dir = "";
01013:                        }
01014:                        if (!dir.endsWith("/")) {
01015:                            dir = dir + "/";
01016:                        }
01017:                        base = new URL("file", "", dir);
01018:                    } else {
01019:                        base = new URL(currentSystemId);
01020:                    }
01021:
01022:                    // expand id
01023:                    url = new URL(base, id);
01024:                } catch (Exception e) {
01025:                    // let it go through
01026:                }
01027:                if (url == null) {
01028:                    return systemId;
01029:                }
01030:                return url.toString();
01031:            }
01032:
01033:            /**
01034:             * Fixes a platform dependent filename to standard URI form.
01035:             *
01036:             * @param str The string to fix.
01037:             *
01038:             * @return Returns the fixed URI string.
01039:             */
01040:            private static String fixURI(String str) {
01041:
01042:                // handle platform dependent strings
01043:                str = str.replace(java.io.File.separatorChar, '/');
01044:
01045:                // Windows fix
01046:                if (str.length() >= 2) {
01047:                    char ch1 = str.charAt(1);
01048:                    if (ch1 == ':') {
01049:                        char ch0 = Character.toUpperCase(str.charAt(0));
01050:                        if (ch0 >= 'A' && ch0 <= 'Z') {
01051:                            str = "/" + str;
01052:                        }
01053:                    }
01054:                }
01055:
01056:                // done
01057:                return str;
01058:            }
01059:
01060:            private void traverseInclude(Element includeDecl) throws Exception {
01061:                // General Attribute Checking
01062:                int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
01063:                Hashtable attrValues = generalCheck(includeDecl, scope);
01064:                checkContent(includeDecl, XUtil
01065:                        .getFirstChildElement(includeDecl), true);
01066:
01067:                Attr locationAttr = includeDecl
01068:                        .getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
01069:                if (locationAttr == null) {
01070:                    // REVISIT: Localize
01071:                    reportGenericSchemaError("a schemaLocation attribute must be specified on an <include> element");
01072:                    return;
01073:                }
01074:                String location = locationAttr.getValue();
01075:                // expand it before passing it to the parser
01076:                InputSource source = null;
01077:
01078:                // If fEntityResolver is not null and is not the default, only then use it - Gopal Sharma, Sun Microsystems Inc.
01079:                if ((fEntityResolver != null)
01080:                        && !(fEntityResolver.getClass().getName()
01081:                                .equals("org.apache.xerces.validators.common.XMLValidator$Resolver"))) {
01082:                    source = fEntityResolver.resolveEntity("", location);
01083:                }
01084:
01085:                if (source == null) {
01086:                    location = expandSystemId(location, fCurrentSchemaURL);
01087:                    source = new InputSource(location);
01088:                }
01089:                // create a string for uniqueness of this included schema in fIncludeLocations
01090:                // algorithm:  string is pubId+sysId or if both null then filename
01091:                String pubId = "";
01092:                String sysId = "";
01093:                if (source.getPublicId() != null)
01094:                    pubId = source.getPublicId();
01095:                if (source.getSystemId() != null)
01096:                    sysId = source.getSystemId();
01097:
01098:                if (pubId.length() != 0 || sysId.length() != 0)
01099:                    location = pubId + sysId;
01100:
01101:                if (fIncludeLocations.contains((Object) location)) {
01102:                    return;
01103:                }
01104:                fIncludeLocations.addElement((Object) location);
01105:
01106:                DOMParser parser = new IgnoreWhitespaceParser();
01107:                parser
01108:                        .setEntityResolver((fEntityResolver != null) ? (fEntityResolver)
01109:                                : (new Resolver()));
01110:                parser.setErrorHandler(new ErrorHandler() {
01111:                    public void error(SAXParseException ex) throws SAXException {
01112:                        StringBuffer str = new StringBuffer();
01113:                        String systemId_ = ex.getSystemId();
01114:                        if (systemId_ != null) {
01115:                            int index = systemId_.lastIndexOf('/');
01116:                            if (index != -1)
01117:                                systemId_ = systemId_.substring(index + 1);
01118:                            str.append(systemId_);
01119:                        }
01120:                        str.append(':').append(ex.getLineNumber()).append(':')
01121:                                .append(ex.getColumnNumber());
01122:                        String message = ex.getMessage();
01123:                        if (message.toLowerCase().trim().endsWith("not found.")) {
01124:                            System.err.println("[Warning] " + str.toString()
01125:                                    + ": " + message);
01126:                        } else { // do standard thing
01127:                            System.err.println("[Error] " + str.toString()
01128:                                    + ":" + message);
01129:                            throw ex;
01130:                        }
01131:                    }
01132:                });
01133:
01134:                try {
01135:                    parser.setFeature("http://xml.org/sax/features/validation",
01136:                            false);
01137:                    parser.setFeature("http://xml.org/sax/features/namespaces",
01138:                            true);
01139:                    parser
01140:                            .setFeature(
01141:                                    "http://apache.org/xml/features/dom/defer-node-expansion",
01142:                                    false);
01143:                    parser
01144:                            .setFeature(
01145:                                    "http://apache.org/xml/features/continue-after-fatal-error",
01146:                                    true);
01147:                } catch (org.xml.sax.SAXNotRecognizedException e) {
01148:                    e.printStackTrace();
01149:                } catch (org.xml.sax.SAXNotSupportedException e) {
01150:                    e.printStackTrace();
01151:                }
01152:
01153:                try {
01154:                    parser.parse(source);
01155:                } catch (IOException e) {
01156:                    // we already produce warnings on IOExceptions!
01157:                    // e.printStackTrace();
01158:                } catch (SAXException e) {
01159:                    //e.printStackTrace();
01160:                }
01161:
01162:                Document document = parser.getDocument(); //Our Grammar
01163:                Element root = null;
01164:                if (document != null) {
01165:                    root = document.getDocumentElement();
01166:                }
01167:
01168:                if (root != null) {
01169:                    String targetNSURI = getTargetNamespaceString(root);
01170:                    if (targetNSURI.length() > 0
01171:                            && !targetNSURI.equals(fTargetNSURIString)) {
01172:                        // REVISIT: Localize
01173:                        reportGenericSchemaError("included schema '" + location
01174:                                + "' has a different targetNameSpace '"
01175:                                + targetNSURI + "'");
01176:                    } else {
01177:                        // We not creating another TraverseSchema object to compile
01178:                        // the included schema file, because the scope count, anon-type count
01179:                        // should not be reset for a included schema, this can be fixed by saving
01180:                        // the counters in the Schema Grammar,
01181:                        if (fSchemaInfoListRoot == null) {
01182:                            fSchemaInfoListRoot = new SchemaInfo(
01183:                                    fElementDefaultQualified,
01184:                                    fAttributeDefaultQualified, fBlockDefault,
01185:                                    fFinalDefault, fCurrentSchemaURL,
01186:                                    fSchemaRootElement, fNamespacesScope, null,
01187:                                    null);
01188:                            fCurrentSchemaInfo = fSchemaInfoListRoot;
01189:                        }
01190:                        fSchemaRootElement = root;
01191:                        fSchemaURLStack.push(fCurrentSchemaURL);
01192:                        fCurrentSchemaURL = location;
01193:                        traverseIncludedSchemaHeader(root);
01194:                        //
01195:                        // Bug fix: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3272
01196:                        // For included schemas with no namespace we need to bind the default namespace
01197:                        // (empty string) to the target namespace of the including XML Schema.
01198:                        if ((fTargetNSURIString.length() != 0)
01199:                                && (root.getAttributeNode("xmlns") == null)) {
01200:                            fNamespacesScope.setNamespaceForPrefix(
01201:                                    StringPool.EMPTY_STRING, fTargetNSURI);
01202:                        }
01203:                        // and now we'd better save this stuff!
01204:                        fCurrentSchemaInfo = new SchemaInfo(
01205:                                fElementDefaultQualified,
01206:                                fAttributeDefaultQualified, fBlockDefault,
01207:                                fFinalDefault, fCurrentSchemaURL,
01208:                                fSchemaRootElement, fNamespacesScope,
01209:                                fCurrentSchemaInfo.getNext(),
01210:                                fCurrentSchemaInfo);
01211:                        (fCurrentSchemaInfo.getPrev())
01212:                                .setNext(fCurrentSchemaInfo);
01213:                        traverseIncludedSchema(root);
01214:                        // there must always be a previous element!
01215:                        fCurrentSchemaInfo = fCurrentSchemaInfo.getPrev();
01216:                        fCurrentSchemaInfo.restore();
01217:                        fCurrentSchemaURL = (String) fSchemaURLStack.pop();
01218:                    }
01219:
01220:                }
01221:
01222:            }
01223:
01224:            private void traverseIncludedSchemaHeader(Element root)
01225:                    throws Exception {
01226:                // General Attribute Checking
01227:                int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
01228:                Hashtable attrValues = generalCheck(root, scope);
01229:
01230:                // Retrieved the Namespace mapping from the schema element.
01231:                NamedNodeMap schemaEltAttrs = root.getAttributes();
01232:                int i = 0;
01233:                Attr sattr = null;
01234:
01235:                boolean seenXMLNS = false;
01236:                while ((sattr = (Attr) schemaEltAttrs.item(i++)) != null) {
01237:                    String attName = sattr.getName();
01238:                    if (attName.startsWith("xmlns:")) {
01239:                        String attValue = sattr.getValue();
01240:                        String prefix = attName
01241:                                .substring(attName.indexOf(":") + 1);
01242:                        fNamespacesScope.setNamespaceForPrefix(fStringPool
01243:                                .addSymbol(prefix), fStringPool
01244:                                .addSymbol(attValue));
01245:                    }
01246:                    if (attName.equals("xmlns")) {
01247:
01248:                        String attValue = sattr.getValue();
01249:                        fNamespacesScope.setNamespaceForPrefix(
01250:                                StringPool.EMPTY_STRING, fStringPool
01251:                                        .addSymbol(attValue));
01252:                        seenXMLNS = true;
01253:                    }
01254:
01255:                }
01256:                if (!seenXMLNS && fTargetNSURIString.length() == 0) {
01257:                    fNamespacesScope.setNamespaceForPrefix(
01258:                            StringPool.EMPTY_STRING, StringPool.EMPTY_STRING);
01259:                }
01260:
01261:                fElementDefaultQualified = root.getAttribute(
01262:                        SchemaSymbols.ATT_ELEMENTFORMDEFAULT).equals(
01263:                        SchemaSymbols.ATTVAL_QUALIFIED);
01264:                fAttributeDefaultQualified = root.getAttribute(
01265:                        SchemaSymbols.ATT_ATTRIBUTEFORMDEFAULT).equals(
01266:                        SchemaSymbols.ATTVAL_QUALIFIED);
01267:                Attr blockAttr = root
01268:                        .getAttributeNode(SchemaSymbols.ATT_BLOCKDEFAULT);
01269:                if (blockAttr == null)
01270:                    fBlockDefault = 0;
01271:                else
01272:                    fBlockDefault = parseBlockSet(blockAttr.getValue());
01273:                Attr finalAttr = root
01274:                        .getAttributeNode(SchemaSymbols.ATT_FINALDEFAULT);
01275:                if (finalAttr == null)
01276:                    fFinalDefault = 0;
01277:                else
01278:                    fFinalDefault = parseFinalSet(finalAttr.getValue());
01279:
01280:                //REVISIT, really sticky when noTargetNamesapce, for now, we assume everyting is in the same name space);
01281:                if (fTargetNSURI == StringPool.EMPTY_STRING) {
01282:                    fElementDefaultQualified = true;
01283:                    //fAttributeDefaultQualified = true;
01284:                }
01285:
01286:                //fScopeCount++;
01287:                //fCurrentScope = -1;
01288:            } // traverseIncludedSchemaHeader
01289:
01290:            private void traverseIncludedSchema(Element root) throws Exception {
01291:                // General Attribute Checking
01292:                int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
01293:                Hashtable attrValues = generalCheck(root, scope);
01294:
01295:                //extract all top-level attribute, attributeGroup, and group Decls and put them in the 3 hasn table in the SchemaGrammar.
01296:                extractTopLevel3Components(root);
01297:
01298:                // handle <redefine>, <include> and <import> elements.
01299:                Element child = XUtil.getFirstChildElement(root);
01300:                for (; child != null; child = XUtil
01301:                        .getNextSiblingElement(child)) {
01302:
01303:                    String name = child.getLocalName();
01304:
01305:                    if (name.equals(SchemaSymbols.ELT_ANNOTATION)) {
01306:                        traverseAnnotationDecl(child);
01307:                    } else if (name.equals(SchemaSymbols.ELT_INCLUDE)) {
01308:                        fNamespacesScope.increaseDepth();
01309:                        traverseInclude(child);
01310:                        fNamespacesScope.decreaseDepth();
01311:                    } else if (name.equals(SchemaSymbols.ELT_IMPORT)) {
01312:                        traverseImport(child);
01313:                    } else if (name.equals(SchemaSymbols.ELT_REDEFINE)) {
01314:                        fRedefineSucceeded = true; // presume worked until proven failed.
01315:                        traverseRedefine(child);
01316:                    } else
01317:                        break;
01318:                }
01319:
01320:                // handle the rest of the schema elements.
01321:                // BEWARE!  this method gets called both from traverseRedefine and
01322:                // traverseInclude; the preconditions (especially with respect to
01323:                // groups and attributeGroups) are different!
01324:                for (; child != null; child = XUtil
01325:                        .getNextSiblingElement(child)) {
01326:
01327:                    String name = child.getLocalName();
01328:
01329:                    if (name.equals(SchemaSymbols.ELT_ANNOTATION)) {
01330:                        traverseAnnotationDecl(child);
01331:                    } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
01332:                        traverseSimpleTypeDecl(child);
01333:                    } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
01334:                        traverseComplexTypeDecl(child);
01335:                    } else if (name.equals(SchemaSymbols.ELT_ELEMENT)) {
01336:                        traverseElementDecl(child);
01337:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
01338:                        if (fRedefineAttributeGroupMap != null) {
01339:                            String dName = child
01340:                                    .getAttribute(SchemaSymbols.ATT_NAME);
01341:                            String bName = (String) fRedefineAttributeGroupMap
01342:                                    .get(dName);
01343:                            if (bName != null) {
01344:                                child.setAttribute(SchemaSymbols.ATT_NAME,
01345:                                        bName);
01346:                                // and make sure we wipe this out of the grammar!
01347:                                fSchemaGrammar.topLevelAttrGrpDecls
01348:                                        .remove(dName);
01349:                                // Now we reuse this location in the array to store info we'll need for validation...
01350:                                ComplexTypeInfo typeInfo = new ComplexTypeInfo();
01351:                                int templateElementNameIndex = fStringPool
01352:                                        .addSymbol("$" + bName);
01353:                                int typeNameIndex = fStringPool.addSymbol("%"
01354:                                        + bName);
01355:                                typeInfo.scopeDefined = -2;
01356:                                typeInfo.contentSpecHandle = -1;
01357:                                typeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
01358:                                typeInfo.datatypeValidator = null;
01359:                                typeInfo.templateElementIndex = fSchemaGrammar
01360:                                        .addElementDecl(
01361:                                                new QName(
01362:                                                        -1,
01363:                                                        templateElementNameIndex,
01364:                                                        typeNameIndex,
01365:                                                        fTargetNSURI),
01366:                                                (fTargetNSURI == StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING
01367:                                                        : -2,
01368:                                                typeInfo.scopeDefined,
01369:                                                typeInfo.contentType,
01370:                                                typeInfo.contentSpecHandle, -1,
01371:                                                typeInfo.datatypeValidator);
01372:
01373:                                Vector anyAttDecls = new Vector();
01374:                                // need to determine how to initialize these babies; then
01375:                                // on the <redefine> traversing end, try
01376:                                // and cast the hash value into the right form;
01377:                                // failure indicates nothing to redefine; success
01378:                                // means we can feed checkAttribute... what it needs...
01379:                                traverseAttributeGroupDecl(child, typeInfo,
01380:                                        anyAttDecls);
01381:                                typeInfo.attlistHead = fSchemaGrammar
01382:                                        .getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
01383:                                fRedefineAttributeGroupMap.put(dName,
01384:                                        new Object[] { typeInfo,
01385:                                                fSchemaGrammar, anyAttDecls });
01386:                                continue;
01387:                            }
01388:                        }
01389:                        traverseAttributeGroupDecl(child, null, null);
01390:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
01391:                        traverseAttributeDecl(child, null, false);
01392:                    } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
01393:                        String dName = child
01394:                                .getAttribute(SchemaSymbols.ATT_NAME);
01395:                        if (fGroupNameRegistry.get(fTargetNSURIString + ","
01396:                                + dName) == null) {
01397:                            // we've been renamed already
01398:                            traverseGroupDecl(child);
01399:                            continue;
01400:                        }
01401:                        // if we're here: must have been a restriction.
01402:                        // we have yet to be renamed.
01403:                        try {
01404:                            GroupInfo gi = (GroupInfo) fGroupNameRegistry
01405:                                    .get(fTargetNSURIString + "," + dName);
01406:                            // if that succeeded then we're done; were ref'd here in
01407:                            // an include most likely.
01408:                            continue;
01409:                        } catch (ClassCastException c) {
01410:                            String s = (String) fGroupNameRegistry
01411:                                    .get(fTargetNSURIString + "," + dName);
01412:                            if (s == null)
01413:                                continue; // must have seen this already--somehow...
01414:                        }
01415:                        ;
01416:                        String bName = (String) fGroupNameRegistry
01417:                                .get(fTargetNSURIString + "," + dName);
01418:                        if (bName != null) {
01419:                            child.setAttribute(SchemaSymbols.ATT_NAME, bName);
01420:                            // Now we reuse this location in the array to store info we'll need for validation...
01421:                            // note that traverseGroupDecl will happily do that for us!
01422:                        }
01423:                        traverseGroupDecl(child);
01424:                    } else if (name.equals(SchemaSymbols.ELT_NOTATION)) {
01425:                        traverseNotationDecl(child);
01426:                    } else {
01427:                        // REVISIT: Localize
01428:                        reportGenericSchemaError("error in content of included <schema> element information item");
01429:                    }
01430:                } // for each child node
01431:
01432:            }
01433:
01434:            // This method's job is to open a redefined schema and store away its root element, defaultElementQualified and other
01435:            // such info, in order that it can be available when redefinition actually takes place.
01436:            // It assumes that it will be called from the schema doing the redefining, and it assumes
01437:            // that the other schema's info has already been saved, putting the info it finds into the
01438:            // SchemaInfoList element that is passed in.
01439:            private void openRedefinedSchema(Element redefineDecl,
01440:                    SchemaInfo store) throws Exception {
01441:                Attr locationAttr = redefineDecl
01442:                        .getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
01443:                if (locationAttr == null) {
01444:                    // REVISIT: Localize
01445:                    fRedefineSucceeded = false;
01446:                    reportGenericSchemaError("a schemaLocation attribute must be specified on a <redefine> element");
01447:                    return;
01448:                }
01449:                String location = locationAttr.getValue();
01450:
01451:                // expand it before passing it to the parser
01452:                InputSource source = null;
01453:                if (fEntityResolver != null) {
01454:                    source = fEntityResolver.resolveEntity("", location);
01455:                }
01456:
01457:                if (source == null) {
01458:                    location = expandSystemId(location, fCurrentSchemaURL);
01459:                    source = new InputSource(location);
01460:                }
01461:                // Make sure we don't redefine the same schema twice; it's allowed
01462:                // but the specs encourage us to avoid it.
01463:                // algorithm:  string is pubId+sysId or if both null then filename
01464:                String pubId = "";
01465:                String sysId = "";
01466:                if (source.getPublicId() != null)
01467:                    pubId = source.getPublicId();
01468:                if (source.getSystemId() != null)
01469:                    sysId = source.getSystemId();
01470:
01471:                if (pubId.length() != 0 || sysId.length() != 0)
01472:                    location += pubId + sysId;
01473:
01474:                // make sure we're not redefining ourselves!
01475:                if (source.getSystemId().equals(fCurrentSchemaURL)) {
01476:                    // REVISIT:  localize
01477:                    reportGenericSchemaError("src-redefine.2:  a schema cannot redefine itself");
01478:                    fRedefineSucceeded = false;
01479:                    return;
01480:                }
01481:                if (fRedefineLocations.get((Object) location) != null) {
01482:                    // then we'd better make sure we're directed at that schema...
01483:                    fCurrentSchemaInfo = (SchemaInfo) (fRedefineLocations
01484:                            .get((Object) location));
01485:                    fCurrentSchemaInfo.restore();
01486:                    return;
01487:                }
01488:
01489:                DOMParser parser = new IgnoreWhitespaceParser();
01490:                parser
01491:                        .setEntityResolver((fEntityResolver != null) ? (fEntityResolver)
01492:                                : (new Resolver()));
01493:                parser.setErrorHandler(new ErrorHandler());
01494:
01495:                try {
01496:                    parser.setFeature("http://xml.org/sax/features/validation",
01497:                            false);
01498:                    parser.setFeature("http://xml.org/sax/features/namespaces",
01499:                            true);
01500:                    parser
01501:                            .setFeature(
01502:                                    "http://apache.org/xml/features/dom/defer-node-expansion",
01503:                                    false);
01504:                    parser
01505:                            .setFeature(
01506:                                    "http://apache.org/xml/features/continue-after-fatal-error",
01507:                                    true);
01508:                } catch (org.xml.sax.SAXNotRecognizedException e) {
01509:                    e.printStackTrace();
01510:                } catch (org.xml.sax.SAXNotSupportedException e) {
01511:                    e.printStackTrace();
01512:                }
01513:
01514:                try {
01515:                    parser.parse(source);
01516:                } catch (IOException e) {
01517:                    e.printStackTrace();
01518:                } catch (SAXException e) {
01519:                    //e.printStackTrace();
01520:                }
01521:
01522:                Document document = parser.getDocument(); //Our Grammar to be redefined
01523:                Element root = null;
01524:                if (document != null) {
01525:                    root = document.getDocumentElement();
01526:                }
01527:
01528:                if (root == null) { // nothing to be redefined, so just continue; specs disallow an error here.
01529:                    fRedefineSucceeded = false;
01530:                    return;
01531:                }
01532:
01533:                // now if root isn't null, it'll contain the root of the schema we need to redefine.
01534:                // We do this in two phases:  first, we look through the children of
01535:                // redefineDecl.  Each one will correspond to an element of the
01536:                // redefined schema that we need to redefine.  To do this, we rename the
01537:                // element of the redefined schema, and rework the base or ref tag of
01538:                // the kid we're working on to refer to the renamed group or derive the
01539:                // renamed type.  Once we've done this, we actually go through the
01540:                // schema being redefined and convert it to a grammar.  Only then do we
01541:                // run through redefineDecl's kids and put them in the grammar.
01542:                //
01543:                // This approach is kosher with the specs.  It does raise interesting
01544:                // questions about error reporting, and perhaps also about grammar
01545:                // access, but it is comparatively efficient (we need make at most
01546:                // only 2 traversals of any given information item) and moreover
01547:                // we can use existing code to build the grammar structures once the
01548:                // first pass is out of the way, so this should be quite robust.
01549:
01550:                // check to see if the targetNameSpace is right
01551:                String redefinedTargetNSURIString = getTargetNamespaceString(root);
01552:                if (redefinedTargetNSURIString.length() > 0
01553:                        && !redefinedTargetNSURIString
01554:                                .equals(fTargetNSURIString)) {
01555:                    // REVISIT: Localize
01556:                    fRedefineSucceeded = false;
01557:                    reportGenericSchemaError("redefined schema '" + location
01558:                            + "' has a different targetNameSpace '"
01559:                            + redefinedTargetNSURIString
01560:                            + "' from the original schema");
01561:                } else {
01562:                    // targetNamespace is right, so let's do the renaming...
01563:                    // and let's keep in mind that the targetNamespace of the redefined
01564:                    // elements is that of the redefined schema!
01565:                    fSchemaRootElement = root;
01566:                    fCurrentSchemaURL = location;
01567:                    fNamespacesScope = new NamespacesScope(this );
01568:                    fNamespacesScope.setNamespaceForPrefix(fStringPool
01569:                            .addSymbol("xml"), fStringPool
01570:                            .addSymbol("http://www.w3.org/XML/1998/namespace"));
01571:                    if ((redefinedTargetNSURIString.length() == 0)
01572:                            && (root.getAttributeNode("xmlns") == null)) {
01573:                        fNamespacesScope.setNamespaceForPrefix(
01574:                                StringPool.EMPTY_STRING, fTargetNSURI);
01575:                    } else {
01576:                    }
01577:                    // get default form xmlns bindings et al.
01578:                    traverseIncludedSchemaHeader(root);
01579:                    // and then save them...
01580:                    store.setNext(new SchemaInfo(fElementDefaultQualified,
01581:                            fAttributeDefaultQualified, fBlockDefault,
01582:                            fFinalDefault, fCurrentSchemaURL,
01583:                            fSchemaRootElement, fNamespacesScope, null, store));
01584:                    (store.getNext()).setPrev(store);
01585:                    fCurrentSchemaInfo = store.getNext();
01586:                    fRedefineLocations.put((Object) location, store.getNext());
01587:                } // end if
01588:            } // end openRedefinedSchema
01589:
01590:            /****
01591:             * <redefine
01592:             *        schemaLocation = uriReference
01593:             *        {any attributes with non-schema namespace . . .}>
01594:             *        Content: (annotation | (
01595:             *            attributeGroup | complexType | group | simpleType))*
01596:             *    </redefine>
01597:             */
01598:            private void traverseRedefine(Element redefineDecl)
01599:                    throws Exception {
01600:                // General Attribute Checking
01601:                int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
01602:                Hashtable attrValues = generalCheck(redefineDecl, scope);
01603:
01604:                // initialize storage areas...
01605:                fRedefineAttributeGroupMap = new Hashtable();
01606:                NamespacesScope saveNSScope = (NamespacesScope) fNamespacesScope
01607:                        .clone();
01608:
01609:                // only case in which need to save contents is when fSchemaInfoListRoot is null; otherwise we'll have
01610:                // done this already one way or another.
01611:                if (fSchemaInfoListRoot == null) {
01612:                    fSchemaInfoListRoot = new SchemaInfo(
01613:                            fElementDefaultQualified,
01614:                            fAttributeDefaultQualified, fBlockDefault,
01615:                            fFinalDefault, fCurrentSchemaURL,
01616:                            fSchemaRootElement, fNamespacesScope, null, null);
01617:                    openRedefinedSchema(redefineDecl, fSchemaInfoListRoot);
01618:                    if (!fRedefineSucceeded)
01619:                        return;
01620:                    fCurrentSchemaInfo = fSchemaInfoListRoot.getNext();
01621:                    fNamespacesScope = (NamespacesScope) saveNSScope.clone();
01622:                    renameRedefinedComponents(redefineDecl, fSchemaInfoListRoot
01623:                            .getNext().getRoot(), fSchemaInfoListRoot.getNext());
01624:                } else {
01625:                    // may have a chain here; need to be wary!
01626:                    SchemaInfo curr = fSchemaInfoListRoot;
01627:                    for (; curr.getNext() != null; curr = curr.getNext())
01628:                        ;
01629:                    fCurrentSchemaInfo = curr;
01630:                    fCurrentSchemaInfo.restore();
01631:                    openRedefinedSchema(redefineDecl, fCurrentSchemaInfo);
01632:                    if (!fRedefineSucceeded)
01633:                        return;
01634:                    fNamespacesScope = (NamespacesScope) saveNSScope.clone();
01635:                    renameRedefinedComponents(redefineDecl, fCurrentSchemaInfo
01636:                            .getRoot(), fCurrentSchemaInfo);
01637:                }
01638:                // Now we have to march through our nicely-renamed schemas from the
01639:                // bottom up.  When we do these traversals other <redefine>'s may
01640:                // perhaps be encountered; we leave recursion to sort this out.
01641:
01642:                fCurrentSchemaInfo.restore();
01643:                traverseIncludedSchema(fSchemaRootElement);
01644:                fNamespacesScope = (NamespacesScope) saveNSScope.clone();
01645:                // and last but not least:  traverse our own <redefine>--the one all
01646:                // this labour has been expended upon.
01647:                for (Element child = XUtil.getFirstChildElement(redefineDecl); child != null; child = XUtil
01648:                        .getNextSiblingElement(child)) {
01649:                    String name = child.getLocalName();
01650:
01651:                    // annotations can occur anywhere in <redefine>s!
01652:                    if (name.equals(SchemaSymbols.ELT_ANNOTATION)) {
01653:                        traverseAnnotationDecl(child);
01654:                    } else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
01655:                        traverseSimpleTypeDecl(child);
01656:                    } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
01657:                        traverseComplexTypeDecl(child);
01658:                    } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
01659:                        String dName = child
01660:                                .getAttribute(SchemaSymbols.ATT_NAME);
01661:                        if (fGroupNameRegistry.get(fTargetNSURIString + ","
01662:                                + dName) == null
01663:                                || ((fRestrictedRedefinedGroupRegistry
01664:                                        .get(fTargetNSURIString + "," + dName) != null) && !((Boolean) fRestrictedRedefinedGroupRegistry
01665:                                        .get(fTargetNSURIString + "," + dName))
01666:                                        .booleanValue())) { // extension!
01667:                            traverseGroupDecl(child);
01668:                            continue;
01669:                        }
01670:                        traverseGroupDecl(child);
01671:                        GroupInfo bGIObj = null;
01672:                        try {
01673:                            bGIObj = (GroupInfo) fGroupNameRegistry
01674:                                    .get(fTargetNSURIString + "," + dName
01675:                                            + redefIdentifier);
01676:                        } catch (ClassCastException c) {
01677:                            // if it's still a String, then we mustn't have found a corresponding attributeGroup in the redefined schema.
01678:                            // REVISIT:  localize
01679:                            reportGenericSchemaError("src-redefine.6.2:  a <group> within a <redefine> must either have a ref to a <group> with the same name or must restrict such an <group>");
01680:                            continue;
01681:                        }
01682:                        if (bGIObj != null) { // we have something!
01683:                            int bCSIndex = bGIObj.contentSpecIndex;
01684:                            GroupInfo dGIObj;
01685:                            try {
01686:                                dGIObj = (GroupInfo) fGroupNameRegistry
01687:                                        .get(fTargetNSURIString + "," + dName);
01688:                            } catch (ClassCastException c) {
01689:                                continue;
01690:                            }
01691:                            if (dGIObj == null) // something went wrong...
01692:                                continue;
01693:                            int dCSIndex = dGIObj.contentSpecIndex;
01694:                            try {
01695:                                checkParticleDerivationOK(dCSIndex, -1,
01696:                                        bCSIndex, -1, null);
01697:                            } catch (ParticleRecoverableError e) {
01698:                                reportGenericSchemaError(e.getMessage());
01699:                            }
01700:                        } else
01701:                            // REVISIT:  localize
01702:                            reportGenericSchemaError("src-redefine.6.2:  a <group> within a <redefine> must either have a ref to a <group> with the same name or must restrict such an <group>");
01703:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
01704:                        if (fRedefineAttributeGroupMap != null) {
01705:                            String dName = child
01706:                                    .getAttribute(SchemaSymbols.ATT_NAME);
01707:                            Object[] bAttGrpStore = null;
01708:                            try {
01709:                                bAttGrpStore = (Object[]) fRedefineAttributeGroupMap
01710:                                        .get(dName);
01711:                            } catch (ClassCastException c) {
01712:                                // if it's still a String, then we mustn't have found a corresponding attributeGroup in the redefined schema.
01713:                                // REVISIT:  localize
01714:                                reportGenericSchemaError("src-redefine.7.2:  an <attributeGroup> within a <redefine> must either have a ref to an <attributeGroup> with the same name or must restrict such an <attributeGroup>");
01715:                                continue;
01716:                            }
01717:                            if (bAttGrpStore != null) { // we have something!
01718:                                ComplexTypeInfo bTypeInfo = (ComplexTypeInfo) bAttGrpStore[0];
01719:                                SchemaGrammar bSchemaGrammar = (SchemaGrammar) bAttGrpStore[1];
01720:                                Vector bAnyAttDecls = (Vector) bAttGrpStore[2];
01721:                                XMLAttributeDecl bAnyAttDecl = (bAnyAttDecls
01722:                                        .size() > 0) ? (XMLAttributeDecl) bAnyAttDecls
01723:                                        .elementAt(0)
01724:                                        : null;
01725:                                ComplexTypeInfo dTypeInfo = new ComplexTypeInfo();
01726:                                int templateElementNameIndex = fStringPool
01727:                                        .addSymbol("$" + dName);
01728:                                int dTypeNameIndex = fStringPool.addSymbol("%"
01729:                                        + dName);
01730:                                dTypeInfo.scopeDefined = -2;
01731:                                dTypeInfo.contentSpecHandle = -1;
01732:                                dTypeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
01733:                                dTypeInfo.datatypeValidator = null;
01734:                                dTypeInfo.templateElementIndex = fSchemaGrammar
01735:                                        .addElementDecl(
01736:                                                new QName(
01737:                                                        -1,
01738:                                                        templateElementNameIndex,
01739:                                                        dTypeNameIndex,
01740:                                                        fTargetNSURI),
01741:                                                (fTargetNSURI == StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING
01742:                                                        : -2,
01743:                                                dTypeInfo.scopeDefined,
01744:                                                dTypeInfo.contentType,
01745:                                                dTypeInfo.contentSpecHandle,
01746:                                                -1, dTypeInfo.datatypeValidator);
01747:
01748:                                Vector dAnyAttDecls = new Vector();
01749:                                XMLAttributeDecl dAnyAttDecl = (dAnyAttDecls
01750:                                        .size() > 0) ? (XMLAttributeDecl) dAnyAttDecls
01751:                                        .elementAt(0)
01752:                                        : null;
01753:                                traverseAttributeGroupDecl(child, dTypeInfo,
01754:                                        dAnyAttDecls);
01755:                                dTypeInfo.attlistHead = fSchemaGrammar
01756:                                        .getFirstAttributeDeclIndex(dTypeInfo.templateElementIndex);
01757:                                try {
01758:                                    checkAttributesDerivationOKRestriction(
01759:                                            dTypeInfo.attlistHead,
01760:                                            fSchemaGrammar, dAnyAttDecl,
01761:                                            bTypeInfo.attlistHead,
01762:                                            bSchemaGrammar, bAnyAttDecl);
01763:                                } catch (ComplexTypeRecoverableError e) {
01764:                                    String message = e.getMessage();
01765:                                    reportGenericSchemaError("src-redefine.7.2:  redefinition failed because of "
01766:                                            + message);
01767:                                }
01768:                                continue;
01769:                            }
01770:                        }
01771:                        traverseAttributeGroupDecl(child, null, null);
01772:                    } // no else; error reported in the previous traversal
01773:                } //for
01774:
01775:                // and restore the original globals
01776:                fCurrentSchemaInfo = fCurrentSchemaInfo.getPrev();
01777:                fCurrentSchemaInfo.restore();
01778:            } // traverseRedefine
01779:
01780:            // the purpose of this method is twofold:  1.  To find and appropriately modify all information items
01781:            // in redefinedSchema with names that are redefined by children of
01782:            // redefineDecl.  2.  To make sure the redefine element represented by
01783:            // redefineDecl is valid as far as content goes and with regard to
01784:            // properly referencing components to be redefined.  No traversing is done here!
01785:            // This method also takes actions to find and, if necessary, modify the names
01786:            // of elements in <redefine>'s in the schema that's being redefined.
01787:            private void renameRedefinedComponents(Element redefineDecl,
01788:                    Element schemaToRedefine, SchemaInfo currSchemaInfo)
01789:                    throws Exception {
01790:                for (Element child = XUtil.getFirstChildElement(redefineDecl); child != null; child = XUtil
01791:                        .getNextSiblingElement(child)) {
01792:                    String name = child.getLocalName();
01793:                    if (name.equals(SchemaSymbols.ELT_ANNOTATION))
01794:                        continue;
01795:                    else if (name.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
01796:                        String typeName = child
01797:                                .getAttribute(SchemaSymbols.ATT_NAME);
01798:                        if (fTraversedRedefineElements.contains(typeName))
01799:                            continue;
01800:                        if (validateRedefineNameChange(
01801:                                SchemaSymbols.ELT_SIMPLETYPE, typeName,
01802:                                typeName + redefIdentifier, child)) {
01803:                            fixRedefinedSchema(SchemaSymbols.ELT_SIMPLETYPE,
01804:                                    typeName, typeName + redefIdentifier,
01805:                                    schemaToRedefine, currSchemaInfo);
01806:                        }
01807:                    } else if (name.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
01808:                        String typeName = child
01809:                                .getAttribute(SchemaSymbols.ATT_NAME);
01810:                        if (fTraversedRedefineElements.contains(typeName))
01811:                            continue;
01812:                        if (validateRedefineNameChange(
01813:                                SchemaSymbols.ELT_COMPLEXTYPE, typeName,
01814:                                typeName + redefIdentifier, child)) {
01815:                            fixRedefinedSchema(SchemaSymbols.ELT_COMPLEXTYPE,
01816:                                    typeName, typeName + redefIdentifier,
01817:                                    schemaToRedefine, currSchemaInfo);
01818:                        }
01819:                    } else if (name.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
01820:                        String baseName = child
01821:                                .getAttribute(SchemaSymbols.ATT_NAME);
01822:                        if (fTraversedRedefineElements.contains(baseName))
01823:                            continue;
01824:                        if (validateRedefineNameChange(
01825:                                SchemaSymbols.ELT_ATTRIBUTEGROUP, baseName,
01826:                                baseName + redefIdentifier, child)) {
01827:                            fixRedefinedSchema(
01828:                                    SchemaSymbols.ELT_ATTRIBUTEGROUP, baseName,
01829:                                    baseName + redefIdentifier,
01830:                                    schemaToRedefine, currSchemaInfo);
01831:                        }
01832:                    } else if (name.equals(SchemaSymbols.ELT_GROUP)) {
01833:                        String baseName = child
01834:                                .getAttribute(SchemaSymbols.ATT_NAME);
01835:                        if (fTraversedRedefineElements.contains(baseName))
01836:                            continue;
01837:                        if (validateRedefineNameChange(SchemaSymbols.ELT_GROUP,
01838:                                baseName, baseName + redefIdentifier, child)) {
01839:                            fixRedefinedSchema(SchemaSymbols.ELT_GROUP,
01840:                                    baseName, baseName + redefIdentifier,
01841:                                    schemaToRedefine, currSchemaInfo);
01842:                        }
01843:                    } else {
01844:                        fRedefineSucceeded = false;
01845:                        // REVISIT: Localize
01846:                        reportGenericSchemaError("invalid top-level content for <redefine>");
01847:                        return;
01848:                    }
01849:                } // for
01850:            } // renameRedefinedComponents
01851:
01852:            // This function looks among the children of curr for an element of type elementSought.
01853:            // If it finds one, it evaluates whether its ref attribute contains a reference
01854:            // to originalName.  If it does, it returns 1 + the value returned by
01855:            // calls to itself on all other children.  In all other cases it returns 0 plus
01856:            // the sum of the values returned by calls to itself on curr's children.
01857:            // It also resets the value of ref so that it will refer to the renamed type from the schema
01858:            // being redefined.
01859:            private int changeRedefineGroup(QName originalName,
01860:                    String elementSought, String newName, Element curr)
01861:                    throws Exception {
01862:                int result = 0;
01863:                for (Element child = XUtil.getFirstChildElement(curr); child != null; child = XUtil
01864:                        .getNextSiblingElement(child)) {
01865:                    String name = child.getLocalName();
01866:                    if (!name.equals(elementSought))
01867:                        result += changeRedefineGroup(originalName,
01868:                                elementSought, newName, child);
01869:                    else {
01870:                        String ref = child.getAttribute(SchemaSymbols.ATT_REF);
01871:                        if (ref.length() != 0) {
01872:                            String prefix = "";
01873:                            String localpart = ref;
01874:                            int colonptr = ref.indexOf(":");
01875:                            if (colonptr > 0) {
01876:                                prefix = ref.substring(0, colonptr);
01877:                                localpart = ref.substring(colonptr + 1);
01878:                            }
01879:                            String uriStr = resolvePrefixToURI(prefix);
01880:                            if (originalName.equals(new QName(-1, fStringPool
01881:                                    .addSymbol(localpart), fStringPool
01882:                                    .addSymbol(localpart), fStringPool
01883:                                    .addSymbol(uriStr)))) {
01884:                                if (prefix.length() == 0)
01885:                                    child.setAttribute(SchemaSymbols.ATT_REF,
01886:                                            newName);
01887:                                else
01888:                                    child.setAttribute(SchemaSymbols.ATT_REF,
01889:                                            prefix + ":" + newName);
01890:                                result++;
01891:                                if (elementSought
01892:                                        .equals(SchemaSymbols.ELT_GROUP)) {
01893:                                    String minOccurs = child
01894:                                            .getAttribute(SchemaSymbols.ATT_MINOCCURS);
01895:                                    String maxOccurs = child
01896:                                            .getAttribute(SchemaSymbols.ATT_MAXOCCURS);
01897:                                    if (!((maxOccurs.length() == 0 || maxOccurs
01898:                                            .equals("1")) && (minOccurs
01899:                                            .length() == 0 || minOccurs
01900:                                            .equals("1")))) {
01901:                                        //REVISIT:  localize
01902:                                        reportGenericSchemaError("src-redefine.6.1.2:  the group "
01903:                                                + ref
01904:                                                + " which contains a reference to a group being redefined must have minOccurs = maxOccurs = 1");
01905:                                    }
01906:                                }
01907:                            }
01908:                        } // if ref was null some other stage of processing will flag the error
01909:                    }
01910:                }
01911:                return result;
01912:            } // changeRedefineGroup
01913:
01914:            // This simple function looks for the first occurrence of an eltLocalname
01915:            // schema information item and appropriately changes the value of
01916:            // its name or type attribute from oldName to newName.
01917:            // Root contains the root of the schema being operated upon.
01918:            // If it turns out that what we're looking for is in a <redefine> though, then we
01919:            // just rename it--and it's reference--to be the same and wait until
01920:            // renameRedefineDecls can get its hands on it and do it properly.
01921:            private void fixRedefinedSchema(String eltLocalname,
01922:                    String oldName, String newName, Element schemaToRedefine,
01923:                    SchemaInfo currSchema) throws Exception {
01924:
01925:                boolean foundIt = false;
01926:                for (Element child = XUtil
01927:                        .getFirstChildElement(schemaToRedefine); child != null; child = XUtil
01928:                        .getNextSiblingElement(child)) {
01929:                    String name = child.getLocalName();
01930:                    if (name.equals(SchemaSymbols.ELT_REDEFINE)) { // need to search the redefine decl...
01931:                        for (Element redefChild = XUtil
01932:                                .getFirstChildElement(child); redefChild != null; redefChild = XUtil
01933:                                .getNextSiblingElement(redefChild)) {
01934:                            String redefName = redefChild.getLocalName();
01935:                            if (redefName.equals(eltLocalname)) {
01936:                                String infoItemName = redefChild
01937:                                        .getAttribute(SchemaSymbols.ATT_NAME);
01938:                                if (!infoItemName.equals(oldName))
01939:                                    continue;
01940:                                else { // found it!
01941:                                    foundIt = true;
01942:                                    openRedefinedSchema(child, currSchema);
01943:                                    if (!fRedefineSucceeded)
01944:                                        return;
01945:                                    NamespacesScope saveNSS = (NamespacesScope) fNamespacesScope
01946:                                            .clone();
01947:                                    currSchema.restore();
01948:                                    if (validateRedefineNameChange(
01949:                                            eltLocalname, oldName, newName
01950:                                                    + redefIdentifier,
01951:                                            redefChild)
01952:                                            && (currSchema.getNext() != null)) {
01953:                                        currSchema.getNext().restore();
01954:                                        fixRedefinedSchema(eltLocalname,
01955:                                                oldName, newName
01956:                                                        + redefIdentifier,
01957:                                                fSchemaRootElement, currSchema
01958:                                                        .getNext());
01959:                                    }
01960:                                    fNamespacesScope = saveNSS;
01961:                                    redefChild.setAttribute(
01962:                                            SchemaSymbols.ATT_NAME, newName);
01963:                                    // and we now know we will traverse this, so set fTraversedRedefineElements appropriately...
01964:                                    fTraversedRedefineElements
01965:                                            .addElement(newName);
01966:                                    currSchema.restore();
01967:                                    fCurrentSchemaInfo = currSchema;
01968:                                    break;
01969:                                }
01970:                            }
01971:                        } //for
01972:                        if (foundIt)
01973:                            break;
01974:                    } else if (name.equals(eltLocalname)) {
01975:                        String infoItemName = child
01976:                                .getAttribute(SchemaSymbols.ATT_NAME);
01977:                        if (!infoItemName.equals(oldName))
01978:                            continue;
01979:                        else { // found it!
01980:                            foundIt = true;
01981:                            child.setAttribute(SchemaSymbols.ATT_NAME, newName);
01982:                            break;
01983:                        }
01984:                    }
01985:                } //for
01986:                if (!foundIt) {
01987:                    fRedefineSucceeded = false;
01988:                    // REVISIT: localize
01989:                    reportGenericSchemaError("could not find a declaration in the schema to be redefined corresponding to "
01990:                            + oldName);
01991:                }
01992:            } // end fixRedefinedSchema
01993:
01994:            // this method returns true if the redefine component is valid, and if
01995:            // it was possible to revise it correctly.  The definition of
01996:            // correctly will depend on whether renameRedefineDecls
01997:            // or fixRedefineSchema is the caller.
01998:            // this method also prepends a prefix onto newName if necessary; newName will never contain one.
01999:            private boolean validateRedefineNameChange(String eltLocalname,
02000:                    String oldName, String newName, Element child)
02001:                    throws Exception {
02002:                if (eltLocalname.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
02003:                    QName processedTypeName = new QName(-1, fStringPool
02004:                            .addSymbol(oldName),
02005:                            fStringPool.addSymbol(oldName), fTargetNSURI);
02006:                    Element grandKid = XUtil.getFirstChildElement(child);
02007:                    if (grandKid == null) {
02008:                        fRedefineSucceeded = false;
02009:                        // REVISIT: Localize
02010:                        reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
02011:                    } else {
02012:                        String grandKidName = grandKid.getLocalName();
02013:                        if (grandKidName.equals(SchemaSymbols.ELT_ANNOTATION)) {
02014:                            grandKid = XUtil.getNextSiblingElement(grandKid);
02015:                            grandKidName = grandKid.getLocalName();
02016:                        }
02017:                        if (grandKid == null) {
02018:                            fRedefineSucceeded = false;
02019:                            // REVISIT: Localize
02020:                            reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
02021:                        } else if (!grandKidName
02022:                                .equals(SchemaSymbols.ELT_RESTRICTION)) {
02023:                            fRedefineSucceeded = false;
02024:                            // REVISIT: Localize
02025:                            reportGenericSchemaError("a simpleType child of a <redefine> must have a restriction element as a child");
02026:                        } else {
02027:                            String derivedBase = grandKid
02028:                                    .getAttribute(SchemaSymbols.ATT_BASE);
02029:                            QName processedDerivedBase = parseBase(derivedBase);
02030:                            if (!processedTypeName.equals(processedDerivedBase)) {
02031:                                fRedefineSucceeded = false;
02032:                                // REVISIT: Localize
02033:                                reportGenericSchemaError("the base attribute of the restriction child of a simpleType child of a redefine must have the same value as the simpleType's type attribute");
02034:                            } else {
02035:                                // now we have to do the renaming...
02036:                                String prefix = "";
02037:                                int colonptr = derivedBase.indexOf(":");
02038:                                if (colonptr > 0)
02039:                                    prefix = derivedBase.substring(0, colonptr)
02040:                                            + ":";
02041:                                grandKid.setAttribute(SchemaSymbols.ATT_BASE,
02042:                                        prefix + newName);
02043:                                return true;
02044:                            }
02045:                        }
02046:                    }
02047:                } else if (eltLocalname.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
02048:                    QName processedTypeName = new QName(-1, fStringPool
02049:                            .addSymbol(oldName),
02050:                            fStringPool.addSymbol(oldName), fTargetNSURI);
02051:                    Element grandKid = XUtil.getFirstChildElement(child);
02052:                    if (grandKid == null) {
02053:                        fRedefineSucceeded = false;
02054:                        // REVISIT: Localize
02055:                        reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
02056:                    } else {
02057:                        if (grandKid.getLocalName().equals(
02058:                                SchemaSymbols.ELT_ANNOTATION)) {
02059:                            grandKid = XUtil.getNextSiblingElement(grandKid);
02060:                        }
02061:                        if (grandKid == null) {
02062:                            fRedefineSucceeded = false;
02063:                            // REVISIT: Localize
02064:                            reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
02065:                        } else {
02066:                            // have to go one more level down; let another pass worry whether complexType is valid.
02067:                            Element greatGrandKid = XUtil
02068:                                    .getFirstChildElement(grandKid);
02069:                            if (greatGrandKid == null) {
02070:                                fRedefineSucceeded = false;
02071:                                // REVISIT: Localize
02072:                                reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
02073:                            } else {
02074:                                String greatGrandKidName = greatGrandKid
02075:                                        .getLocalName();
02076:                                if (greatGrandKidName
02077:                                        .equals(SchemaSymbols.ELT_ANNOTATION)) {
02078:                                    greatGrandKid = XUtil
02079:                                            .getNextSiblingElement(greatGrandKid);
02080:                                    greatGrandKidName = greatGrandKid
02081:                                            .getLocalName();
02082:                                }
02083:                                if (greatGrandKid == null) {
02084:                                    fRedefineSucceeded = false;
02085:                                    // REVISIT: Localize
02086:                                    reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
02087:                                } else if (!greatGrandKidName
02088:                                        .equals(SchemaSymbols.ELT_RESTRICTION)
02089:                                        && !greatGrandKidName
02090:                                                .equals(SchemaSymbols.ELT_EXTENSION)) {
02091:                                    fRedefineSucceeded = false;
02092:                                    // REVISIT: Localize
02093:                                    reportGenericSchemaError("a complexType child of a <redefine> must have a restriction or extension element as a grandchild");
02094:                                } else {
02095:                                    String derivedBase = greatGrandKid
02096:                                            .getAttribute(SchemaSymbols.ATT_BASE);
02097:                                    QName processedDerivedBase = parseBase(derivedBase);
02098:                                    if (!processedTypeName
02099:                                            .equals(processedDerivedBase)) {
02100:                                        fRedefineSucceeded = false;
02101:                                        // REVISIT: Localize
02102:                                        reportGenericSchemaError("the base attribute of the restriction or extension grandchild of a complexType child of a redefine must have the same value as the complexType's type attribute");
02103:                                    } else {
02104:                                        // now we have to do the renaming...
02105:                                        String prefix = "";
02106:                                        int colonptr = derivedBase.indexOf(":");
02107:                                        if (colonptr > 0)
02108:                                            prefix = derivedBase.substring(0,
02109:                                                    colonptr)
02110:                                                    + ":";
02111:                                        greatGrandKid.setAttribute(
02112:                                                SchemaSymbols.ATT_BASE, prefix
02113:                                                        + newName);
02114:                                        return true;
02115:                                    }
02116:                                }
02117:                            }
02118:                        }
02119:                    }
02120:                } else if (eltLocalname
02121:                        .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
02122:                    QName processedBaseName = new QName(-1, fStringPool
02123:                            .addSymbol(oldName),
02124:                            fStringPool.addSymbol(oldName), fTargetNSURI);
02125:                    int attGroupRefsCount = changeRedefineGroup(
02126:                            processedBaseName, eltLocalname, newName, child);
02127:                    if (attGroupRefsCount > 1) {
02128:                        fRedefineSucceeded = false;
02129:                        // REVISIT:  localize
02130:                        reportGenericSchemaError("if an attributeGroup child of a <redefine> element contains an attributeGroup ref'ing itself, it must have exactly 1; this one has "
02131:                                + attGroupRefsCount);
02132:                    } else if (attGroupRefsCount == 1) {
02133:                        return true;
02134:                    } else
02135:                        fRedefineAttributeGroupMap.put(oldName, newName);
02136:                } else if (eltLocalname.equals(SchemaSymbols.ELT_GROUP)) {
02137:                    QName processedBaseName = new QName(-1, fStringPool
02138:                            .addSymbol(oldName),
02139:                            fStringPool.addSymbol(oldName), fTargetNSURI);
02140:                    int groupRefsCount = changeRedefineGroup(processedBaseName,
02141:                            eltLocalname, newName, child);
02142:                    String restrictedName = newName.substring(0, newName
02143:                            .length()
02144:                            - redefIdentifier.length());
02145:                    if (!fRedefineSucceeded) {
02146:                        fRestrictedRedefinedGroupRegistry.put(
02147:                                fTargetNSURIString + "," + restrictedName,
02148:                                new Boolean(false));
02149:                    }
02150:                    if (groupRefsCount > 1) {
02151:                        fRedefineSucceeded = false;
02152:                        fRestrictedRedefinedGroupRegistry.put(
02153:                                fTargetNSURIString + "," + restrictedName,
02154:                                new Boolean(false));
02155:                        // REVISIT:  localize
02156:                        reportGenericSchemaError("if a group child of a <redefine> element contains a group ref'ing itself, it must have exactly 1; this one has "
02157:                                + groupRefsCount);
02158:                    } else if (groupRefsCount == 1) {
02159:                        fRestrictedRedefinedGroupRegistry.put(
02160:                                fTargetNSURIString + "," + restrictedName,
02161:                                new Boolean(false));
02162:                        return true;
02163:                    } else {
02164:                        fGroupNameRegistry.put(fTargetNSURIString + ","
02165:                                + oldName, newName);
02166:                        fRestrictedRedefinedGroupRegistry.put(
02167:                                fTargetNSURIString + "," + restrictedName,
02168:                                new Boolean(true));
02169:                    }
02170:                } else {
02171:                    fRedefineSucceeded = false;
02172:                    // REVISIT: Localize
02173:                    reportGenericSchemaError("internal Xerces error; please submit a bug with schema as testcase");
02174:                }
02175:                // if we get here then we must have reported an error and failed somewhere...
02176:                return false;
02177:            } // validateRedefineNameChange
02178:
02179:            private void traverseImport(Element importDecl) throws Exception {
02180:                // General Attribute Checking
02181:                int scope = GeneralAttrCheck.ELE_CONTEXT_GLOBAL;
02182:                Hashtable attrValues = generalCheck(importDecl, scope);
02183:                checkContent(importDecl,
02184:                        XUtil.getFirstChildElement(importDecl), true);
02185:
02186:                String namespaceString = importDecl
02187:                        .getAttribute(SchemaSymbols.ATT_NAMESPACE);
02188:                SchemaGrammar importedGrammar = (SchemaGrammar) fGrammarResolver
02189:                        .getGrammar(namespaceString);
02190:
02191:                if ((importedGrammar == null)
02192:                        || namespaceString.trim().equals(fTargetNSURIString)) {
02193:                    importedGrammar = new SchemaGrammar();
02194:                } else {
02195:                    return;
02196:                }
02197:
02198:                Element root = null;
02199:                if (namespaceString.length() == 0) {
02200:                    if (fTargetNSURI == StringPool.EMPTY_STRING) {
02201:                        // REVISIT:  localize
02202:                        reportGenericSchemaError("src-import.1.2:  if the namespace attribute on an <import> element is not present, the <import>ing schema must have a targetNamespace");
02203:                        // look in external-noNamespaceSchemaLocation property!
02204:                        if (fExternalNoNamespaceSchema != null) {
02205:                            root = openImportedSchema(fExternalNoNamespaceSchema);
02206:                        }
02207:                    }
02208:                } else {
02209:                    if (fTargetNSURIString.equals(namespaceString.trim())) {
02210:                        // REVISIT:  localize
02211:                        reportGenericSchemaError("src-import.1.1:  the namespace attribute of an <import> element must not be the same as the targetNamespace of the <import>ing schema");
02212:                        // look in external-schemaLocation property!
02213:                        if (fExternalSchemas != null) {
02214:                            Enumeration externalNamespaces = fExternalSchemas
02215:                                    .keys();
02216:                            while (externalNamespaces.hasMoreElements()) {
02217:                                String namespace = (String) externalNamespaces
02218:                                        .nextElement();
02219:                                if (namespace.trim().equals(
02220:                                        namespaceString.trim())) {
02221:                                    root = openImportedSchema((String) fExternalSchemas
02222:                                            .get(namespace));
02223:                                    break;
02224:                                }
02225:                            }
02226:                        }
02227:                    }
02228:                }
02229:                String location = "";
02230:                if (root == null) { // try our own schemaLocation
02231:                    Attr locationAttr = importDecl
02232:                            .getAttributeNode(SchemaSymbols.ATT_SCHEMALOCATION);
02233:                    if (locationAttr != null) {
02234:                        location = locationAttr.getValue();
02235:                        root = openImportedSchema(location);
02236:                    }
02237:                }
02238:                if (root != null) {
02239:                    String targetNSURI = getTargetNamespaceString(root);
02240:                    if (!targetNSURI.equals(namespaceString)) {
02241:                        // REVISIT: Localize
02242:                        reportGenericSchemaError("imported schema '" + location
02243:                                + "' has a different targetNameSpace '"
02244:                                + targetNSURI + "' from what is declared '"
02245:                                + namespaceString + "'.");
02246:                    } else {
02247:                        location = fCurrentSchemaURL;
02248:                        TraverseSchema impSchema = new TraverseSchema(root,
02249:                                fStringPool, importedGrammar, fGrammarResolver,
02250:                                fErrorReporter, location, fEntityResolver,
02251:                                fFullConstraintChecking, fGeneralAttrCheck,
02252:                                fUnparsedExternalSchemas,
02253:                                fExternalNoNamespaceSchema);
02254:                        fCurrentSchemaURL = (String) fSchemaURLStack.pop();
02255:                        Enumeration ics = impSchema.fIdentityConstraints.keys();
02256:                        while (ics.hasMoreElements()) {
02257:                            Object icsKey = ics.nextElement();
02258:                            fIdentityConstraints.put(icsKey,
02259:                                    impSchema.fIdentityConstraints.get(icsKey));
02260:                        }
02261:                        Enumeration icNames = impSchema.fIdentityConstraintNames
02262:                                .keys();
02263:                        while (icNames.hasMoreElements()) {
02264:                            String icsNameKey = (String) icNames.nextElement();
02265:                            fIdentityConstraintNames.put(icsNameKey,
02266:                                    impSchema.fIdentityConstraintNames
02267:                                            .get(icsNameKey));
02268:                        }
02269:                    }
02270:                }
02271:            }
02272:
02273:            private Element openImportedSchema(String location)
02274:                    throws Exception {
02275:                // expand it before passing it to the parser
02276:                InputSource source = null;
02277:
02278:                // If fEntityResolver is not null and is not the default, only then use it - Gopal Sharma, Sun Microsystems Inc.
02279:                if ((fEntityResolver != null)
02280:                        && !(fEntityResolver.getClass().getName()
02281:                                .equals("org.apache.xerces.validators.common.XMLValidator$Resolver"))) {
02282:                    source = fEntityResolver.resolveEntity("", location);
02283:                }
02284:
02285:                if (source == null) {
02286:                    location = expandSystemId(location, fCurrentSchemaURL);
02287:                    source = new InputSource(location);
02288:                }
02289:                // create a string for uniqueness of this imported schema in fImportLocations
02290:                // algorithm:  string is pubId+sysId or if both null then filename
02291:                String pubId = "";
02292:                String sysId = "";
02293:                if (source.getPublicId() != null)
02294:                    pubId = source.getPublicId();
02295:                if (source.getSystemId() != null)
02296:                    sysId = source.getSystemId();
02297:
02298:                if (pubId.length() != 0 || sysId.length() != 0)
02299:                    location = pubId + sysId;
02300:
02301:                if (fImportLocations.contains((Object) location)) {
02302:                    return null;
02303:                }
02304:                // check to make sure we're not importing ourselves...
02305:                if (source.getSystemId().equals(fCurrentSchemaURL)) {
02306:                    // REVISIT:  localize
02307:                    return null;
02308:                }
02309:
02310:                DOMParser parser = new IgnoreWhitespaceParser();
02311:                parser
02312:                        .setEntityResolver((fEntityResolver != null) ? (fEntityResolver)
02313:                                : (new Resolver()));
02314:                parser.setErrorHandler(new ErrorHandler() {
02315:                    public void error(SAXParseException ex) throws SAXException {
02316:                        StringBuffer str = new StringBuffer();
02317:                        String systemId_ = ex.getSystemId();
02318:                        if (systemId_ != null) {
02319:                            int index = systemId_.lastIndexOf('/');
02320:                            if (index != -1)
02321:                                systemId_ = systemId_.substring(index + 1);
02322:                            str.append(systemId_);
02323:                        }
02324:                        str.append(':').append(ex.getLineNumber()).append(':')
02325:                                .append(ex.getColumnNumber());
02326:                        String message = ex.getMessage();
02327:                        if (message.toLowerCase().trim().endsWith("not found.")) {
02328:                            System.err.println("[Warning] " + str.toString()
02329:                                    + ": " + message);
02330:                        } else { // do standard thing
02331:                            System.err.println("[Error] " + str.toString()
02332:                                    + ":" + message);
02333:                            throw ex;
02334:                        }
02335:                    }
02336:                });
02337:
02338:                try {
02339:                    parser.setFeature("http://xml.org/sax/features/validation",
02340:                            false);
02341:                    parser.setFeature("http://xml.org/sax/features/namespaces",
02342:                            true);
02343:                    parser
02344:                            .setFeature(
02345:                                    "http://apache.org/xml/features/dom/defer-node-expansion",
02346:                                    false);
02347:                    parser
02348:                            .setFeature(
02349:                                    "http://apache.org/xml/features/continue-after-fatal-error",
02350:                                    true);
02351:                } catch (org.xml.sax.SAXNotRecognizedException e) {
02352:                    e.printStackTrace();
02353:                } catch (org.xml.sax.SAXNotSupportedException e) {
02354:                    e.printStackTrace();
02355:                }
02356:
02357:                try {
02358:                    parser.parse(source);
02359:                } catch (IOException e) {
02360:                    // e.printStackTrace();
02361:                } catch (SAXException e) {
02362:                    e.printStackTrace();
02363:                }
02364:
02365:                Document document = parser.getDocument(); //Our Grammar
02366:                Element root = null;
02367:                if (document != null) {
02368:                    root = document.getDocumentElement();
02369:                }
02370:                if (root != null) {
02371:                    fImportLocations.addElement((Object) location);
02372:                }
02373:                fSchemaURLStack.push(fCurrentSchemaURL);
02374:                fCurrentSchemaURL = location;
02375:                return root;
02376:            } // openImportedSchema
02377:
02378:            // utility method for finding the targetNamespace (and flagging errors if they occur)
02379:            private String getTargetNamespaceString(Element root)
02380:                    throws Exception {
02381:                String targetNSURI = "";
02382:                Attr targetNSAttr = root
02383:                        .getAttributeNode(SchemaSymbols.ATT_TARGETNAMESPACE);
02384:                if (targetNSAttr != null) {
02385:                    targetNSURI = targetNSAttr.getValue();
02386:                    if (targetNSURI.length() == 0) {
02387:                        // REVISIT:  localize
02388:                        reportGenericSchemaError("sch-prop-correct.1:  \"\" is not a legal value for the targetNamespace attribute; the attribute must either be absent or contain a nonempty value");
02389:                    }
02390:                }
02391:                return targetNSURI;
02392:            } // end getTargetNamespaceString(Element)
02393:
02394:            /**
02395:             * <annotation>(<appinfo> | <documentation>)*</annotation>
02396:             *
02397:             * @param annotationDecl:  the DOM node corresponding to the <annotation> info item
02398:             */
02399:            private void traverseAnnotationDecl(Element annotationDecl)
02400:                    throws Exception {
02401:
02402:                // General Attribute Checking
02403:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
02404:                Hashtable attrValues = generalCheck(annotationDecl, scope);
02405:
02406:                for (Element child = XUtil.getFirstChildElement(annotationDecl); child != null; child = XUtil
02407:                        .getNextSiblingElement(child)) {
02408:                    String name = child.getLocalName();
02409:                    if (!((name.equals(SchemaSymbols.ELT_APPINFO)) || (name
02410:                            .equals(SchemaSymbols.ELT_DOCUMENTATION)))) {
02411:                        // REVISIT: Localize
02412:                        reportGenericSchemaError("an <annotation> can only contain <appinfo> and <documentation> elements");
02413:                    }
02414:
02415:                    // General Attribute Checking
02416:                    attrValues = generalCheck(child, scope);
02417:                }
02418:            }
02419:
02420:            //
02421:            // Evaluates content of Annotation if present.
02422:            //
02423:            // @param: elm - top element
02424:            // @param: content - content must be annotation? or some other simple content
02425:            // @param: isEmpty: -- true if the content allowed is (annotation?) only
02426:            //                     false if must have some element (with possible preceding <annotation?>)
02427:            //
02428:            //REVISIT: this function should be used in all traverse* methods!
02429:            private Element checkContent(Element elm, Element content,
02430:                    boolean isEmpty) throws Exception {
02431:                //isEmpty = true-> means content can be null!
02432:                if (content == null) {
02433:                    if (!isEmpty) {
02434:                        reportSchemaError(SchemaMessageProvider.ContentError,
02435:                                new Object[] { elm
02436:                                        .getAttribute(SchemaSymbols.ATT_NAME) });
02437:                    }
02438:                    return null;
02439:                }
02440:                if (content.getLocalName().equals(SchemaSymbols.ELT_ANNOTATION)) {
02441:                    traverseAnnotationDecl(content);
02442:                    content = XUtil.getNextSiblingElement(content);
02443:                    if (content == null) { //must be followed by <simpleType?>
02444:                        if (!isEmpty) {
02445:                            reportSchemaError(
02446:                                    SchemaMessageProvider.ContentError,
02447:                                    new Object[] { elm
02448:                                            .getAttribute(SchemaSymbols.ATT_NAME) });
02449:                        }
02450:                        return null;
02451:                    }
02452:                    if (content.getLocalName().equals(
02453:                            SchemaSymbols.ELT_ANNOTATION)) {
02454:                        reportSchemaError(
02455:                                SchemaMessageProvider.AnnotationError,
02456:                                new Object[] { elm
02457:                                        .getAttribute(SchemaSymbols.ATT_NAME) });
02458:                        return null;
02459:                    }
02460:                    //return null if expected only annotation?, else returns updated content
02461:                }
02462:                return content;
02463:            }
02464:
02465:            //@param: elm - top element
02466:            //@param: baseTypeStr - type (base/itemType/memberTypes)
02467:            //@param: baseRefContext:  whether the caller is using this type as a base for restriction, union or list
02468:            //return DatatypeValidator available for the baseTypeStr, null if not found or disallowed.
02469:            // also throws an error if the base type won't allow itself to be used in this context.
02470:            //REVISIT: this function should be used in some|all traverse* methods!
02471:            private DatatypeValidator findDTValidator(Element elm,
02472:                    String baseTypeStr, int baseRefContext) throws Exception {
02473:                int baseType = fStringPool.addSymbol(baseTypeStr);
02474:                String prefix = "";
02475:                DatatypeValidator baseValidator = null;
02476:                String localpart = baseTypeStr;
02477:                int colonptr = baseTypeStr.indexOf(":");
02478:                if (colonptr > 0) {
02479:                    prefix = baseTypeStr.substring(0, colonptr);
02480:                    localpart = baseTypeStr.substring(colonptr + 1);
02481:                }
02482:                String uri = resolvePrefixToURI(prefix);
02483:                if (uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
02484:                        && localpart.equals("anySimpleType")
02485:                        && baseRefContext == SchemaSymbols.RESTRICTION) {
02486:                    reportSchemaError(
02487:                            SchemaMessageProvider.UnknownBaseDatatype,
02488:                            new Object[] {
02489:                                    elm.getAttribute(SchemaSymbols.ATT_BASE),
02490:                                    elm.getAttribute(SchemaSymbols.ATT_NAME) });
02491:                    return null;
02492:                }
02493:                baseValidator = getDatatypeValidator(uri, localpart);
02494:                if (baseValidator == null) {
02495:                    Element baseTypeNode = getTopLevelComponentByName(
02496:                            SchemaSymbols.ELT_SIMPLETYPE, localpart);
02497:                    if (baseTypeNode != null) {
02498:                        traverseSimpleTypeDecl(baseTypeNode);
02499:
02500:                        baseValidator = getDatatypeValidator(uri, localpart);
02501:                    }
02502:                }
02503:                Integer finalValue;
02504:                if (baseValidator == null) {
02505:                    reportSchemaError(
02506:                            SchemaMessageProvider.UnknownBaseDatatype,
02507:                            new Object[] {
02508:                                    elm.getAttribute(SchemaSymbols.ATT_BASE),
02509:                                    elm.getAttribute(SchemaSymbols.ATT_NAME) });
02510:                } else {
02511:                    finalValue = ((Integer) fSimpleTypeFinalRegistry.get(uri
02512:                            + "," + localpart));
02513:                    if ((finalValue != null)
02514:                            && ((finalValue.intValue() & baseRefContext) != 0)) {
02515:                        //REVISIT:  localize
02516:                        reportGenericSchemaError("the base type "
02517:                                + baseTypeStr
02518:                                + " does not allow itself to be used as the base for a restriction and/or as a type in a list and/or union");
02519:                        return baseValidator;
02520:                    }
02521:                }
02522:                return baseValidator;
02523:            }
02524:
02525:            private void checkEnumerationRequiredNotation(String name,
02526:                    String type) throws Exception {
02527:                String localpart = type;
02528:                int colonptr = type.indexOf(":");
02529:                if (colonptr > 0) {
02530:                    localpart = type.substring(colonptr + 1);
02531:                }
02532:                if (localpart.equals("NOTATION")) {
02533:                    reportGenericSchemaError("[enumeration-required-notation] It is an error for NOTATION to be used "
02534:                            + "directly in a schema in element/attribute '"
02535:                            + name + "'");
02536:                }
02537:
02538:            }
02539:
02540:            // @used in traverseSimpleType
02541:            // on return we need to pop the last simpleType name from
02542:            // the name stack
02543:            private int resetSimpleTypeNameStack(int returnValue) {
02544:                if (!fSimpleTypeNameStack.empty()) {
02545:                    fSimpleTypeNameStack.pop();
02546:                }
02547:                return returnValue;
02548:            }
02549:
02550:            // @used in traverseSimpleType
02551:            // report an error cos-list-of-atomic and reset the last name of the list datatype we traversing
02552:            private void reportCosListOfAtomic() throws Exception {
02553:                reportGenericSchemaError("cos-list-of-atomic: The itemType must have a {variety} of atomic or union (in which case all the {member type definitions} must be atomic)");
02554:                fListName = "";
02555:            }
02556:
02557:            // @used in traverseSimpleType
02558:            // find if union datatype validator has list datatype member.
02559:            private boolean isListDatatype(DatatypeValidator validator) {
02560:                if (validator instanceof  UnionDatatypeValidator) {
02561:                    Vector temp = ((UnionDatatypeValidator) validator)
02562:                            .getBaseValidators();
02563:                    for (int i = 0; i < temp.size(); i++) {
02564:                        if (temp.elementAt(i) instanceof  ListDatatypeValidator) {
02565:                            return true;
02566:                        }
02567:                        if (temp.elementAt(i) instanceof  UnionDatatypeValidator) {
02568:                            if (isListDatatype((DatatypeValidator) temp
02569:                                    .elementAt(i))) {
02570:                                return true;
02571:                            }
02572:                        }
02573:                    }
02574:                }
02575:                return false;
02576:            }
02577:
02578:            /**
02579:             * Traverse SimpleType declaration:
02580:             * <simpleType
02581:             *         final = #all | list of (restriction, union or list)
02582:             *         id = ID
02583:             *         name = NCName>
02584:             *         Content: (annotation? , ((list | restriction | union)))
02585:             *       </simpleType>
02586:             * traverse <list>|<restriction>|<union>
02587:             *
02588:             * @param simpleTypeDecl
02589:             * @return
02590:             */
02591:            private int traverseSimpleTypeDecl(Element simpleTypeDecl)
02592:                    throws Exception {
02593:
02594:                // General Attribute Checking
02595:                int scope = isTopLevel(simpleTypeDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
02596:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
02597:                Hashtable attrValues = generalCheck(simpleTypeDecl, scope);
02598:
02599:                String nameProperty = simpleTypeDecl
02600:                        .getAttribute(SchemaSymbols.ATT_NAME);
02601:                String qualifiedName = nameProperty;
02602:
02603:                //---------------------------------------------------
02604:                // set qualified name
02605:                //---------------------------------------------------
02606:                if (nameProperty.length() == 0) { // anonymous simpleType
02607:                    qualifiedName = fTargetNSURIString + "," + "#S#"
02608:                            + (fSimpleTypeAnonCount++);
02609:                    fStringPool.addSymbol(qualifiedName);
02610:                } else {
02611:                    // this behaviour has been changed so that we neither
02612:                    // process unqualified names as if they came from the schemaforschema namespace nor
02613:                    // fail to pick up unqualified names from schemas with no
02614:                    // targetnamespace.  - NG
02615:                    //if (fTargetNSURIString.length () != 0) {
02616:                    qualifiedName = fTargetNSURIString + "," + qualifiedName;
02617:                    //}
02618:                    fStringPool.addSymbol(nameProperty);
02619:                }
02620:
02621:                //----------------------------------------------------------------------
02622:                //check if we have already traversed the same simpleType decl
02623:                //----------------------------------------------------------------------
02624:                if (fDatatypeRegistry.getDatatypeValidator(qualifiedName) != null) {
02625:                    return resetSimpleTypeNameStack(fStringPool
02626:                            .addSymbol(qualifiedName));
02627:                } else {
02628:                    if (fSimpleTypeNameStack.search(qualifiedName) != -1) {
02629:                        // cos-no-circular-unions && no circular definitions
02630:                        reportGenericSchemaError("cos-no-circular-unions: no circular definitions are allowed for an element '"
02631:                                + nameProperty + "'");
02632:                        return resetSimpleTypeNameStack(-1);
02633:                    }
02634:                }
02635:
02636:                //----------------------------------------------------------
02637:                // update _final_ registry
02638:                //----------------------------------------------------------
02639:                Attr finalAttr = simpleTypeDecl
02640:                        .getAttributeNode(SchemaSymbols.ATT_FINAL);
02641:                int finalProperty = 0;
02642:                if (finalAttr != null)
02643:                    finalProperty = parseFinalSet(finalAttr.getValue());
02644:                else
02645:                    finalProperty = parseFinalSet(null);
02646:
02647:                // if we have a nonzero final , store it in the hash...
02648:                if (finalProperty != 0)
02649:                    fSimpleTypeFinalRegistry.put(qualifiedName, new Integer(
02650:                            finalProperty));
02651:
02652:                // -------------------------------
02653:                // remember name being traversed to
02654:                // avoid circular definitions in union
02655:                // -------------------------------
02656:                fSimpleTypeNameStack.push(qualifiedName);
02657:
02658:                //----------------------------------------------------------------------
02659:                //annotation?,(list|restriction|union)
02660:                //----------------------------------------------------------------------
02661:                Element content = XUtil.getFirstChildElement(simpleTypeDecl);
02662:                content = checkContent(simpleTypeDecl, content, false);
02663:                if (content == null) {
02664:                    return resetSimpleTypeNameStack(-1);
02665:                }
02666:
02667:                // General Attribute Checking
02668:                scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
02669:                Hashtable contentAttrs = generalCheck(content, scope);
02670:
02671:                //----------------------------------------------------------------------
02672:                //use content.getLocalName for the cases there "xsd:" is a prefix, ei. "xsd:list"
02673:                //----------------------------------------------------------------------
02674:                String varietyProperty = content.getLocalName();
02675:                String baseTypeQNameProperty = null;
02676:                Vector dTValidators = null;
02677:                int size = 0;
02678:                StringTokenizer unionMembers = null;
02679:                boolean list = false;
02680:                boolean union = false;
02681:                boolean restriction = false;
02682:                int numOfTypes = 0; //list/restriction = 1, union = "+"
02683:
02684:                if (varietyProperty.equals(SchemaSymbols.ELT_LIST)) { //traverse List
02685:                    baseTypeQNameProperty = content
02686:                            .getAttribute(SchemaSymbols.ATT_ITEMTYPE);
02687:                    list = true;
02688:                    if (fListName.length() != 0) { // parent is <list> datatype
02689:                        reportCosListOfAtomic();
02690:                        return resetSimpleTypeNameStack(-1);
02691:                    } else {
02692:                        fListName = qualifiedName;
02693:                    }
02694:                } else if (varietyProperty
02695:                        .equals(SchemaSymbols.ELT_RESTRICTION)) { //traverse Restriction
02696:                    baseTypeQNameProperty = content
02697:                            .getAttribute(SchemaSymbols.ATT_BASE);
02698:                    restriction = true;
02699:                } else if (varietyProperty.equals(SchemaSymbols.ELT_UNION)) { //traverse union
02700:                    union = true;
02701:                    baseTypeQNameProperty = content
02702:                            .getAttribute(SchemaSymbols.ATT_MEMBERTYPES);
02703:                    if (baseTypeQNameProperty.length() != 0) {
02704:                        unionMembers = new StringTokenizer(
02705:                                baseTypeQNameProperty);
02706:                        size = unionMembers.countTokens();
02707:                    } else {
02708:                        size = 1; //at least one must be seen as <simpleType> decl
02709:                    }
02710:                    dTValidators = new Vector(size, 2);
02711:                } else {
02712:                    reportSchemaError(SchemaMessageProvider.FeatureUnsupported,
02713:                            new Object[] { varietyProperty });
02714:                    return -1;
02715:                }
02716:                if (XUtil.getNextSiblingElement(content) != null) {
02717:                    // REVISIT: Localize
02718:                    reportGenericSchemaError("error in content of simpleType");
02719:                }
02720:
02721:                int typeNameIndex;
02722:                DatatypeValidator baseValidator = null;
02723:
02724:                if (baseTypeQNameProperty.length() == 0) {
02725:                    //---------------------------
02726:                    //must 'see' <simpleType>
02727:                    //---------------------------
02728:
02729:                    //content = {annotation?,simpleType?...}
02730:                    content = XUtil.getFirstChildElement(content);
02731:
02732:                    //check content (annotation?, ...)
02733:                    content = checkContent(simpleTypeDecl, content, false);
02734:                    if (content == null) {
02735:                        return resetSimpleTypeNameStack(-1);
02736:                    }
02737:                    if (content.getLocalName().equals(
02738:                            SchemaSymbols.ELT_SIMPLETYPE)) {
02739:                        typeNameIndex = traverseSimpleTypeDecl(content);
02740:                        if (typeNameIndex != -1) {
02741:                            baseValidator = fDatatypeRegistry
02742:                                    .getDatatypeValidator(fStringPool
02743:                                            .toString(typeNameIndex));
02744:                            if (baseValidator != null && union) {
02745:                                dTValidators
02746:                                        .addElement((DatatypeValidator) baseValidator);
02747:                            }
02748:                        }
02749:                        if (typeNameIndex == -1 || baseValidator == null) {
02750:                            reportSchemaError(
02751:                                    SchemaMessageProvider.UnknownBaseDatatype,
02752:                                    new Object[] {
02753:                                            content
02754:                                                    .getAttribute(SchemaSymbols.ATT_BASE),
02755:                                            content
02756:                                                    .getAttribute(SchemaSymbols.ATT_NAME) });
02757:                            return resetSimpleTypeNameStack(-1);
02758:                        }
02759:                    } else {
02760:                        reportSchemaError(
02761:                                SchemaMessageProvider.ListUnionRestrictionError,
02762:                                new Object[] { simpleTypeDecl
02763:                                        .getAttribute(SchemaSymbols.ATT_NAME) });
02764:                        return resetSimpleTypeNameStack(-1);
02765:                    }
02766:                } //end - must see simpleType?
02767:                else {
02768:                    //-----------------------------
02769:                    //base was provided - get proper validator.
02770:                    //-----------------------------
02771:                    numOfTypes = 1;
02772:                    if (union) {
02773:                        numOfTypes = size;
02774:                    }
02775:                    //--------------------------------------------------------------------
02776:                    // this loop is also where we need to find out whether the type being used as
02777:                    // a base (or itemType or whatever) allows such things.
02778:                    //--------------------------------------------------------------------
02779:                    int baseRefContext = (restriction ? SchemaSymbols.RESTRICTION
02780:                            : 0);
02781:                    baseRefContext = baseRefContext
02782:                            | (union ? SchemaSymbols.UNION : 0);
02783:                    baseRefContext = baseRefContext
02784:                            | (list ? SchemaSymbols.LIST : 0);
02785:                    for (int i = 0; i < numOfTypes; i++) { //find all validators
02786:                        if (union) {
02787:                            baseTypeQNameProperty = unionMembers.nextToken();
02788:                        }
02789:                        baseValidator = findDTValidator(simpleTypeDecl,
02790:                                baseTypeQNameProperty, baseRefContext);
02791:                        if (baseValidator == null) {
02792:                            return resetSimpleTypeNameStack(-1);
02793:                        }
02794:                        // ------------------------------
02795:                        // (variety is list)cos-list-of-atomic
02796:                        // ------------------------------
02797:                        if (fListName.length() != 0) {
02798:                            if (baseValidator instanceof  ListDatatypeValidator) {
02799:                                reportCosListOfAtomic();
02800:                                return resetSimpleTypeNameStack(-1);
02801:                            }
02802:                            //-----------------------------------------------------
02803:                            // if baseValidator is of type (union) need to look
02804:                            // at Union validators to make sure that List is not one of them
02805:                            //-----------------------------------------------------
02806:                            if (isListDatatype(baseValidator)) {
02807:                                reportCosListOfAtomic();
02808:                                return resetSimpleTypeNameStack(-1);
02809:
02810:                            }
02811:
02812:                        }
02813:                        if (union) {
02814:                            dTValidators
02815:                                    .addElement((DatatypeValidator) baseValidator); //add validator to structure
02816:                        }
02817:                    }
02818:                } //end - base is available
02819:
02820:                // ------------------------------------------
02821:                // move to next child
02822:                // <base==empty)->[simpleType]->[facets]  OR
02823:                // <base!=empty)->[facets]
02824:                // ------------------------------------------
02825:                if (baseTypeQNameProperty.length() == 0) {
02826:                    content = XUtil.getNextSiblingElement(content);
02827:                } else {
02828:                    content = XUtil.getFirstChildElement(content);
02829:                }
02830:
02831:                // ------------------------------------------
02832:                //get more types for union if any
02833:                // ------------------------------------------
02834:                if (union) {
02835:                    int index = size;
02836:                    if (baseTypeQNameProperty.length() != 0) {
02837:                        content = checkContent(simpleTypeDecl, content, true);
02838:                    }
02839:                    while (content != null) {
02840:                        typeNameIndex = traverseSimpleTypeDecl(content);
02841:                        if (typeNameIndex != -1) {
02842:                            baseValidator = fDatatypeRegistry
02843:                                    .getDatatypeValidator(fStringPool
02844:                                            .toString(typeNameIndex));
02845:                            if (baseValidator != null) {
02846:                                if (fListName.length() != 0
02847:                                        && baseValidator instanceof  ListDatatypeValidator) {
02848:                                    reportCosListOfAtomic();
02849:                                    return resetSimpleTypeNameStack(-1);
02850:                                }
02851:                                dTValidators
02852:                                        .addElement((DatatypeValidator) baseValidator);
02853:                            }
02854:                        }
02855:                        if (baseValidator == null || typeNameIndex == -1) {
02856:                            reportSchemaError(
02857:                                    SchemaMessageProvider.UnknownBaseDatatype,
02858:                                    new Object[] {
02859:                                            simpleTypeDecl
02860:                                                    .getAttribute(SchemaSymbols.ATT_BASE),
02861:                                            simpleTypeDecl
02862:                                                    .getAttribute(SchemaSymbols.ATT_NAME) });
02863:                            return (-1);
02864:                        }
02865:                        content = XUtil.getNextSiblingElement(content);
02866:                    }
02867:                } // end - traverse Union
02868:
02869:                if (fListName.length() != 0) {
02870:                    // reset fListName, meaning that we are done with
02871:                    // traversing <list> and its itemType resolves to atomic value
02872:                    if (fListName.equals(qualifiedName)) {
02873:                        fListName = "";
02874:                    }
02875:                }
02876:
02877:                int numFacets = 0;
02878:                fFacetData.clear();
02879:                if (restriction && content != null) {
02880:                    short flags = 0; // flag facets that have fixed="true"
02881:                    int numEnumerationLiterals = 0;
02882:                    Vector enumData = new Vector();
02883:                    content = checkContent(simpleTypeDecl, content, true);
02884:                    StringBuffer pattern = null;
02885:                    String facet;
02886:                    while (content != null) {
02887:                        if (content.getNodeType() == Node.ELEMENT_NODE) {
02888:                            // General Attribute Checking
02889:                            contentAttrs = generalCheck(content, scope);
02890:                            numFacets++;
02891:                            facet = content.getLocalName();
02892:                            if (facet.equals(SchemaSymbols.ELT_ENUMERATION)) {
02893:                                numEnumerationLiterals++;
02894:                                String enumVal = content
02895:                                        .getAttribute(SchemaSymbols.ATT_VALUE);
02896:                                String localName;
02897:                                if (baseValidator instanceof  NOTATIONDatatypeValidator) {
02898:                                    String prefix = "";
02899:                                    String localpart = enumVal;
02900:                                    int colonptr = enumVal.indexOf(":");
02901:                                    if (colonptr > 0) {
02902:                                        prefix = enumVal.substring(0, colonptr);
02903:                                        localpart = enumVal
02904:                                                .substring(colonptr + 1);
02905:                                    }
02906:                                    String uriStr = (prefix.length() != 0) ? resolvePrefixToURI(prefix)
02907:                                            : fTargetNSURIString;
02908:                                    nameProperty = uriStr + ":" + localpart;
02909:                                    localName = (String) fNotationRegistry
02910:                                            .get(nameProperty);
02911:                                    if (localName == null) {
02912:                                        localName = traverseNotationFromAnotherSchema(
02913:                                                localpart, uriStr);
02914:                                        if (localName == null) {
02915:                                            reportGenericSchemaError("Notation '"
02916:                                                    + localpart
02917:                                                    + "' not found in the grammar "
02918:                                                    + uriStr);
02919:
02920:                                        }
02921:                                    }
02922:                                    enumVal = nameProperty;
02923:                                }
02924:                                enumData.addElement(enumVal);
02925:                                checkContent(simpleTypeDecl, XUtil
02926:                                        .getFirstChildElement(content), true);
02927:                            } else if (facet
02928:                                    .equals(SchemaSymbols.ELT_ANNOTATION)
02929:                                    || facet
02930:                                            .equals(SchemaSymbols.ELT_SIMPLETYPE)) {
02931:                                reportSchemaError(
02932:                                        SchemaMessageProvider.ListUnionRestrictionError,
02933:                                        new Object[] { simpleTypeDecl
02934:                                                .getAttribute(SchemaSymbols.ATT_NAME) });
02935:                            } else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
02936:                                if (pattern == null) {
02937:                                    pattern = new StringBuffer(
02938:                                            content
02939:                                                    .getAttribute(SchemaSymbols.ATT_VALUE));
02940:                                } else {
02941:                                    // ---------------------------------------------
02942:                                    //datatypes: 5.2.4 pattern: src-multiple-pattern
02943:                                    // ---------------------------------------------
02944:                                    pattern.append("|");
02945:                                    pattern
02946:                                            .append(content
02947:                                                    .getAttribute(SchemaSymbols.ATT_VALUE));
02948:                                    checkContent(simpleTypeDecl, XUtil
02949:                                            .getFirstChildElement(content),
02950:                                            true);
02951:                                }
02952:                            } else {
02953:                                if (fFacetData.containsKey(facet))
02954:                                    reportSchemaError(
02955:                                            SchemaMessageProvider.DatatypeError,
02956:                                            new Object[] { "The facet '"
02957:                                                    + facet
02958:                                                    + "' is defined more than once." });
02959:                                fFacetData.put(facet, content
02960:                                        .getAttribute(SchemaSymbols.ATT_VALUE));
02961:
02962:                                if (content.getAttribute(
02963:                                        SchemaSymbols.ATT_FIXED).equals(
02964:                                        SchemaSymbols.ATTVAL_TRUE)
02965:                                        || content
02966:                                                .getAttribute(
02967:                                                        SchemaSymbols.ATT_FIXED)
02968:                                                .equals(
02969:                                                        SchemaSymbols.ATTVAL_TRUE_1)) {
02970:                                    // --------------------------------------------
02971:                                    // set fixed facet flags
02972:                                    // length - must remain const through derivation
02973:                                    // thus we don't care if it fixed
02974:                                    // --------------------------------------------
02975:                                    if (facet
02976:                                            .equals(SchemaSymbols.ELT_MINLENGTH)) {
02977:                                        flags |= DatatypeValidator.FACET_MINLENGTH;
02978:                                    } else if (facet
02979:                                            .equals(SchemaSymbols.ELT_MAXLENGTH)) {
02980:                                        flags |= DatatypeValidator.FACET_MAXLENGTH;
02981:                                    } else if (facet
02982:                                            .equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
02983:                                        flags |= DatatypeValidator.FACET_MAXEXCLUSIVE;
02984:                                    } else if (facet
02985:                                            .equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
02986:                                        flags |= DatatypeValidator.FACET_MAXINCLUSIVE;
02987:                                    } else if (facet
02988:                                            .equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
02989:                                        flags |= DatatypeValidator.FACET_MINEXCLUSIVE;
02990:                                    } else if (facet
02991:                                            .equals(SchemaSymbols.ELT_MININCLUSIVE)) {
02992:                                        flags |= DatatypeValidator.FACET_MININCLUSIVE;
02993:                                    } else if (facet
02994:                                            .equals(SchemaSymbols.ELT_TOTALDIGITS)) {
02995:                                        flags |= DatatypeValidator.FACET_TOTALDIGITS;
02996:                                    } else if (facet
02997:                                            .equals(SchemaSymbols.ELT_FRACTIONDIGITS)) {
02998:                                        flags |= DatatypeValidator.FACET_FRACTIONDIGITS;
02999:                                    } else if (facet
03000:                                            .equals(SchemaSymbols.ELT_WHITESPACE)
03001:                                            && baseValidator instanceof  StringDatatypeValidator) {
03002:                                        flags |= DatatypeValidator.FACET_WHITESPACE;
03003:                                    }
03004:                                }
03005:                                checkContent(simpleTypeDecl, XUtil
03006:                                        .getFirstChildElement(content), true);
03007:                            }
03008:                        }
03009:                        content = XUtil.getNextSiblingElement(content);
03010:                    }
03011:                    if (numEnumerationLiterals > 0) {
03012:                        fFacetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
03013:                    }
03014:                    if (pattern != null) {
03015:                        fFacetData.put(SchemaSymbols.ELT_PATTERN, pattern
03016:                                .toString());
03017:                    }
03018:                    if (flags != 0) {
03019:                        fFacetData.put(DatatypeValidator.FACET_FIXED,
03020:                                new Short(flags));
03021:                    }
03022:                }
03023:
03024:                else if (list && content != null) {
03025:                    // report error - must not have any children!
03026:                    if (baseTypeQNameProperty.length() != 0) {
03027:                        content = checkContent(simpleTypeDecl, content, true);
03028:                        if (content != null) {
03029:                            reportSchemaError(
03030:                                    SchemaMessageProvider.ListUnionRestrictionError,
03031:                                    new Object[] { simpleTypeDecl
03032:                                            .getAttribute(SchemaSymbols.ATT_NAME) });
03033:                        }
03034:                    } else {
03035:                        reportSchemaError(
03036:                                SchemaMessageProvider.ListUnionRestrictionError,
03037:                                new Object[] { simpleTypeDecl
03038:                                        .getAttribute(SchemaSymbols.ATT_NAME) });
03039:                        //REVISIT: should we return?
03040:                    }
03041:                } else if (union && content != null) {
03042:                    //report error - must not have any children!
03043:                    if (baseTypeQNameProperty.length() != 0) {
03044:                        content = checkContent(simpleTypeDecl, content, true);
03045:                        if (content != null) {
03046:                            reportSchemaError(
03047:                                    SchemaMessageProvider.ListUnionRestrictionError,
03048:                                    new Object[] { simpleTypeDecl
03049:                                            .getAttribute(SchemaSymbols.ATT_NAME) });
03050:                        }
03051:                    } else {
03052:                        reportSchemaError(
03053:                                SchemaMessageProvider.ListUnionRestrictionError,
03054:                                new Object[] { simpleTypeDecl
03055:                                        .getAttribute(SchemaSymbols.ATT_NAME) });
03056:                        //REVISIT: should we return?
03057:                    }
03058:                }
03059:
03060:                // ----------------------------------------------------------------------
03061:                // create & register validator for "generated" type if it doesn't exist
03062:                // ----------------------------------------------------------------------
03063:                try {
03064:                    DatatypeValidator newValidator = fDatatypeRegistry
03065:                            .getDatatypeValidator(qualifiedName);
03066:
03067:                    if (newValidator == null) { // not previously registered
03068:                        if (list) {
03069:                            fDatatypeRegistry.createDatatypeValidator(
03070:                                    qualifiedName, baseValidator, fFacetData,
03071:                                    true);
03072:                        } else if (restriction) {
03073:                            fDatatypeRegistry.createDatatypeValidator(
03074:                                    qualifiedName, baseValidator, fFacetData,
03075:                                    false);
03076:                        } else { //union
03077:                            fDatatypeRegistry.createDatatypeValidator(
03078:                                    qualifiedName, dTValidators);
03079:                        }
03080:
03081:                    }
03082:
03083:                } catch (Exception e) {
03084:                    reportSchemaError(SchemaMessageProvider.DatatypeError,
03085:                            new Object[] { e.getMessage() });
03086:                }
03087:                return resetSimpleTypeNameStack(fStringPool
03088:                        .addSymbol(qualifiedName));
03089:            }
03090:
03091:            /*
03092:             * <any
03093:             *   id = ID
03094:             *   maxOccurs = string
03095:             *   minOccurs = nonNegativeInteger
03096:             *   namespace = (##any | ##other) | List of (anyURI | (##targetNamespace | ##local))
03097:             *   processContents = lax | skip | strict>
03098:             *   Content: (annotation?)
03099:             * </any>
03100:             */
03101:            private int traverseAny(Element child) throws Exception {
03102:                // General Attribute Checking
03103:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
03104:                Hashtable attrValues = generalCheck(child, scope);
03105:
03106:                Element annotation = checkContent(child, XUtil
03107:                        .getFirstChildElement(child), true);
03108:                if (annotation != null) {
03109:                    // REVISIT: Localize
03110:                    reportGenericSchemaError("<any> elements can contain at most one <annotation> element in their children");
03111:                }
03112:                int anyIndex = -1;
03113:                String namespace = child.getAttribute(
03114:                        SchemaSymbols.ATT_NAMESPACE).trim();
03115:                String processContents = child.getAttribute("processContents")
03116:                        .trim();
03117:
03118:                int processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY;
03119:                int processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER;
03120:                int processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS;
03121:
03122:                if (processContents.length() > 0
03123:                        && !processContents.equals("strict")) {
03124:                    if (processContents.equals("lax")) {
03125:                        processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_LAX;
03126:                        processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX;
03127:                        processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS_LAX;
03128:                    } else if (processContents.equals("skip")) {
03129:                        processContentsAny = XMLContentSpec.CONTENTSPECNODE_ANY_SKIP;
03130:                        processContentsAnyOther = XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP;
03131:                        processContentsAnyLocal = XMLContentSpec.CONTENTSPECNODE_ANY_NS_SKIP;
03132:                    }
03133:                }
03134:
03135:                if (namespace.length() == 0 || namespace.equals("##any")) {
03136:                    anyIndex = fSchemaGrammar.addContentSpecNode(
03137:                            processContentsAny, -1, StringPool.EMPTY_STRING,
03138:                            false);
03139:                } else if (namespace.equals("##other")) {
03140:                    String uri = fTargetNSURIString;
03141:                    int uriIndex = fStringPool.addSymbol(uri);
03142:                    anyIndex = fSchemaGrammar.addContentSpecNode(
03143:                            processContentsAnyOther, -1, uriIndex, false);
03144:                } else if (namespace.length() > 0) {
03145:                    int uriIndex, leafIndex, choiceIndex;
03146:
03147:                    StringTokenizer tokenizer = new StringTokenizer(namespace);
03148:                    String token = tokenizer.nextToken();
03149:                    if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
03150:                        uriIndex = StringPool.EMPTY_STRING;
03151:                    } else {
03152:                        if (token.equals("##targetNamespace"))
03153:                            token = fTargetNSURIString;
03154:                        uriIndex = fStringPool.addSymbol(token);
03155:                    }
03156:                    choiceIndex = fSchemaGrammar.addContentSpecNode(
03157:                            processContentsAnyLocal, -1, uriIndex, false);
03158:
03159:                    // store a list of seen uri, so that if there are duplicate
03160:                    // namespaces, we only add one of them to the content model
03161:                    int[] uriList = new int[8];
03162:                    uriList[0] = uriIndex;
03163:                    int uriCount = 1;
03164:
03165:                    while (tokenizer.hasMoreElements()) {
03166:                        token = tokenizer.nextToken();
03167:                        if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
03168:                            uriIndex = StringPool.EMPTY_STRING;
03169:                        } else {
03170:                            if (token.equals("##targetNamespace"))
03171:                                token = fTargetNSURIString;
03172:                            uriIndex = fStringPool.addSymbol(token);
03173:                        }
03174:                        // check whether we have seen this namespace, if so, skip
03175:                        for (int i = 0; i < uriCount; i++) {
03176:                            if (uriList[i] == uriIndex)
03177:                                continue;
03178:                        }
03179:                        // add this namespace to the list
03180:                        if (uriList.length == uriCount) {
03181:                            int[] newList = new int[uriCount * 2];
03182:                            System.arraycopy(uriList, 0, newList, 0, uriCount);
03183:                            uriList = newList;
03184:                        }
03185:                        uriList[uriCount++] = uriIndex;
03186:
03187:                        leafIndex = fSchemaGrammar.addContentSpecNode(
03188:                                processContentsAnyLocal, -1, uriIndex, false);
03189:                        choiceIndex = fSchemaGrammar.addContentSpecNode(
03190:                                XMLContentSpec.CONTENTSPECNODE_CHOICE,
03191:                                choiceIndex, leafIndex, false);
03192:                    }
03193:                    anyIndex = choiceIndex;
03194:                } else {
03195:                    // REVISIT: Localize
03196:                    reportGenericSchemaError("Empty namespace attribute for any element");
03197:                }
03198:
03199:                return anyIndex;
03200:            }
03201:
03202:            public DatatypeValidator getDatatypeValidator(String uri,
03203:                    String localpart) {
03204:
03205:                DatatypeValidator dv = null;
03206:
03207:                if (uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
03208:                    dv = fDatatypeRegistry.getDatatypeValidator(localpart);
03209:                } else {
03210:                    dv = fDatatypeRegistry.getDatatypeValidator(uri + ","
03211:                            + localpart);
03212:                }
03213:
03214:                return dv;
03215:            }
03216:
03217:            /*
03218:             * <anyAttribute
03219:             *   id = ID
03220:             *   namespace = ##any | ##other | ##local | list of {uri, ##targetNamespace}>
03221:             *   Content: (annotation?)
03222:             * </anyAttribute>
03223:             */
03224:            private XMLAttributeDecl traverseAnyAttribute(
03225:                    Element anyAttributeDecl) throws Exception {
03226:                // General Attribute Checking
03227:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
03228:                Hashtable attrValues = generalCheck(anyAttributeDecl, scope);
03229:
03230:                Element annotation = checkContent(anyAttributeDecl, XUtil
03231:                        .getFirstChildElement(anyAttributeDecl), true);
03232:                if (annotation != null) {
03233:                    // REVISIT: Localize
03234:                    reportGenericSchemaError("<anyAttribute> elements can contain at most one <annotation> element in their children");
03235:                }
03236:                XMLAttributeDecl anyAttDecl = new XMLAttributeDecl();
03237:                String processContents = anyAttributeDecl.getAttribute(
03238:                        SchemaSymbols.ATT_PROCESSCONTENTS).trim();
03239:                String namespace = anyAttributeDecl.getAttribute(
03240:                        SchemaSymbols.ATT_NAMESPACE).trim();
03241:                // simplify!  NG
03242:                //String curTargetUri = anyAttributeDecl.getOwnerDocument().getDocumentElement().getAttribute("targetNamespace");
03243:                String curTargetUri = fTargetNSURIString;
03244:
03245:                if (namespace.length() == 0
03246:                        || namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDANY)) {
03247:                    anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_ANY;
03248:                } else if (namespace.equals(SchemaSymbols.ATTVAL_TWOPOUNDOTHER)) {
03249:                    anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_OTHER;
03250:                    anyAttDecl.name.uri = fStringPool.addSymbol(curTargetUri);
03251:                } else if (namespace.length() > 0) {
03252:                    anyAttDecl.type = XMLAttributeDecl.TYPE_ANY_LIST;
03253:
03254:                    StringTokenizer tokenizer = new StringTokenizer(namespace);
03255:                    int aStringList = fStringPool.startStringList();
03256:                    Vector tokens = new Vector();
03257:                    int tokenStr;
03258:                    while (tokenizer.hasMoreElements()) {
03259:                        String token = tokenizer.nextToken();
03260:                        if (token.equals(SchemaSymbols.ATTVAL_TWOPOUNDLOCAL)) {
03261:                            tokenStr = StringPool.EMPTY_STRING;
03262:                        } else {
03263:                            if (token
03264:                                    .equals(SchemaSymbols.ATTVAL_TWOPOUNDTARGETNS))
03265:                                token = curTargetUri;
03266:                            tokenStr = fStringPool.addSymbol(token);
03267:                        }
03268:                        if (!fStringPool.addStringToList(aStringList, tokenStr)) {
03269:                            reportGenericSchemaError("Internal StringPool error when reading the "
03270:                                    + "namespace attribute for anyattribute declaration");
03271:                        }
03272:                    }
03273:                    fStringPool.finishStringList(aStringList);
03274:
03275:                    anyAttDecl.enumeration = aStringList;
03276:                } else {
03277:                    // REVISIT: Localize
03278:                    reportGenericSchemaError("Empty namespace attribute for anyattribute declaration");
03279:                }
03280:
03281:                // default processContents is "strict";
03282:                if (processContents.equals(SchemaSymbols.ATTVAL_SKIP)) {
03283:                    anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_SKIP;
03284:                } else if (processContents.equals(SchemaSymbols.ATTVAL_LAX)) {
03285:                    anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_LAX;
03286:                } else {
03287:                    anyAttDecl.defaultType |= XMLAttributeDecl.PROCESSCONTENTS_STRICT;
03288:                }
03289:
03290:                return anyAttDecl;
03291:            }
03292:
03293:            // Schema Component Constraint: Attribute Wildcard Intersection
03294:            // For a wildcard's {namespace constraint} value to be the intensional intersection of two other such values (call them O1 and O2): the appropriate case among the following must be true:
03295:            // 1 If O1 and O2 are the same value, then that value must be the value.
03296:            // 2 If either O1 or O2 is any, then the other must be the value.
03297:            // 3 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or absent), then that set, minus the negated namespace name if it was in the set, must be the value.
03298:            // 4 If both O1 and O2 are sets of (namespace names or absent), then the intersection of those sets must be the value.
03299:            // 5 If the two are negations of different namespace names, then the intersection is not expressible.
03300:            // In the case where there are more than two values, the intensional intersection is determined by identifying the intensional intersection of two of the values as above, then the intensional intersection of that value with the third (providing the first intersection was expressible), and so on as required.
03301:            private XMLAttributeDecl AWildCardIntersection(
03302:                    XMLAttributeDecl oneAny, XMLAttributeDecl anotherAny) {
03303:                // if either one is not expressible, the result is still not expressible
03304:                if (oneAny.type == -1) {
03305:                    return oneAny;
03306:                }
03307:                if (anotherAny.type == -1) {
03308:                    return anotherAny;
03309:                }
03310:
03311:                // 1 If O1 and O2 are the same value, then that value must be the value.
03312:                // this one is dealt with in different branches
03313:
03314:                // 2 If either O1 or O2 is any, then the other must be the value.
03315:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
03316:                    return anotherAny;
03317:                }
03318:                if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
03319:                    return oneAny;
03320:                }
03321:
03322:                // 3 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or absent), then that set, minus the negated namespace name if it was in the set, must be the value.
03323:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
03324:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03325:                        || oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03326:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03327:                    XMLAttributeDecl anyList, anyOther;
03328:                    if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03329:                        anyList = oneAny;
03330:                        anyOther = anotherAny;
03331:                    } else {
03332:                        anyList = anotherAny;
03333:                        anyOther = oneAny;
03334:                    }
03335:
03336:                    int[] uriList = fStringPool
03337:                            .stringListAsIntArray(anyList.enumeration);
03338:                    if (elementInSet(anyOther.name.uri, uriList)) {
03339:                        int newList = fStringPool.startStringList();
03340:                        for (int i = 0; i < uriList.length; i++) {
03341:                            if (uriList[i] != anyOther.name.uri) {
03342:                                fStringPool
03343:                                        .addStringToList(newList, uriList[i]);
03344:                            }
03345:                        }
03346:                        fStringPool.finishStringList(newList);
03347:                        anyList.enumeration = newList;
03348:                    }
03349:
03350:                    return anyList;
03351:                }
03352:
03353:                // 4 If both O1 and O2 are sets of (namespace names or absent), then the intersection of those sets must be the value.
03354:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03355:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03356:                    int[] result = intersect2sets(
03357:                            fStringPool
03358:                                    .stringListAsIntArray(oneAny.enumeration),
03359:                            fStringPool
03360:                                    .stringListAsIntArray(anotherAny.enumeration));
03361:                    int newList = fStringPool.startStringList();
03362:                    for (int i = 0; i < result.length; i++) {
03363:                        fStringPool.addStringToList(newList, result[i]);
03364:                    }
03365:                    fStringPool.finishStringList(newList);
03366:                    oneAny.enumeration = newList;
03367:                    return oneAny;
03368:                }
03369:
03370:                // 5 If the two are negations of different namespace names, then the intersection is not expressible.
03371:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
03372:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03373:                    if (oneAny.name.uri == anotherAny.name.uri) {
03374:                        return oneAny;
03375:                    } else {
03376:                        oneAny.type = -1;
03377:                        return oneAny;
03378:                    }
03379:                }
03380:
03381:                // should never go there;
03382:                return oneAny;
03383:            }
03384:
03385:            // Schema Component Constraint: Attribute Wildcard Union
03386:            // For a wildcard's {namespace constraint} value to be the intensional union of two other such values (call them O1 and O2): the appropriate case among the following must be true:
03387:            // 1 If O1 and O2 are the same value, then that value must be the value.
03388:            // 2 If either O1 or O2 is any, then any must be the value.
03389:            // 3 If both O1 and O2 are sets of (namespace names or absent), then the union of those sets must be the value.
03390:            // 4 If the two are negations of different namespace names, then any must be the value.
03391:            // 5 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or absent), then The appropriate case among the following must be true:
03392:            // 5.1 If the set includes the negated namespace name, then any must be the value.
03393:            // 5.2 If the set does not include the negated namespace name, then whichever of O1 or O2 is a pair of not and a namespace name must be the value.
03394:            // In the case where there are more than two values, the intensional union is determined by identifying the intensional union of two of the values as above, then the intensional union of that value with the third, and so on as required.
03395:            private XMLAttributeDecl AWildCardUnion(XMLAttributeDecl oneAny,
03396:                    XMLAttributeDecl anotherAny) {
03397:                // if either one is not expressible, the result is still not expressible
03398:                if (oneAny.type == -1) {
03399:                    return oneAny;
03400:                }
03401:                if (anotherAny.type == -1) {
03402:                    return anotherAny;
03403:                }
03404:
03405:                // 1 If O1 and O2 are the same value, then that value must be the value.
03406:                // this one is dealt with in different branches
03407:
03408:                // 2 If either O1 or O2 is any, then any must be the value.
03409:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
03410:                    return oneAny;
03411:                }
03412:                if (anotherAny.type == XMLAttributeDecl.TYPE_ANY_ANY) {
03413:                    return anotherAny;
03414:                }
03415:
03416:                // 3 If both O1 and O2 are sets of (namespace names or absent), then the union of those sets must be the value.
03417:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03418:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03419:                    int[] result = union2sets(
03420:                            fStringPool
03421:                                    .stringListAsIntArray(oneAny.enumeration),
03422:                            fStringPool
03423:                                    .stringListAsIntArray(anotherAny.enumeration));
03424:                    int newList = fStringPool.startStringList();
03425:                    for (int i = 0; i < result.length; i++) {
03426:                        fStringPool.addStringToList(newList, result[i]);
03427:                    }
03428:                    fStringPool.finishStringList(newList);
03429:                    oneAny.enumeration = newList;
03430:                    return oneAny;
03431:                }
03432:
03433:                // 4 If the two are negations of different namespace names, then any must be the value.
03434:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
03435:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03436:                    if (oneAny.name.uri == anotherAny.name.uri) {
03437:                        return oneAny;
03438:                    } else {
03439:                        oneAny.type = XMLAttributeDecl.TYPE_ANY_ANY;
03440:                        return oneAny;
03441:                    }
03442:                }
03443:
03444:                // 5 If either O1 or O2 is a pair of not and a namespace name and the other is a set of (namespace names or absent), then The appropriate case among the following must be true:
03445:                if (oneAny.type == XMLAttributeDecl.TYPE_ANY_OTHER
03446:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03447:                        || oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST
03448:                        && anotherAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03449:                    XMLAttributeDecl anyList, anyOther;
03450:                    if (oneAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03451:                        anyList = oneAny;
03452:                        anyOther = anotherAny;
03453:                    } else {
03454:                        anyList = anotherAny;
03455:                        anyOther = oneAny;
03456:                    }
03457:                    // 5.1 If the set includes the negated namespace name, then any must be the value.
03458:                    if (elementInSet(anyOther.name.uri, fStringPool
03459:                            .stringListAsIntArray(anyList.enumeration))) {
03460:                        anyOther.type = XMLAttributeDecl.TYPE_ANY_ANY;
03461:                    }
03462:                    // 5.2 If the set does not include the negated namespace name, then whichever of O1 or O2 is a pair of not and a namespace name must be the value.
03463:
03464:                    return anyOther;
03465:                }
03466:
03467:                // should never go there;
03468:                return oneAny;
03469:            }
03470:
03471:            // Schema Component Constraint: Wildcard Subset
03472:            // For a namespace constraint (call it sub) to be an intensional subset of another namespace constraint (call it super) one of the following must be true:
03473:            // 1 super must be any.
03474:            // 2 All of the following must be true:
03475:            // 2.1 sub must be a pair of not and a namespace name or absent.
03476:            // 2.2 super must be a pair of not and the same value.
03477:            // 3 All of the following must be true:
03478:            // 3.1 sub must be a set whose members are either namespace names or absent.
03479:            // 3.2 One of the following must be true:
03480:            // 3.2.1 super must be the same set or a superset thereof.
03481:            // 3.2.2 super must be a pair of not and a namespace name or absent and that value must not be in sub's set.
03482:            private boolean AWildCardSubset(XMLAttributeDecl subAny,
03483:                    XMLAttributeDecl super Any) {
03484:                // if either one is not expressible, it can't be a subset
03485:                if (subAny.type == -1 || super Any.type == -1)
03486:                    return false;
03487:
03488:                // 1 super must be any.
03489:                if (super Any.type == XMLAttributeDecl.TYPE_ANY_ANY)
03490:                    return true;
03491:
03492:                // 2 All of the following must be true:
03493:                // 2.1 sub must be a pair of not and a namespace name or absent.
03494:                if (subAny.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03495:                    // 2.2 super must be a pair of not and the same value.
03496:                    if (super Any.type == XMLAttributeDecl.TYPE_ANY_OTHER
03497:                            && subAny.name.uri == super Any.name.uri) {
03498:                        return true;
03499:                    }
03500:                }
03501:
03502:                // 3 All of the following must be true:
03503:                // 3.1 sub must be a set whose members are either namespace names or absent.
03504:                if (subAny.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03505:                    // 3.2 One of the following must be true:
03506:                    // 3.2.1 super must be the same set or a superset thereof.
03507:                    if (super Any.type == XMLAttributeDecl.TYPE_ANY_LIST
03508:                            && subset2sets(
03509:                                    fStringPool
03510:                                            .stringListAsIntArray(subAny.enumeration),
03511:                                    fStringPool
03512:                                            .stringListAsIntArray(super Any.enumeration))) {
03513:                        return true;
03514:                    }
03515:
03516:                    // 3.2.2 super must be a pair of not and a namespace name or absent and that value must not be in sub's set.
03517:                    if (super Any.type == XMLAttributeDecl.TYPE_ANY_OTHER
03518:                            && !elementInSet(super Any.name.uri, fStringPool
03519:                                    .stringListAsIntArray(super Any.enumeration))) {
03520:                        return true;
03521:                    }
03522:                }
03523:
03524:                return false;
03525:            }
03526:
03527:            // Validation Rule: Wildcard allows Namespace Name
03528:            // For a value which is either a namespace name or absent to be valid with respect to a wildcard constraint (the value of a {namespace constraint}) one of the following must be true:
03529:            // 1 The constraint must be any.
03530:            // 2 All of the following must be true:
03531:            // 2.1 The constraint is a pair of not and a namespace name or absent ([Definition:]  call this the namespace test).
03532:            // 2.2 The value must not be identical to the namespace test.
03533:            // 2.3 The value must not be absent.
03534:            // 3 The constraint is a set, and the value is identical to one of the members of the set.
03535:            private boolean AWildCardAllowsNameSpace(XMLAttributeDecl wildcard,
03536:                    String uri) {
03537:                // if the constrain is not expressible, then nothing is allowed
03538:                if (wildcard.type == -1)
03539:                    return false;
03540:
03541:                // 1 The constraint must be any.
03542:                if (wildcard.type == XMLAttributeDecl.TYPE_ANY_ANY)
03543:                    return true;
03544:
03545:                int uriStr = fStringPool.addString(uri);
03546:
03547:                // 2 All of the following must be true:
03548:                // 2.1 The constraint is a pair of not and a namespace name or absent ([Definition:]  call this the namespace test).
03549:                if (wildcard.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
03550:                    // 2.2 The value must not be identical to the namespace test.
03551:                    // 2.3 The value must not be absent.
03552:                    if (uriStr != wildcard.name.uri
03553:                            && uriStr != StringPool.EMPTY_STRING)
03554:                        return true;
03555:                }
03556:
03557:                // 3 The constraint is a set, and the value is identical to one of the members of the set.
03558:                if (wildcard.type == XMLAttributeDecl.TYPE_ANY_LIST) {
03559:                    if (elementInSet(uriStr, fStringPool
03560:                            .stringListAsIntArray(wildcard.enumeration)))
03561:                        return true;
03562:                }
03563:
03564:                return false;
03565:            }
03566:
03567:            private boolean isAWildCard(XMLAttributeDecl a) {
03568:                if (a.type == XMLAttributeDecl.TYPE_ANY_ANY
03569:                        || a.type == XMLAttributeDecl.TYPE_ANY_LIST
03570:                        || a.type == XMLAttributeDecl.TYPE_ANY_OTHER)
03571:                    return true;
03572:                else
03573:                    return false;
03574:            }
03575:
03576:            int[] intersect2sets(int[] one, int[] theOther) {
03577:                int[] result = new int[(one.length > theOther.length ? one.length
03578:                        : theOther.length)];
03579:
03580:                // simple implemention,
03581:                int count = 0;
03582:                for (int i = 0; i < one.length; i++) {
03583:                    if (elementInSet(one[i], theOther))
03584:                        result[count++] = one[i];
03585:                }
03586:
03587:                int[] result2 = new int[count];
03588:                System.arraycopy(result, 0, result2, 0, count);
03589:
03590:                return result2;
03591:            }
03592:
03593:            int[] union2sets(int[] one, int[] theOther) {
03594:                int[] result1 = new int[one.length];
03595:
03596:                // simple implemention,
03597:                int count = 0;
03598:                for (int i = 0; i < one.length; i++) {
03599:                    if (!elementInSet(one[i], theOther))
03600:                        result1[count++] = one[i];
03601:                }
03602:
03603:                int[] result2 = new int[count + theOther.length];
03604:                System.arraycopy(result1, 0, result2, 0, count);
03605:                System.arraycopy(theOther, 0, result2, count, theOther.length);
03606:
03607:                return result2;
03608:            }
03609:
03610:            boolean subset2sets(int[] subSet, int[] super Set) {
03611:                for (int i = 0; i < subSet.length; i++) {
03612:                    if (!elementInSet(subSet[i], super Set))
03613:                        return false;
03614:                }
03615:
03616:                return true;
03617:            }
03618:
03619:            boolean elementInSet(int ele, int[] set) {
03620:                boolean found = false;
03621:                for (int i = 0; i < set.length && !found; i++) {
03622:                    if (ele == set[i])
03623:                        found = true;
03624:                }
03625:
03626:                return found;
03627:            }
03628:
03629:            // wrapper traverseComplexTypeDecl method
03630:            private int traverseComplexTypeDecl(Element complexTypeDecl)
03631:                    throws Exception {
03632:                return traverseComplexTypeDecl(complexTypeDecl, false);
03633:            }
03634:
03635:            /**
03636:             * Traverse ComplexType Declaration - Rec Implementation.
03637:             *
03638:             *       <complexType
03639:             *         abstract = boolean
03640:             *         block = #all or (possibly empty) subset of {extension, restriction}
03641:             *         final = #all or (possibly empty) subset of {extension, restriction}
03642:             *         id = ID
03643:             *         mixed = boolean : false
03644:             *         name = NCName>
03645:             *         Content: (annotation? , (simpleContent | complexContent |
03646:             *                    ( (group | all | choice | sequence)? ,
03647:             *                    ( (attribute | attributeGroup)* , anyAttribute?))))
03648:             *       </complexType>
03649:             * @param complexTypeDecl
03650:             * @param forwardRef
03651:             * @return
03652:             */
03653:
03654:            private int traverseComplexTypeDecl(Element complexTypeDecl,
03655:                    boolean forwardRef) throws Exception {
03656:
03657:                // General Attribute Checking
03658:                int scope = isTopLevel(complexTypeDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
03659:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
03660:                Hashtable attrValues = generalCheck(complexTypeDecl, scope);
03661:
03662:                // ------------------------------------------------------------------
03663:                // Get the attributes of the type
03664:                // ------------------------------------------------------------------
03665:                String isAbstract = complexTypeDecl
03666:                        .getAttribute(SchemaSymbols.ATT_ABSTRACT);
03667:                String blockSet = null;
03668:                Attr blockAttr = complexTypeDecl
03669:                        .getAttributeNode(SchemaSymbols.ATT_BLOCK);
03670:                if (blockAttr != null)
03671:                    blockSet = blockAttr.getValue();
03672:                String finalSet = null;
03673:                Attr finalAttr = complexTypeDecl
03674:                        .getAttributeNode(SchemaSymbols.ATT_FINAL);
03675:                if (finalAttr != null)
03676:                    finalSet = finalAttr.getValue();
03677:                String typeId = complexTypeDecl
03678:                        .getAttribute(SchemaSymbols.ATTVAL_ID);
03679:                String typeName = complexTypeDecl
03680:                        .getAttribute(SchemaSymbols.ATT_NAME);
03681:                String mixed = complexTypeDecl
03682:                        .getAttribute(SchemaSymbols.ATT_MIXED);
03683:                boolean isMixed = mixed.equals(SchemaSymbols.ATTVAL_TRUE)
03684:                        || mixed.equals(SchemaSymbols.ATTVAL_TRUE_1);
03685:                boolean isNamedType = false;
03686:                Stack savedGroupNameStack = null;
03687:
03688:                // ------------------------------------------------------------------
03689:                // Generate a type name, if one wasn't specified
03690:                // ------------------------------------------------------------------
03691:                if (typeName.length() == 0) { // gensym a unique name
03692:                    typeName = genAnonTypeName(complexTypeDecl);
03693:                }
03694:
03695:                if (DEBUGGING)
03696:                    System.out.println("traversing complex Type : " + typeName);
03697:
03698:                int typeNameIndex = fStringPool.addSymbol(typeName);
03699:
03700:                // ------------------------------------------------------------------
03701:                // Check if the type has already been registered
03702:                // ------------------------------------------------------------------
03703:                if (isTopLevel(complexTypeDecl)) {
03704:
03705:                    String fullName = fTargetNSURIString + "," + typeName;
03706:                    ComplexTypeInfo temp = (ComplexTypeInfo) fComplexTypeRegistry
03707:                            .get(fullName);
03708:                    if (temp != null) {
03709:                        // check for duplicate declarations
03710:                        if (!forwardRef) {
03711:                            if (temp.declSeen())
03712:                                reportGenericSchemaError("sch-props-correct: Duplicate declaration for complexType "
03713:                                        + typeName);
03714:                            else
03715:                                temp.setDeclSeen();
03716:
03717:                        }
03718:                        return fStringPool.addSymbol(fullName);
03719:                    } else {
03720:                        // check if the type is the name of a simple type
03721:                        if (getDatatypeValidator(fTargetNSURIString, typeName) != null)
03722:                            reportGenericSchemaError("sch-props-correct: Duplicate type declaration - type is "
03723:                                    + typeName);
03724:
03725:                    }
03726:                }
03727:
03728:                fCurrentTypeNameStack.push(typeName);
03729:
03730:                int scopeDefined = fScopeCount++;
03731:                int previousScope = fCurrentScope;
03732:                fCurrentScope = scopeDefined;
03733:
03734:                // Squirrel away the groupNameStack.
03735:                // If we are in the middle of processing a group, and we hit the group again
03736:                // because of a complexType for an element, it's not an error.
03737:                if (!fCurrentGroupNameStack.isEmpty()) {
03738:                    savedGroupNameStack = fCurrentGroupNameStack;
03739:                    fCurrentGroupNameStack = new Stack();
03740:                }
03741:
03742:                Element child = null;
03743:                ComplexTypeInfo typeInfo = new ComplexTypeInfo();
03744:                typeInfo.scopeDefined = scopeDefined;
03745:
03746:                try {
03747:
03748:                    // ------------------------------------------------------------------
03749:                    // First, handle any ANNOTATION declaration and get next child
03750:                    // ------------------------------------------------------------------
03751:                    child = checkContent(complexTypeDecl, XUtil
03752:                            .getFirstChildElement(complexTypeDecl), true);
03753:
03754:                    // ------------------------------------------------------------------
03755:                    // Process the content of the complex type declaration
03756:                    // ------------------------------------------------------------------
03757:                    if (child == null) {
03758:                        //
03759:                        // EMPTY complexType with complexContent
03760:                        //
03761:                        processComplexContent(typeNameIndex, child, typeInfo,
03762:                                null, isMixed);
03763:                    } else {
03764:                        String childName = child.getLocalName();
03765:                        int index = -2;
03766:
03767:                        if (childName.equals(SchemaSymbols.ELT_SIMPLECONTENT)) {
03768:                            //
03769:                            // SIMPLE CONTENT element
03770:                            //
03771:                            traverseSimpleContentDecl(typeNameIndex, child,
03772:                                    typeInfo);
03773:                            if (XUtil.getNextSiblingElement(child) != null)
03774:                                throw new ComplexTypeRecoverableError(
03775:                                        "Invalid child following the simpleContent child in the complexType");
03776:                        } else if (childName
03777:                                .equals(SchemaSymbols.ELT_COMPLEXCONTENT)) {
03778:                            //
03779:                            // COMPLEX CONTENT element
03780:                            //
03781:                            traverseComplexContentDecl(typeNameIndex, child,
03782:                                    typeInfo, isMixed);
03783:                            if (XUtil.getNextSiblingElement(child) != null)
03784:                                throw new ComplexTypeRecoverableError(
03785:                                        "Invalid child following the complexContent child in the complexType");
03786:                        } else {
03787:                            //
03788:                            // We must have ....
03789:                            // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
03790:                            // Note that it's possible that only attributes are specified.
03791:                            //
03792:                            processComplexContent(typeNameIndex, child,
03793:                                    typeInfo, null, isMixed);
03794:
03795:                        }
03796:                    }
03797:                    typeInfo.blockSet = parseBlockSet(blockSet);
03798:                    // make sure block's value was absent, #all or in {extension, restriction}
03799:                    if ((blockSet != null)
03800:                            && blockSet.length() != 0
03801:                            && (!blockSet.equals(SchemaSymbols.ATTVAL_POUNDALL) && (((typeInfo.blockSet & SchemaSymbols.RESTRICTION) == 0) && ((typeInfo.blockSet & SchemaSymbols.EXTENSION) == 0))))
03802:                        throw new ComplexTypeRecoverableError(
03803:                                "The values of the 'block' attribute of a complexType must be either #all or a list of 'restriction' and 'extension'; "
03804:                                        + blockSet + " was found");
03805:
03806:                    typeInfo.finalSet = parseFinalSet(finalSet);
03807:                    // make sure final's value was absent, #all or in {extension, restriction}
03808:                    if ((finalSet != null)
03809:                            && finalSet.length() != 0
03810:                            && (!finalSet.equals(SchemaSymbols.ATTVAL_POUNDALL) && (((typeInfo.finalSet & SchemaSymbols.RESTRICTION) == 0) && ((typeInfo.finalSet & SchemaSymbols.EXTENSION) == 0))))
03811:                        throw new ComplexTypeRecoverableError(
03812:                                "The values of the 'final' attribute of a complexType must be either #all or a list of 'restriction' and 'extension'; "
03813:                                        + finalSet + " was found");
03814:
03815:                } catch (ComplexTypeRecoverableError e) {
03816:                    String message = e.getMessage();
03817:                    handleComplexTypeError(message, typeNameIndex, typeInfo);
03818:                }
03819:
03820:                // ------------------------------------------------------------------
03821:                // Finish the setup of the typeInfo and register the type
03822:                // ------------------------------------------------------------------
03823:                if (isAbstract.equals(SchemaSymbols.ATTVAL_TRUE)
03824:                        || isAbstract.equals(SchemaSymbols.ATTVAL_TRUE_1))
03825:                    typeInfo.setIsAbstractType();
03826:                if (!forwardRef)
03827:                    typeInfo.setDeclSeen();
03828:                typeName = fTargetNSURIString + "," + typeName;
03829:                typeInfo.typeName = new String(typeName);
03830:
03831:                if (DEBUGGING)
03832:                    System.out.println(">>>add complex Type to Registry: "
03833:                            + typeName + " baseDTValidator="
03834:                            + typeInfo.baseDataTypeValidator + " baseCTInfo="
03835:                            + typeInfo.baseComplexTypeInfo + " derivedBy="
03836:                            + typeInfo.derivedBy + " contentType="
03837:                            + typeInfo.contentType + " contentSpecHandle="
03838:                            + typeInfo.contentSpecHandle
03839:                            + " datatypeValidator="
03840:                            + typeInfo.datatypeValidator + " scopeDefined="
03841:                            + typeInfo.scopeDefined);
03842:
03843:                fComplexTypeRegistry.put(typeName, typeInfo);
03844:
03845:                // ------------------------------------------------------------------
03846:                // Before exiting, restore the scope, mainly for nested anonymous types
03847:                // ------------------------------------------------------------------
03848:                fCurrentScope = previousScope;
03849:                if (savedGroupNameStack != null)
03850:                    fCurrentGroupNameStack = savedGroupNameStack;
03851:                fCurrentTypeNameStack.pop();
03852:                checkRecursingComplexType();
03853:
03854:                //set template element's typeInfo
03855:                fSchemaGrammar.setElementComplexTypeInfo(
03856:                        typeInfo.templateElementIndex, typeInfo);
03857:
03858:                typeNameIndex = fStringPool.addSymbol(typeName);
03859:                return typeNameIndex;
03860:
03861:            } // end traverseComplexTypeDecl
03862:
03863:            /**
03864:             * Traverse SimpleContent Declaration
03865:             *
03866:             *       <simpleContent
03867:             *         id = ID
03868:             *         {any attributes with non-schema namespace...}>
03869:             *
03870:             *         Content: (annotation? , (restriction | extension))
03871:             *       </simpleContent>
03872:             *
03873:             *       <restriction
03874:             *         base = QNAME
03875:             *         id = ID
03876:             *         {any attributes with non-schema namespace...}>
03877:             *
03878:             *         Content: (annotation?,(simpleType?, (minExclusive|minInclusive|maxExclusive
03879:             *                    | maxInclusive | totalDigits | fractionDigits | length | minLength
03880:             *                    | maxLength | encoding | period | duration | enumeration
03881:             *                    | pattern | whiteSpace)*) ? ,
03882:             *                    ((attribute | attributeGroup)* , anyAttribute?))
03883:             *       </restriction>
03884:             *
03885:             *       <extension
03886:             *         base = QNAME
03887:             *         id = ID
03888:             *         {any attributes with non-schema namespace...}>
03889:             *         Content: (annotation? , ((attribute | attributeGroup)* , anyAttribute?))
03890:             *       </extension>
03891:             *
03892:             * @param typeNameIndex
03893:             * @param simpleContentTypeDecl
03894:             * @param typeInfo
03895:             * @return
03896:             */
03897:
03898:            private void traverseSimpleContentDecl(int typeNameIndex,
03899:                    Element simpleContentDecl, ComplexTypeInfo typeInfo)
03900:                    throws Exception {
03901:
03902:                // General Attribute Checking
03903:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
03904:                Hashtable attrValues = generalCheck(simpleContentDecl, scope);
03905:
03906:                String typeName = fStringPool.toString(typeNameIndex);
03907:
03908:                // -----------------------------------------------------------------------
03909:                // Get attributes.
03910:                // -----------------------------------------------------------------------
03911:                String simpleContentTypeId = simpleContentDecl
03912:                        .getAttribute(SchemaSymbols.ATTVAL_ID);
03913:
03914:                // -----------------------------------------------------------------------
03915:                // Set the content type to be simple, and initialize content spec handle
03916:                // -----------------------------------------------------------------------
03917:                typeInfo.contentType = XMLElementDecl.TYPE_SIMPLE;
03918:                typeInfo.contentSpecHandle = -1;
03919:
03920:                Element simpleContent = checkContent(simpleContentDecl, XUtil
03921:                        .getFirstChildElement(simpleContentDecl), false);
03922:
03923:                // If there are no children, return
03924:                if (simpleContent == null) {
03925:                    throw new ComplexTypeRecoverableError();
03926:                }
03927:
03928:                // General Attribute Checking
03929:                attrValues = generalCheck(simpleContent, scope);
03930:
03931:                // -----------------------------------------------------------------------
03932:                // The content should be either "restriction" or "extension"
03933:                // -----------------------------------------------------------------------
03934:                String simpleContentName = simpleContent.getLocalName();
03935:                if (simpleContentName.equals(SchemaSymbols.ELT_RESTRICTION))
03936:                    typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
03937:                else if (simpleContentName.equals(SchemaSymbols.ELT_EXTENSION))
03938:                    typeInfo.derivedBy = SchemaSymbols.EXTENSION;
03939:                else {
03940:
03941:                    throw new ComplexTypeRecoverableError(
03942:                            "The content of the simpleContent element is invalid.  The "
03943:                                    + "content must be RESTRICTION or EXTENSION");
03944:                }
03945:
03946:                // -----------------------------------------------------------------------
03947:                // Get the attributes of the restriction/extension element
03948:                // -----------------------------------------------------------------------
03949:                String base = simpleContent
03950:                        .getAttribute(SchemaSymbols.ATT_BASE);
03951:                String typeId = simpleContent
03952:                        .getAttribute(SchemaSymbols.ATTVAL_ID);
03953:
03954:                // -----------------------------------------------------------------------
03955:                // Skip over any annotations in the restriction or extension elements
03956:                // -----------------------------------------------------------------------
03957:                Element content = checkContent(simpleContent, XUtil
03958:                        .getFirstChildElement(simpleContent), true);
03959:
03960:                // -----------------------------------------------------------------------
03961:                // Handle the base type name
03962:                // -----------------------------------------------------------------------
03963:                if (base.length() == 0) {
03964:                    throw new ComplexTypeRecoverableError(
03965:                            "The BASE attribute must be specified for the "
03966:                                    + "RESTRICTION or EXTENSION element");
03967:                }
03968:
03969:                QName baseQName = parseBase(base);
03970:                // check if we're extending a simpleType which has a "final" setting which precludes this
03971:                Integer finalValue = ((Integer) fSimpleTypeFinalRegistry
03972:                        .get(fStringPool.toString(baseQName.uri) + ","
03973:                                + fStringPool.toString(baseQName.localpart)));
03974:                if (finalValue != null
03975:                        && (finalValue.intValue() == typeInfo.derivedBy))
03976:                    throw new ComplexTypeRecoverableError(
03977:                            "The simpleType "
03978:                                    + base
03979:                                    + " that "
03980:                                    + typeName
03981:                                    + " uses has a value of \"final\" which does not permit extension");
03982:
03983:                String baseTypeURI = fStringPool.toString(baseQName.uri);
03984:                String baseLocalName = fStringPool
03985:                        .toString(baseQName.localpart);
03986:                if (baseTypeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
03987:                        && baseLocalName.equals("anyType")) {
03988:                    throw new ComplexTypeRecoverableError(
03989:                            "The type '"
03990:                                    + base
03991:                                    + "' specified as the "
03992:                                    + "base in the simpleContent element must be a complex type with simple content");
03993:                }
03994:
03995:                processBaseTypeInfo(baseQName, typeInfo);
03996:
03997:                // check that the base isn't a complex type with simple content
03998:                if (typeInfo.baseComplexTypeInfo != null) {
03999:                    if (typeInfo.baseComplexTypeInfo.contentType != XMLElementDecl.TYPE_SIMPLE) {
04000:                        throw new ComplexTypeRecoverableError(
04001:                                "The type '"
04002:                                        + base
04003:                                        + "' specified as the "
04004:                                        + "base in the simpleContent element must not have complexContent");
04005:                    }
04006:                }
04007:
04008:                // -----------------------------------------------------------------------
04009:                // Process the content of the derivation
04010:                // -----------------------------------------------------------------------
04011:                Element attrNode = null;
04012:                //
04013:                // RESTRICTION
04014:                //
04015:                if (typeInfo.derivedBy == SchemaSymbols.RESTRICTION) {
04016:                    //
04017:                    //Schema Spec : Complex Type Definition Properties Correct : 2
04018:                    //
04019:                    if (typeInfo.baseDataTypeValidator != null) {
04020:                        throw new ComplexTypeRecoverableError(
04021:                                "ct-props-correct.2: The type '"
04022:                                        + base
04023:                                        + "' is a simple type.  It cannot be used in a "
04024:                                        + "derivation by RESTRICTION for a complexType");
04025:                    } else {
04026:                        typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
04027:                    }
04028:
04029:                    //
04030:                    // Check that the base's final set does not include RESTRICTION
04031:                    //
04032:                    if ((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.RESTRICTION) != 0) {
04033:                        throw new ComplexTypeRecoverableError(
04034:                                "Derivation by restriction is forbidden by either the base type "
04035:                                        + base + " or the schema");
04036:                    }
04037:
04038:                    // -----------------------------------------------------------------------
04039:                    // There may be a simple type definition in the restriction element
04040:                    // The data type validator will be based on it, if specified
04041:                    // -----------------------------------------------------------------------
04042:                    if (content != null
04043:                            && content.getLocalName().equals(
04044:                                    SchemaSymbols.ELT_SIMPLETYPE)) {
04045:                        int simpleTypeNameIndex = traverseSimpleTypeDecl(content);
04046:                        if (simpleTypeNameIndex != -1) {
04047:                            DatatypeValidator dv = fDatatypeRegistry
04048:                                    .getDatatypeValidator(fStringPool
04049:                                            .toString(simpleTypeNameIndex));
04050:
04051:                            //check that this datatype validator is validly derived from the base
04052:                            //according to derivation-ok-restriction 5.1.1
04053:                            if (!checkSimpleTypeDerivationOK(dv,
04054:                                    typeInfo.baseDataTypeValidator)) {
04055:                                throw new ComplexTypeRecoverableError(
04056:                                        "derivation-ok-restriction.5.1.1:  The content type is not a valid restriction of the content type of the base");
04057:                            }
04058:                            typeInfo.baseDataTypeValidator = dv;
04059:                            content = XUtil.getNextSiblingElement(content);
04060:                        } else {
04061:                            throw new ComplexTypeRecoverableError();
04062:                        }
04063:                    }
04064:
04065:                    //
04066:                    // Build up facet information
04067:                    //
04068:                    int numEnumerationLiterals = 0;
04069:                    int numFacets = 0;
04070:                    Hashtable facetData = new Hashtable();
04071:                    Vector enumData = new Vector();
04072:                    Element child;
04073:
04074:                    // General Attribute Checking
04075:                    scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
04076:                    Hashtable contentAttrs;
04077:
04078:                    //REVISIT: there is a better way to do this,
04079:                    for (child = content; child != null
04080:                            && (child.getLocalName().equals(
04081:                                    SchemaSymbols.ELT_MINEXCLUSIVE)
04082:                                    || child.getLocalName().equals(
04083:                                            SchemaSymbols.ELT_MININCLUSIVE)
04084:                                    || child.getLocalName().equals(
04085:                                            SchemaSymbols.ELT_MAXEXCLUSIVE)
04086:                                    || child.getLocalName().equals(
04087:                                            SchemaSymbols.ELT_MAXINCLUSIVE)
04088:                                    || child.getLocalName().equals(
04089:                                            SchemaSymbols.ELT_TOTALDIGITS)
04090:                                    || child.getLocalName().equals(
04091:                                            SchemaSymbols.ELT_FRACTIONDIGITS)
04092:                                    || child.getLocalName().equals(
04093:                                            SchemaSymbols.ELT_LENGTH)
04094:                                    || child.getLocalName().equals(
04095:                                            SchemaSymbols.ELT_MINLENGTH)
04096:                                    || child.getLocalName().equals(
04097:                                            SchemaSymbols.ELT_MAXLENGTH)
04098:                                    || child.getLocalName().equals(
04099:                                            SchemaSymbols.ELT_ENUMERATION)
04100:                                    || child.getLocalName().equals(
04101:                                            SchemaSymbols.ELT_PATTERN)
04102:                                    || child.getLocalName().equals(
04103:                                            SchemaSymbols.ELT_WHITESPACE) || child
04104:                                    .getLocalName().equals(
04105:                                            SchemaSymbols.ELT_ANNOTATION)); child = XUtil
04106:                            .getNextSiblingElement(child)) {
04107:                        if (child.getNodeType() == Node.ELEMENT_NODE) {
04108:                            Element facetElt = (Element) child;
04109:                            // General Attribute Checking
04110:                            contentAttrs = generalCheck(facetElt, scope);
04111:                            numFacets++;
04112:                            if (facetElt.getLocalName().equals(
04113:                                    SchemaSymbols.ELT_ENUMERATION)) {
04114:                                numEnumerationLiterals++;
04115:                                enumData.addElement(facetElt
04116:                                        .getAttribute(SchemaSymbols.ATT_VALUE));
04117:                                //Enumerations can have annotations ? ( 0 | 1 )
04118:                                Element enumContent = XUtil
04119:                                        .getFirstChildElement(facetElt);
04120:                                if (enumContent != null
04121:                                        && enumContent.getLocalName().equals(
04122:                                                SchemaSymbols.ELT_ANNOTATION)) {
04123:                                    traverseAnnotationDecl(child);
04124:                                }
04125:                                // TO DO: if Jeff check in new changes to TraverseSimpleType, copy them over
04126:                            } else {
04127:                                facetData.put(facetElt.getLocalName(), facetElt
04128:                                        .getAttribute(SchemaSymbols.ATT_VALUE));
04129:                            }
04130:                        }
04131:                    } // end of for loop thru facets
04132:
04133:                    if (numEnumerationLiterals > 0) {
04134:                        facetData.put(SchemaSymbols.ELT_ENUMERATION, enumData);
04135:                    }
04136:
04137:                    //
04138:                    // If there were facets, create a new data type validator, otherwise
04139:                    // the data type validator is from the base
04140:                    //
04141:                    if (numFacets > 0) {
04142:                        try {
04143:                            typeInfo.datatypeValidator = fDatatypeRegistry
04144:                                    .createDatatypeValidator(typeName,
04145:                                            typeInfo.baseDataTypeValidator,
04146:                                            facetData, false);
04147:                        } catch (Exception e) {
04148:                            throw new ComplexTypeRecoverableError(e
04149:                                    .getMessage());
04150:                        }
04151:
04152:                    } else
04153:                        typeInfo.datatypeValidator = typeInfo.baseDataTypeValidator;
04154:
04155:                    if (child != null) {
04156:                        //
04157:                        // Check that we have attributes
04158:                        //
04159:                        if (!isAttrOrAttrGroup(child)) {
04160:                            throw new ComplexTypeRecoverableError(
04161:                                    "Invalid child in the RESTRICTION element of simpleContent");
04162:                        } else
04163:                            attrNode = child;
04164:                    }
04165:
04166:                } // end RESTRICTION
04167:
04168:                //
04169:                // EXTENSION
04170:                //
04171:                else {
04172:                    if (typeInfo.baseComplexTypeInfo != null) {
04173:                        typeInfo.baseDataTypeValidator = typeInfo.baseComplexTypeInfo.datatypeValidator;
04174:                        //
04175:                        // Check that the base's final set does not include EXTENSION
04176:                        //
04177:                        if ((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.EXTENSION) != 0) {
04178:                            throw new ComplexTypeRecoverableError(
04179:                                    "Derivation by extension is forbidden by either the base type "
04180:                                            + base + " or the schema");
04181:                        }
04182:                    }
04183:
04184:                    typeInfo.datatypeValidator = typeInfo.baseDataTypeValidator;
04185:
04186:                    //
04187:                    // Look for attributes
04188:                    //
04189:                    if (content != null) {
04190:                        //
04191:                        // Check that we have attributes
04192:                        //
04193:                        if (!isAttrOrAttrGroup(content)) {
04194:                            throw new ComplexTypeRecoverableError(
04195:                                    "Only annotations and attributes are allowed in the "
04196:                                            + "content of an EXTENSION element for a complexType with simpleContent");
04197:                        } else {
04198:                            attrNode = content;
04199:                        }
04200:                    }
04201:
04202:                }
04203:
04204:                // -----------------------------------------------------------------------
04205:                // add a template element to the grammar element decl pool for the type
04206:                // -----------------------------------------------------------------------
04207:                int templateElementNameIndex = fStringPool.addSymbol("$"
04208:                        + typeName);
04209:
04210:                typeInfo.templateElementIndex = fSchemaGrammar
04211:                        .addElementDecl(
04212:                                new QName(-1, templateElementNameIndex,
04213:                                        typeNameIndex, fTargetNSURI),
04214:                                (fTargetNSURI == StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING
04215:                                        : fCurrentScope, typeInfo.scopeDefined,
04216:                                typeInfo.contentType,
04217:                                typeInfo.contentSpecHandle, -1,
04218:                                typeInfo.datatypeValidator);
04219:                typeInfo.attlistHead = fSchemaGrammar
04220:                        .getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
04221:
04222:                // -----------------------------------------------------------------------
04223:                // Process attributes
04224:                // -----------------------------------------------------------------------
04225:                processAttributes(attrNode, baseQName, typeInfo);
04226:
04227:                if (XUtil.getNextSiblingElement(simpleContent) != null)
04228:                    throw new ComplexTypeRecoverableError(
04229:                            "Invalid child following the RESTRICTION or EXTENSION element in the "
04230:                                    + "complex type definition");
04231:
04232:            } // end traverseSimpleContentDecl
04233:
04234:            /**
04235:             * Traverse complexContent Declaration
04236:             *
04237:             *       <complexContent
04238:             *         id = ID
04239:             *         mixed = boolean
04240:             *         {any attributes with non-schema namespace...}>
04241:             *
04242:             *         Content: (annotation? , (restriction | extension))
04243:             *       </complexContent>
04244:             *
04245:             *       <restriction
04246:             *         base = QNAME
04247:             *         id = ID
04248:             *         {any attributes with non-schema namespace...}>
04249:             *
04250:             *         Content: (annotation? , (group | all | choice | sequence)?,
04251:             *                  ((attribute | attributeGroup)* , anyAttribute?))
04252:             *       </restriction>
04253:             *
04254:             *       <extension
04255:             *         base = QNAME
04256:             *         id = ID
04257:             *         {any attributes with non-schema namespace...}>
04258:             *         Content: (annotation? , (group | all | choice | sequence)?,
04259:             *                  ((attribute | attributeGroup)* , anyAttribute?))
04260:             *       </extension>
04261:             *
04262:             * @param typeNameIndex
04263:             * @param simpleContentTypeDecl
04264:             * @param typeInfo
04265:             * @param mixedOnComplexTypeDecl
04266:             * @return
04267:             */
04268:
04269:            private void traverseComplexContentDecl(int typeNameIndex,
04270:                    Element complexContentDecl, ComplexTypeInfo typeInfo,
04271:                    boolean mixedOnComplexTypeDecl) throws Exception {
04272:
04273:                // General Attribute Checking
04274:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
04275:                Hashtable attrValues = generalCheck(complexContentDecl, scope);
04276:
04277:                String typeName = fStringPool.toString(typeNameIndex);
04278:
04279:                // -----------------------------------------------------------------------
04280:                // Get the attributes
04281:                // -----------------------------------------------------------------------
04282:                String typeId = complexContentDecl
04283:                        .getAttribute(SchemaSymbols.ATTVAL_ID);
04284:                String mixed = complexContentDecl
04285:                        .getAttribute(SchemaSymbols.ATT_MIXED);
04286:
04287:                // -----------------------------------------------------------------------
04288:                // Determine whether the content is mixed, or element-only
04289:                // Setting here overrides any setting on the complex type decl
04290:                // -----------------------------------------------------------------------
04291:                boolean isMixed = mixedOnComplexTypeDecl;
04292:                if (mixed.equals(SchemaSymbols.ATTVAL_TRUE)
04293:                        || mixed.equals(SchemaSymbols.ATTVAL_TRUE_1))
04294:                    isMixed = true;
04295:                else if (mixed.equals(SchemaSymbols.ATTVAL_FALSE)
04296:                        || mixed.equals(SchemaSymbols.ATTVAL_FALSE_0))
04297:                    isMixed = false;
04298:
04299:                // -----------------------------------------------------------------------
04300:                // Since the type must have complex content, set the simple type validators
04301:                // to null
04302:                // -----------------------------------------------------------------------
04303:                typeInfo.datatypeValidator = null;
04304:                typeInfo.baseDataTypeValidator = null;
04305:
04306:                Element complexContent = checkContent(complexContentDecl, XUtil
04307:                        .getFirstChildElement(complexContentDecl), false);
04308:
04309:                // If there are no children, return
04310:                if (complexContent == null) {
04311:                    throw new ComplexTypeRecoverableError();
04312:                }
04313:
04314:                // -----------------------------------------------------------------------
04315:                // The content should be either "restriction" or "extension"
04316:                // -----------------------------------------------------------------------
04317:                String complexContentName = complexContent.getLocalName();
04318:                if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION))
04319:                    typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
04320:                else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION))
04321:                    typeInfo.derivedBy = SchemaSymbols.EXTENSION;
04322:                else {
04323:                    throw new ComplexTypeRecoverableError(
04324:                            "The content of the complexContent element is invalid. "
04325:                                    + "The content must be RESTRICTION or EXTENSION");
04326:                }
04327:
04328:                // Get the attributes of the restriction/extension element
04329:                String base = complexContent
04330:                        .getAttribute(SchemaSymbols.ATT_BASE);
04331:                String complexContentTypeId = complexContent
04332:                        .getAttribute(SchemaSymbols.ATTVAL_ID);
04333:
04334:                // Skip over any annotations in the restriction or extension elements
04335:                Element content = checkContent(complexContent, XUtil
04336:                        .getFirstChildElement(complexContent), true);
04337:
04338:                // -----------------------------------------------------------------------
04339:                // Handle the base type name
04340:                // -----------------------------------------------------------------------
04341:                if (base.length() == 0) {
04342:                    throw new ComplexTypeRecoverableError(
04343:                            "The BASE attribute must be specified for the "
04344:                                    + "RESTRICTION or EXTENSION element");
04345:                }
04346:
04347:                QName baseQName = parseBase(base);
04348:
04349:                // -------------------------------------------------------------
04350:                // check if the base is "anyType"
04351:                // -------------------------------------------------------------
04352:                String baseTypeURI = fStringPool.toString(baseQName.uri);
04353:                String baseLocalName = fStringPool
04354:                        .toString(baseQName.localpart);
04355:                if (!(baseTypeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) && baseLocalName
04356:                        .equals("anyType"))) {
04357:
04358:                    processBaseTypeInfo(baseQName, typeInfo);
04359:
04360:                    //Check that the base is a complex type
04361:                    if (typeInfo.baseComplexTypeInfo == null) {
04362:                        throw new ComplexTypeRecoverableError(
04363:                                "The base type specified in the complexContent element must be a complexType");
04364:                    }
04365:                }
04366:
04367:                // -----------------------------------------------------------------------
04368:                // Process the elements that make up the content
04369:                // -----------------------------------------------------------------------
04370:                processComplexContent(typeNameIndex, content, typeInfo,
04371:                        baseQName, isMixed);
04372:
04373:                if (XUtil.getNextSiblingElement(complexContent) != null)
04374:                    throw new ComplexTypeRecoverableError(
04375:                            "Invalid child following the RESTRICTION or EXTENSION element in the "
04376:                                    + "complex type definition");
04377:
04378:            } // end traverseComplexContentDecl
04379:
04380:            /**
04381:             * Handle complexType error
04382:             *
04383:             * @param message
04384:             * @param typeNameIndex
04385:             * @param typeInfo
04386:             * @return
04387:             */
04388:            private void handleComplexTypeError(String message,
04389:                    int typeNameIndex, ComplexTypeInfo typeInfo)
04390:                    throws Exception {
04391:
04392:                String typeName = fStringPool.toString(typeNameIndex);
04393:                if (message != null) {
04394:                    if (typeName.startsWith("#"))
04395:                        reportGenericSchemaError("Anonymous complexType: "
04396:                                + message);
04397:                    else
04398:                        reportGenericSchemaError("ComplexType '" + typeName
04399:                                + "': " + message);
04400:                }
04401:
04402:                //
04403:                //  Mock up the typeInfo structure so that there won't be problems during
04404:                //  validation
04405:                //
04406:                typeInfo.contentType = XMLElementDecl.TYPE_ANY; // this should match anything
04407:                typeInfo.contentSpecHandle = -1;
04408:                typeInfo.derivedBy = 0;
04409:                typeInfo.datatypeValidator = null;
04410:                typeInfo.attlistHead = -1;
04411:
04412:                int templateElementNameIndex = fStringPool.addSymbol("$"
04413:                        + typeName);
04414:                typeInfo.templateElementIndex = fSchemaGrammar
04415:                        .addElementDecl(
04416:                                new QName(-1, templateElementNameIndex,
04417:                                        typeNameIndex, fTargetNSURI),
04418:                                (fTargetNSURI == StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING
04419:                                        : fCurrentScope, typeInfo.scopeDefined,
04420:                                typeInfo.contentType,
04421:                                typeInfo.contentSpecHandle, -1,
04422:                                typeInfo.datatypeValidator);
04423:                return;
04424:            }
04425:
04426:            /**
04427:             * Generate a name for an anonymous type
04428:             *
04429:             * @param Element
04430:             * @return String
04431:             */
04432:            private String genAnonTypeName(Element complexTypeDecl)
04433:                    throws Exception {
04434:
04435:                // Generate a unique name for the anonymous type by concatenating together the
04436:                // names of parent nodes
04437:                String typeName;
04438:                Element node = complexTypeDecl;
04439:                typeName = "#AnonType_";
04440:                while (!isTopLevel(node)) {
04441:                    node = (Element) node.getParentNode();
04442:                    typeName = typeName
04443:                            + node.getAttribute(SchemaSymbols.ATT_NAME);
04444:                }
04445:
04446:                return typeName;
04447:            }
04448:
04449:            /**
04450:             * Parse base string
04451:             *
04452:             * @param base
04453:             * @return QName
04454:             */
04455:            private QName parseBase(String base) throws Exception {
04456:
04457:                String prefix = "";
04458:                String localpart = base;
04459:                int colonptr = base.indexOf(":");
04460:                if (colonptr > 0) {
04461:                    prefix = base.substring(0, colonptr);
04462:                    localpart = base.substring(colonptr + 1);
04463:                }
04464:
04465:                int nameIndex = fStringPool.addSymbol(base);
04466:                int prefixIndex = fStringPool.addSymbol(prefix);
04467:                int localpartIndex = fStringPool.addSymbol(localpart);
04468:                int URIindex = fStringPool
04469:                        .addSymbol(resolvePrefixToURI(prefix));
04470:                return new QName(prefixIndex, localpartIndex, nameIndex,
04471:                        URIindex);
04472:            }
04473:
04474:            /**
04475:             * Check if base is from another schema
04476:             *
04477:             * @param baseName
04478:             * @return boolean
04479:             */
04480:            private boolean baseFromAnotherSchema(QName baseName)
04481:                    throws Exception {
04482:
04483:                String typeURI = fStringPool.toString(baseName.uri);
04484:                if (!typeURI.equals(fTargetNSURIString)
04485:                        && !typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
04486:                        && typeURI.length() != 0)
04487:                    //REVISIT, !!!! a hack: for schema that has no
04488:                    //target namespace, e.g. personal-schema.xml
04489:                    return true;
04490:                else
04491:                    return false;
04492:
04493:            }
04494:
04495:            /**
04496:             * Process "base" information for a complexType
04497:             *
04498:             * @param baseTypeInfo
04499:             * @param baseName
04500:             * @param typeInfo
04501:             * @return
04502:             */
04503:
04504:            private void processBaseTypeInfo(QName baseName,
04505:                    ComplexTypeInfo typeInfo) throws Exception {
04506:
04507:                ComplexTypeInfo baseComplexTypeInfo = null;
04508:                DatatypeValidator baseDTValidator = null;
04509:
04510:                String typeURI = fStringPool.toString(baseName.uri);
04511:                String localpart = fStringPool.toString(baseName.localpart);
04512:                String base = fStringPool.toString(baseName.rawname);
04513:
04514:                // -------------------------------------------------------------
04515:                // check if the base type is from another schema
04516:                // -------------------------------------------------------------
04517:                if (baseFromAnotherSchema(baseName)) {
04518:                    baseComplexTypeInfo = getTypeInfoFromNS(typeURI, localpart);
04519:                    if (baseComplexTypeInfo == null) {
04520:                        baseDTValidator = getTypeValidatorFromNS(typeURI,
04521:                                localpart);
04522:                    }
04523:                }
04524:
04525:                // -------------------------------------------------------------
04526:                // type must be from same schema
04527:                // -------------------------------------------------------------
04528:                else {
04529:                    String fullBaseName = typeURI + "," + localpart;
04530:
04531:                    // assume the base is a complexType and try to locate the base type first
04532:                    baseComplexTypeInfo = (ComplexTypeInfo) fComplexTypeRegistry
04533:                            .get(fullBaseName);
04534:
04535:                    // if not found, 2 possibilities:
04536:                    //           1: ComplexType in question has not been compiled yet;
04537:                    //           2: base is SimpleTYpe;
04538:                    if (baseComplexTypeInfo == null) {
04539:                        baseDTValidator = getDatatypeValidator(typeURI,
04540:                                localpart);
04541:
04542:                        if (baseDTValidator == null) {
04543:                            int baseTypeSymbol;
04544:                            Element baseTypeNode = getTopLevelComponentByName(
04545:                                    SchemaSymbols.ELT_COMPLEXTYPE, localpart);
04546:                            if (baseTypeNode != null) {
04547:                                // Before traversing the base, make sure we're not already
04548:                                // doing so..
04549:                                // ct-props-correct 3
04550:                                if (fBaseTypeNameStack
04551:                                        .search((Object) fullBaseName) > -1) {
04552:                                    throw new ComplexTypeRecoverableError(
04553:                                            "ct-props-correct.3:  Recursive type definition");
04554:                                }
04555:                                fBaseTypeNameStack.push(fullBaseName);
04556:                                baseTypeSymbol = traverseComplexTypeDecl(
04557:                                        baseTypeNode, true);
04558:                                fBaseTypeNameStack.pop();
04559:                                baseComplexTypeInfo = (ComplexTypeInfo) fComplexTypeRegistry
04560:                                        .get(fStringPool
04561:                                                .toString(baseTypeSymbol));
04562:                                //REVISIT: should it be fullBaseName;
04563:                            } else {
04564:                                baseTypeNode = getTopLevelComponentByName(
04565:                                        SchemaSymbols.ELT_SIMPLETYPE, localpart);
04566:                                if (baseTypeNode != null) {
04567:                                    baseTypeSymbol = traverseSimpleTypeDecl(baseTypeNode);
04568:                                    baseDTValidator = getDatatypeValidator(
04569:                                            typeURI, localpart);
04570:                                }
04571:                            }
04572:                        }
04573:                    }
04574:                } // end else (type must be from same schema)
04575:
04576:                //
04577:                //Schema Spec: Complex Type Definition Representation OK : 2
04578:                //
04579:                if (baseComplexTypeInfo == null && baseDTValidator == null) {
04580:                    throw new ComplexTypeRecoverableError(
04581:                            "src-ct.2: Cannot find type definition for '"
04582:                                    + base + "'");
04583:                }
04584:
04585:                typeInfo.baseComplexTypeInfo = baseComplexTypeInfo;
04586:                typeInfo.baseDataTypeValidator = baseDTValidator;
04587:            } // end processBaseTypeInfo
04588:
04589:            /**
04590:             * Process content which is complex
04591:             *
04592:             *     (group | all | choice | sequence) ? ,
04593:             *     ((attribute | attributeGroup)* , anyAttribute?))
04594:             *
04595:             * @param typeNameIndex
04596:             * @param complexContentChild
04597:             * @param typeInfo
04598:             * @return
04599:             */
04600:
04601:            private void processComplexContent(int typeNameIndex,
04602:                    Element complexContentChild, ComplexTypeInfo typeInfo,
04603:                    QName baseName, boolean isMixed) throws Exception {
04604:
04605:                Element attrNode = null;
04606:                int index = -2;
04607:                String typeName = fStringPool.toString(typeNameIndex);
04608:
04609:                if (complexContentChild != null) {
04610:                    // -------------------------------------------------------------
04611:                    // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
04612:                    // Note that it's possible that only attributes are specified.
04613:                    // -------------------------------------------------------------
04614:
04615:                    String childName = complexContentChild.getLocalName();
04616:
04617:                    if (childName.equals(SchemaSymbols.ELT_GROUP)) {
04618:                        GroupInfo grpInfo = traverseGroupDecl(complexContentChild);
04619:                        int groupIndex = (grpInfo != null) ? grpInfo.contentSpecIndex
04620:                                : -2;
04621:
04622:                        index = handleOccurrences(groupIndex,
04623:                                complexContentChild,
04624:                                hasAllContent(groupIndex) ? GROUP_REF_WITH_ALL
04625:                                        : NOT_ALL_CONTEXT);
04626:                        attrNode = XUtil
04627:                                .getNextSiblingElement(complexContentChild);
04628:                    } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
04629:                        index = handleOccurrences(
04630:                                traverseSequence(complexContentChild),
04631:                                complexContentChild);
04632:                        attrNode = XUtil
04633:                                .getNextSiblingElement(complexContentChild);
04634:                    } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
04635:                        index = handleOccurrences(
04636:                                traverseChoice(complexContentChild),
04637:                                complexContentChild);
04638:                        attrNode = XUtil
04639:                                .getNextSiblingElement(complexContentChild);
04640:                    } else if (childName.equals(SchemaSymbols.ELT_ALL)) {
04641:                        index = handleOccurrences(
04642:                                traverseAll(complexContentChild),
04643:                                complexContentChild, PROCESSING_ALL_GP);
04644:                        attrNode = XUtil
04645:                                .getNextSiblingElement(complexContentChild);
04646:                    } else if (isAttrOrAttrGroup(complexContentChild)) {
04647:                        // reset the contentType
04648:                        typeInfo.contentType = XMLElementDecl.TYPE_ANY;
04649:                        attrNode = complexContentChild;
04650:                    } else {
04651:                        throw new ComplexTypeRecoverableError("Invalid child '"
04652:                                + childName + "' in the complex type");
04653:                    }
04654:                }
04655:
04656:                typeInfo.contentSpecHandle = index;
04657:
04658:                // -----------------------------------------------------------------------
04659:                // Merge in information from base, if it exists
04660:                // -----------------------------------------------------------------------
04661:                if (typeInfo.baseComplexTypeInfo != null) {
04662:                    int baseContentSpecHandle = typeInfo.baseComplexTypeInfo.contentSpecHandle;
04663:
04664:                    //-------------------------------------------------------------
04665:                    // RESTRICTION
04666:                    //-------------------------------------------------------------
04667:                    if (typeInfo.derivedBy == SchemaSymbols.RESTRICTION) {
04668:                        // check to see if the baseType permits derivation by restriction
04669:                        if ((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.RESTRICTION) != 0)
04670:                            throw new ComplexTypeRecoverableError(
04671:                                    "Derivation by restriction is forbidden by either the base type "
04672:                                            + fStringPool
04673:                                                    .toString(baseName.localpart)
04674:                                            + " or the schema");
04675:
04676:                        // if the content is EMPTY, check that the base is correct
04677:                        // according to derivation-ok-restriction 5.2
04678:                        if (typeInfo.contentSpecHandle == -2) {
04679:                            if (!(typeInfo.baseComplexTypeInfo.contentType == XMLElementDecl.TYPE_EMPTY || particleEmptiable(baseContentSpecHandle))) {
04680:                                throw new ComplexTypeRecoverableError(
04681:                                        "derivation-ok-restrictoin.5.2 Content type of complexType is EMPTY but base is not EMPTY or does not have a particle which is emptiable");
04682:                            }
04683:                        }
04684:
04685:                        //
04686:                        // Delay derivation by restriction particle constraint checking until
04687:                        // the whole schema has been processed.  We need to do this because:
04688:                        //  - top-level element declarations are not processed until traversed
04689:                        //    thru the main traverseSchema walk.
04690:                        //
04691:                        //
04692:
04693:                    }
04694:                    //-------------------------------------------------------------
04695:                    // EXTENSION
04696:                    //-------------------------------------------------------------
04697:                    else {
04698:                        // check to see if the baseType permits derivation by extension
04699:                        if ((typeInfo.baseComplexTypeInfo.finalSet & SchemaSymbols.EXTENSION) != 0)
04700:                            throw new ComplexTypeRecoverableError(
04701:                                    "cos-ct-extends.1.1: Derivation by extension is forbidden by either the base type "
04702:                                            + fStringPool
04703:                                                    .toString(baseName.localpart)
04704:                                            + " or the schema");
04705:
04706:                        //
04707:                        // Check if the contentType of the base is consistent with the new type
04708:                        // cos-ct-extends.1.4.2.2
04709:                        if (typeInfo.baseComplexTypeInfo.contentType != XMLElementDecl.TYPE_EMPTY) {
04710:                            if (((typeInfo.baseComplexTypeInfo.contentType == XMLElementDecl.TYPE_CHILDREN) && isMixed)
04711:                                    || ((typeInfo.baseComplexTypeInfo.contentType == XMLElementDecl.TYPE_MIXED_COMPLEX) && !isMixed)) {
04712:                                throw new ComplexTypeRecoverableError(
04713:                                        "cos-ct-extends.1.4.2.2.2.1: The content type of the base type "
04714:                                                + fStringPool
04715:                                                        .toString(baseName.localpart)
04716:                                                + " and derived type "
04717:                                                + typeName
04718:                                                + " must both be mixed or element-only");
04719:                            }
04720:
04721:                        }
04722:
04723:                        //
04724:                        // Compose the final content model by concatenating the base and the
04725:                        // current in sequence
04726:                        //
04727:                        if (baseFromAnotherSchema(baseName)) {
04728:                            String baseSchemaURI = fStringPool
04729:                                    .toString(baseName.uri);
04730:                            SchemaGrammar aGrammar = (SchemaGrammar) fGrammarResolver
04731:                                    .getGrammar(baseSchemaURI);
04732:                            baseContentSpecHandle = importContentSpec(aGrammar,
04733:                                    baseContentSpecHandle);
04734:                        }
04735:                        if (typeInfo.contentSpecHandle == -2) {
04736:                            typeInfo.contentSpecHandle = baseContentSpecHandle;
04737:                        } else if (baseContentSpecHandle > -1) {
04738:                            if (typeInfo.contentSpecHandle > -1
04739:                                    && (hasAllContent(typeInfo.contentSpecHandle) || hasAllContent(baseContentSpecHandle))) {
04740:                                throw new ComplexTypeRecoverableError(
04741:                                        "cos-all-limited.1.2:  An \"all\" model group that is part of a complex type definition must constitute the entire {content type} of the definition.");
04742:                            }
04743:
04744:                            typeInfo.contentSpecHandle = fSchemaGrammar
04745:                                    .addContentSpecNode(
04746:                                            XMLContentSpec.CONTENTSPECNODE_SEQ,
04747:                                            baseContentSpecHandle,
04748:                                            typeInfo.contentSpecHandle, false);
04749:                        }
04750:
04751:                        //
04752:                        // Check that there is a particle in the final content
04753:                        // cos-ct-extends.1.4.2.1
04754:                        // LM - commented out until I get a clarification from HT
04755:                        //
04756:                        //if (typeInfo.contentSpecHandle <0) {
04757:                        //     throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.2.1: The content of a type derived by EXTENSION must contain a particle");
04758:                        //}
04759:                    }
04760:                } else {
04761:                    typeInfo.derivedBy = SchemaSymbols.RESTRICTION;
04762:                }
04763:
04764:                // -------------------------------------------------------------
04765:                // Set the content type
04766:                // -------------------------------------------------------------
04767:                if (isMixed) {
04768:
04769:                    // if there are no children, detect an error
04770:                    // See the definition of content type in Structures 3.4.1
04771:                    // This is commented out for now, until I get a clarification from schema WG
04772:                    // LM.
04773:
04774:                    if (typeInfo.contentSpecHandle == -2) {
04775:                        //throw new ComplexTypeRecoverableError("Type '" + typeName + "': The content of a mixed complexType must not be empty");
04776:
04777:                        // for "mixed" complex type with empty content
04778:                        // we add an optional leaf node to the content model
04779:                        // with empty namespace and -1 name (which won't match any element)
04780:                        // so that the result content model is emptible and only match
04781:                        // with cdata
04782:                        int emptyIndex = fSchemaGrammar.addContentSpecNode(
04783:                                XMLContentSpec.CONTENTSPECNODE_LEAF, -1,
04784:                                fStringPool.EMPTY_STRING, false);
04785:                        if (fSchemaGrammar.getDeferContentSpecExpansion()) {
04786:                            fSchemaGrammar.setContentSpecMinOccurs(emptyIndex,
04787:                                    0);
04788:                            fSchemaGrammar.setContentSpecMaxOccurs(emptyIndex,
04789:                                    1);
04790:                            typeInfo.contentSpecHandle = emptyIndex;
04791:                        } else {
04792:                            typeInfo.contentSpecHandle = fSchemaGrammar
04793:                                    .expandContentModel(emptyIndex, 0, 1);
04794:                        }
04795:
04796:                        typeInfo.contentType = XMLElementDecl.TYPE_MIXED_SIMPLE;
04797:                    }
04798:
04799:                    else
04800:                        typeInfo.contentType = XMLElementDecl.TYPE_MIXED_COMPLEX;
04801:                } else if (typeInfo.contentSpecHandle == -2)
04802:                    typeInfo.contentType = XMLElementDecl.TYPE_EMPTY;
04803:                else
04804:                    typeInfo.contentType = XMLElementDecl.TYPE_CHILDREN;
04805:
04806:                // -------------------------------------------------------------
04807:                // add a template element to the grammar element decl pool.
04808:                // -------------------------------------------------------------
04809:                int templateElementNameIndex = fStringPool.addSymbol("$"
04810:                        + typeName);
04811:
04812:                typeInfo.templateElementIndex = fSchemaGrammar
04813:                        .addElementDecl(
04814:                                new QName(-1, templateElementNameIndex,
04815:                                        typeNameIndex, fTargetNSURI),
04816:                                (fTargetNSURI == StringPool.EMPTY_STRING) ? StringPool.EMPTY_STRING
04817:                                        : fCurrentScope, typeInfo.scopeDefined,
04818:                                typeInfo.contentType,
04819:                                typeInfo.contentSpecHandle, -1,
04820:                                typeInfo.datatypeValidator);
04821:                typeInfo.attlistHead = fSchemaGrammar
04822:                        .getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
04823:
04824:                // -------------------------------------------------------------
04825:                // Now, check attributes and handle
04826:                // -------------------------------------------------------------
04827:                if (attrNode != null) {
04828:                    if (!isAttrOrAttrGroup(attrNode)) {
04829:                        throw new ComplexTypeRecoverableError("Invalid child "
04830:                                + attrNode.getLocalName()
04831:                                + " in the complexType or complexContent");
04832:                    } else
04833:                        processAttributes(attrNode, baseName, typeInfo);
04834:                } else if (typeInfo.baseComplexTypeInfo != null)
04835:                    processAttributes(null, baseName, typeInfo);
04836:
04837:            } // end processComplexContent
04838:
04839:            /**
04840:             * Process attributes of a complex type
04841:             *
04842:             * @param attrNode
04843:             * @param typeInfo
04844:             * @return
04845:             */
04846:
04847:            private void processAttributes(Element attrNode, QName baseName,
04848:                    ComplexTypeInfo typeInfo) throws Exception {
04849:
04850:                XMLAttributeDecl attWildcard = null;
04851:                Vector anyAttDecls = new Vector();
04852:
04853:                Element child;
04854:                for (child = attrNode; child != null; child = XUtil
04855:                        .getNextSiblingElement(child)) {
04856:
04857:                    String childName = child.getLocalName();
04858:
04859:                    if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
04860:                        traverseAttributeDecl(child, typeInfo, false);
04861:                    } else if (childName
04862:                            .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
04863:                        traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
04864:
04865:                    } else if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) {
04866:                        attWildcard = traverseAnyAttribute(child);
04867:                    } else {
04868:                        throw new ComplexTypeRecoverableError(
04869:                                "Invalid child among the children of the complexType definition");
04870:                    }
04871:                }
04872:
04873:                if (attWildcard != null) {
04874:                    XMLAttributeDecl fromGroup = null;
04875:                    final int count = anyAttDecls.size();
04876:                    if (count > 0) {
04877:                        fromGroup = (XMLAttributeDecl) anyAttDecls.elementAt(0);
04878:                        for (int i = 1; i < count; i++) {
04879:                            fromGroup = AWildCardIntersection(fromGroup,
04880:                                    (XMLAttributeDecl) anyAttDecls.elementAt(i));
04881:                        }
04882:                    }
04883:                    if (fromGroup != null) {
04884:                        int saveProcessContents = attWildcard.defaultType;
04885:                        attWildcard = AWildCardIntersection(attWildcard,
04886:                                fromGroup);
04887:                        attWildcard.defaultType = saveProcessContents;
04888:                    }
04889:                } else {
04890:                    //REVISIT: unclear in the Scheme Structures 4.3.3 what to do in this case
04891:                    if (anyAttDecls.size() > 0) {
04892:                        attWildcard = (XMLAttributeDecl) anyAttDecls
04893:                                .elementAt(0);
04894:                    }
04895:                }
04896:                //
04897:                // merge in base type's attribute decls
04898:                //
04899:                XMLAttributeDecl baseAttWildcard = null;
04900:                ComplexTypeInfo baseTypeInfo = typeInfo.baseComplexTypeInfo;
04901:
04902:                SchemaGrammar aGrammar = null;
04903:                if (baseTypeInfo != null && baseTypeInfo.attlistHead > -1) {
04904:                    int attDefIndex = baseTypeInfo.attlistHead;
04905:                    aGrammar = fSchemaGrammar;
04906:                    String baseTypeSchemaURI = baseFromAnotherSchema(baseName) ? fStringPool
04907:                            .toString(baseName.uri)
04908:                            : null;
04909:                    if (baseTypeSchemaURI != null) {
04910:                        aGrammar = (SchemaGrammar) fGrammarResolver
04911:                                .getGrammar(baseTypeSchemaURI);
04912:                    }
04913:                    if (aGrammar == null) {
04914:                        //reportGenericSchemaError("In complexType "+typeName+", can NOT find the grammar "+
04915:                        //                       "with targetNamespace" + baseTypeSchemaURI+
04916:                        //                     "for the base type");
04917:                    } else
04918:                        while (attDefIndex > -1) {
04919:                            fTempAttributeDecl.clear();
04920:                            aGrammar.getAttributeDecl(attDefIndex,
04921:                                    fTempAttributeDecl);
04922:                            if (fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_ANY
04923:                                    || fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_LIST
04924:                                    || fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ANY_OTHER) {
04925:                                if (attWildcard == null) {
04926:                                    baseAttWildcard = fTempAttributeDecl;
04927:                                }
04928:                                attDefIndex = aGrammar
04929:                                        .getNextAttributeDeclIndex(attDefIndex);
04930:                                continue;
04931:                            }
04932:                            // if found a duplicate, if it is derived by restriction,
04933:                            // then skip the one from the base type
04934:
04935:                            int temp = fSchemaGrammar.getAttributeDeclIndex(
04936:                                    typeInfo.templateElementIndex,
04937:                                    fTempAttributeDecl.name);
04938:                            if (temp > -1) {
04939:                                if (typeInfo.derivedBy == SchemaSymbols.EXTENSION) {
04940:                                    throw new ComplexTypeRecoverableError(
04941:                                            "Attribute "
04942:                                                    + fStringPool
04943:                                                            .toString(fTempAttributeDecl.name.localpart)
04944:                                                    + " that appeared in the base should not appear in a derivation by extension");
04945:
04946:                                } else {
04947:                                    attDefIndex = fSchemaGrammar
04948:                                            .getNextAttributeDeclIndex(attDefIndex);
04949:                                    continue;
04950:                                }
04951:                            }
04952:
04953:                            fSchemaGrammar.addAttDef(
04954:                                    typeInfo.templateElementIndex,
04955:                                    fTempAttributeDecl.name,
04956:                                    fTempAttributeDecl.type,
04957:                                    fTempAttributeDecl.enumeration,
04958:                                    fTempAttributeDecl.defaultType,
04959:                                    fTempAttributeDecl.defaultValue,
04960:                                    fTempAttributeDecl.datatypeValidator,
04961:                                    fTempAttributeDecl.list);
04962:                            attDefIndex = aGrammar
04963:                                    .getNextAttributeDeclIndex(attDefIndex);
04964:                        }
04965:                }
04966:
04967:                // att wildcard will inserted after all attributes were processed
04968:                if (attWildcard != null) {
04969:                    if (attWildcard.type != -1) {
04970:                        fSchemaGrammar
04971:                                .addAttDef(typeInfo.templateElementIndex,
04972:                                        attWildcard.name, attWildcard.type,
04973:                                        attWildcard.enumeration,
04974:                                        attWildcard.defaultType,
04975:                                        attWildcard.defaultValue,
04976:                                        attWildcard.datatypeValidator,
04977:                                        attWildcard.list);
04978:                    } else {
04979:                        //REVISIT: unclear in Schema spec if should report error here.
04980:                        reportGenericSchemaError("The intensional intersection for {attribute wildcard}s must be expressible");
04981:                    }
04982:                } else if (baseAttWildcard != null) {
04983:                    fSchemaGrammar.addAttDef(typeInfo.templateElementIndex,
04984:                            baseAttWildcard.name, baseAttWildcard.type,
04985:                            baseAttWildcard.enumeration,
04986:                            baseAttWildcard.defaultType,
04987:                            baseAttWildcard.defaultValue,
04988:                            baseAttWildcard.datatypeValidator,
04989:                            baseAttWildcard.list);
04990:                }
04991:
04992:                typeInfo.attlistHead = fSchemaGrammar
04993:                        .getFirstAttributeDeclIndex(typeInfo.templateElementIndex);
04994:
04995:                // For derivation by restriction, ensure that the resulting attribute list
04996:                // satisfies the constraints in derivation-ok-restriction 2,3,4
04997:                if ((typeInfo.derivedBy == SchemaSymbols.RESTRICTION)
04998:                        && (typeInfo.attlistHead > -1 && baseTypeInfo != null)) {
04999:                    checkAttributesDerivationOKRestriction(
05000:                            typeInfo.attlistHead, fSchemaGrammar, attWildcard,
05001:                            baseTypeInfo.attlistHead, aGrammar, baseAttWildcard);
05002:                }
05003:
05004:            } // end processAttributes
05005:
05006:            // Check that the attributes of a type derived by restriction satisfy the
05007:            // constraints of derivation-ok-restriction
05008:
05009:            private void checkAttributesDerivationOKRestriction(
05010:                    int dAttListHead, SchemaGrammar dGrammar,
05011:                    XMLAttributeDecl dAttWildCard, int bAttListHead,
05012:                    SchemaGrammar bGrammar, XMLAttributeDecl bAttWildCard)
05013:                    throws ComplexTypeRecoverableError {
05014:
05015:                int attDefIndex = dAttListHead;
05016:
05017:                if (bAttListHead < 0) {
05018:                    throw new ComplexTypeRecoverableError(
05019:                            "derivation-ok-restriction.2:  Base type definition does not have any attributes");
05020:                }
05021:
05022:                // Loop thru the attributes
05023:                while (attDefIndex > -1) {
05024:                    fTempAttributeDecl.clear();
05025:                    dGrammar.getAttributeDecl(attDefIndex, fTempAttributeDecl);
05026:                    if (isAWildCard(fTempAttributeDecl)) {
05027:                        attDefIndex = dGrammar
05028:                                .getNextAttributeDeclIndex(attDefIndex);
05029:                        continue;
05030:                    }
05031:                    int bAttDefIndex = bGrammar.findAttributeDecl(bAttListHead,
05032:                            fTempAttributeDecl.name);
05033:                    if (bAttDefIndex > -1) {
05034:                        fTemp2AttributeDecl.clear();
05035:                        bGrammar.getAttributeDecl(bAttDefIndex,
05036:                                fTemp2AttributeDecl);
05037:
05038:                        // derivation-ok-restriction.  Constraint 2.1.1
05039:                        if ((fTemp2AttributeDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) > 0
05040:                                && (fTempAttributeDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_REQUIRED) <= 0) {
05041:                            throw new ComplexTypeRecoverableError(
05042:                                    "derivation-ok-restriction.2.1.1:  Attribute '"
05043:                                            + fStringPool
05044:                                                    .toString(fTempAttributeDecl.name.localpart)
05045:                                            + "' in derivation has an inconsistent REQUIRED setting to that of attribute in base");
05046:                        }
05047:
05048:                        //
05049:                        // derivation-ok-restriction.  Constraint 2.1.2
05050:                        //
05051:                        if (!(checkSimpleTypeDerivationOK(
05052:                                fTempAttributeDecl.datatypeValidator,
05053:                                fTemp2AttributeDecl.datatypeValidator))) {
05054:                            throw new ComplexTypeRecoverableError(
05055:                                    "derivation-ok-restriction.2.1.2:  Type of attribute '"
05056:                                            + fStringPool
05057:                                                    .toString(fTempAttributeDecl.name.localpart)
05058:                                            + "' in derivation must be a restriction of type of attribute in base");
05059:                        }
05060:
05061:                        //
05062:                        // derivation-ok-restriction.  Constraint 2.1.3
05063:                        //
05064:                        if ((fTemp2AttributeDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0) {
05065:
05066:                            if (!((fTempAttributeDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) > 0)
05067:                                    || !fTempAttributeDecl.defaultValue
05068:                                            .equals(fTemp2AttributeDecl.defaultValue)) {
05069:
05070:                                throw new ComplexTypeRecoverableError(
05071:                                        "derivation-ok-restriction.2.1.3:  Attribute '"
05072:                                                + fStringPool
05073:                                                        .toString(fTempAttributeDecl.name.localpart)
05074:                                                + "' is either not fixed, or is not fixed with the same value as the attribute in the base");
05075:                            }
05076:                        }
05077:
05078:                    } else {
05079:                        //
05080:                        // derivation-ok-restriction.  Constraint 2.2
05081:                        //
05082:                        if ((bAttWildCard == null)
05083:                                || !AWildCardAllowsNameSpace(bAttWildCard,
05084:                                        dGrammar.getTargetNamespaceURI())) {
05085:                            throw new ComplexTypeRecoverableError(
05086:                                    "derivation-ok-restriction.2.2:  Attribute '"
05087:                                            + fStringPool
05088:                                                    .toString(fTempAttributeDecl.name.localpart)
05089:                                            + "' has a target namespace which is not valid with respect to a base type definition's wildcard or, the base does not contain a wildcard");
05090:
05091:                        }
05092:                    }
05093:                    attDefIndex = dGrammar
05094:                            .getNextAttributeDeclIndex(attDefIndex);
05095:
05096:                }
05097:
05098:                // derivation-ok-restriction.  Constraint 4
05099:                if (dAttWildCard != null) {
05100:                    if (bAttWildCard == null) {
05101:                        throw new ComplexTypeRecoverableError(
05102:                                "derivation-ok-restriction.4.1: An attribute wildcard is present in the derived type, but not the base");
05103:                    }
05104:
05105:                    if (!AWildCardSubset(dAttWildCard, bAttWildCard)) {
05106:                        throw new ComplexTypeRecoverableError(
05107:                                "derivation-ok-restriction.4.2: The attribute wildcard in the derived type is not a valid subset of that in the base");
05108:
05109:                    }
05110:                }
05111:            }
05112:
05113:            private boolean isAttrOrAttrGroup(Element e) {
05114:                String elementName = e.getLocalName();
05115:
05116:                if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE)
05117:                        || elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)
05118:                        || elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE))
05119:                    return true;
05120:                else
05121:                    return false;
05122:            }
05123:
05124:            private void checkRecursingComplexType() throws Exception {
05125:                if (fCurrentTypeNameStack.empty()) {
05126:                    if (!fElementRecurseComplex.isEmpty()) {
05127:
05128:                        int count = fElementRecurseComplex.size();
05129:
05130:                        for (int i = 0; i < count; i++) {
05131:
05132:                            ElementInfo eobj = (ElementInfo) fElementRecurseComplex
05133:                                    .elementAt(i);
05134:                            int elementIndex = eobj.elementIndex;
05135:                            String typeName = eobj.typeName;
05136:
05137:                            ComplexTypeInfo typeInfo = (ComplexTypeInfo) fComplexTypeRegistry
05138:                                    .get(fTargetNSURIString + "," + typeName);
05139:                            if (typeInfo == null) {
05140:                                throw new Exception(
05141:                                        "Internal Error in void checkRecursingComplexType(). ");
05142:                            } else {
05143:                                // update the element decl with info from the type
05144:
05145:                                fSchemaGrammar.getElementDecl(elementIndex,
05146:                                        fTempElementDecl);
05147:                                fTempElementDecl.type = typeInfo.contentType;
05148:                                fTempElementDecl.contentSpecIndex = typeInfo.contentSpecHandle;
05149:                                fTempElementDecl.datatypeValidator = typeInfo.datatypeValidator;
05150:                                fSchemaGrammar.setElementDecl(elementIndex,
05151:                                        fTempElementDecl);
05152:
05153:                                fSchemaGrammar.setFirstAttributeDeclIndex(
05154:                                        elementIndex, typeInfo.attlistHead);
05155:                                fSchemaGrammar.setElementComplexTypeInfo(
05156:                                        elementIndex, typeInfo);
05157:                                fSchemaGrammar.setElementDefinedScope(
05158:                                        elementIndex, typeInfo.scopeDefined);
05159:                            }
05160:                        }
05161:                        fElementRecurseComplex.removeAllElements();
05162:                    }
05163:                }
05164:            }
05165:
05166:            // Check that the particle defined by the derived ct tree is a valid restriction of
05167:            // that specified by baseContentSpecIndex.   derivedScope and baseScope are the
05168:            // scopes of the particles, respectively.  bInfo is supplied when the base particle
05169:            // is from a base type definition, and may be null - it helps determine other scopes
05170:            // that elements should be looked up in.
05171:
05172:            private void checkParticleDerivationOK(int derivedContentSpecIndex,
05173:                    int derivedScope, int baseContentSpecIndex, int baseScope,
05174:                    ComplexTypeInfo bInfo) throws Exception {
05175:
05176:                // Only do this if full checking is enabled
05177:                if (!fFullConstraintChecking)
05178:                    return;
05179:
05180:                // Check for pointless occurrences of all, choice, sequence.  The result is the
05181:                // contentspec which is not pointless.   If the result is a non-pointless
05182:                // group, Vector is filled  in with the children of interest
05183:                int csIndex1 = derivedContentSpecIndex;
05184:                fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
05185:                int csIndex2 = baseContentSpecIndex;
05186:                fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
05187:
05188:                Vector tempVector1 = new Vector();
05189:                Vector tempVector2 = new Vector();
05190:
05191:                if (tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_SEQ
05192:                        || tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_CHOICE
05193:                        || tempContentSpec1.type == XMLContentSpec.CONTENTSPECNODE_ALL) {
05194:                    csIndex1 = checkForPointlessOccurrences(csIndex1,
05195:                            tempVector1);
05196:                }
05197:                if (tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_SEQ
05198:                        || tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_CHOICE
05199:                        || tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_ALL) {
05200:                    csIndex2 = checkForPointlessOccurrences(csIndex2,
05201:                            tempVector2);
05202:                }
05203:
05204:                fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
05205:                fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
05206:
05207:                switch (tempContentSpec1.type & 0x0f) {
05208:                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05209:                    switch (tempContentSpec2.type & 0x0f) {
05210:
05211:                    // Elt:Elt NameAndTypeOK
05212:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05213:                        checkNameAndTypeOK(csIndex1, derivedScope, csIndex2,
05214:                                baseScope, bInfo);
05215:                        return;
05216:                    }
05217:
05218:                        // Elt:Any NSCompat
05219:                    case XMLContentSpec.CONTENTSPECNODE_ANY:
05220:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05221:                    case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05222:                        checkNSCompat(csIndex1, derivedScope, csIndex2);
05223:                        return;
05224:                    }
05225:
05226:                        // Elt:All RecurseAsIfGroup
05227:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE:
05228:                    case XMLContentSpec.CONTENTSPECNODE_SEQ:
05229:                    case XMLContentSpec.CONTENTSPECNODE_ALL: {
05230:                        checkRecurseAsIfGroup(csIndex1, derivedScope, csIndex2,
05231:                                tempVector2, baseScope, bInfo);
05232:                        return;
05233:                    }
05234:
05235:                    default: {
05236:                        throw new ParticleRecoverableError(
05237:                                "internal Xerces error");
05238:                    }
05239:                    }
05240:                }
05241:
05242:                case XMLContentSpec.CONTENTSPECNODE_ANY:
05243:                case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05244:                case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05245:                    switch (tempContentSpec2.type & 0x0f) {
05246:
05247:                    // Any:Any NSSubset
05248:                    case XMLContentSpec.CONTENTSPECNODE_ANY:
05249:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05250:                    case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05251:                        checkNSSubset(csIndex1, csIndex2);
05252:                        return;
05253:                    }
05254:
05255:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE:
05256:                    case XMLContentSpec.CONTENTSPECNODE_SEQ:
05257:                    case XMLContentSpec.CONTENTSPECNODE_ALL:
05258:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05259:                        throw new ParticleRecoverableError(
05260:                                "cos-particle-restrict: Forbidden restriction: Any: Choice,Seq,All,Elt");
05261:                    }
05262:
05263:                    default: {
05264:                        throw new ParticleRecoverableError(
05265:                                "internal Xerces error");
05266:                    }
05267:                    }
05268:                }
05269:
05270:                case XMLContentSpec.CONTENTSPECNODE_ALL: {
05271:                    switch (tempContentSpec2.type & 0x0f) {
05272:
05273:                    // All:Any NSRecurseCheckCardinality
05274:                    case XMLContentSpec.CONTENTSPECNODE_ANY:
05275:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05276:                    case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05277:                        checkNSRecurseCheckCardinality(csIndex1, tempVector1,
05278:                                derivedScope, csIndex2);
05279:                        return;
05280:                    }
05281:
05282:                    case XMLContentSpec.CONTENTSPECNODE_ALL: {
05283:                        checkRecurse(csIndex1, tempVector1, derivedScope,
05284:                                csIndex2, tempVector2, baseScope, bInfo);
05285:                        return;
05286:                    }
05287:
05288:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE:
05289:                    case XMLContentSpec.CONTENTSPECNODE_SEQ:
05290:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05291:                        throw new ParticleRecoverableError(
05292:                                "cos-particle-restrict: Forbidden restriction: All:Choice,Seq,Elt");
05293:                    }
05294:
05295:                    default: {
05296:                        throw new ParticleRecoverableError(
05297:                                "internal Xerces error");
05298:                    }
05299:                    }
05300:                }
05301:
05302:                case XMLContentSpec.CONTENTSPECNODE_CHOICE: {
05303:                    switch (tempContentSpec2.type & 0x0f) {
05304:
05305:                    // Choice:Any NSRecurseCheckCardinality
05306:                    case XMLContentSpec.CONTENTSPECNODE_ANY:
05307:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05308:                    case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05309:                        checkNSRecurseCheckCardinality(csIndex1, tempVector1,
05310:                                derivedScope, csIndex2);
05311:                        return;
05312:                    }
05313:
05314:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE: {
05315:                        checkRecurseLax(csIndex1, tempVector1, derivedScope,
05316:                                csIndex2, tempVector2, baseScope, bInfo);
05317:                        return;
05318:                    }
05319:
05320:                    case XMLContentSpec.CONTENTSPECNODE_ALL:
05321:                    case XMLContentSpec.CONTENTSPECNODE_SEQ:
05322:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05323:                        throw new ParticleRecoverableError(
05324:                                "cos-particle-restrict: Forbidden restriction: Choice:All,Seq,Leaf");
05325:                    }
05326:
05327:                    default: {
05328:                        throw new ParticleRecoverableError(
05329:                                "internal Xerces error");
05330:                    }
05331:                    }
05332:                }
05333:
05334:                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
05335:                    switch (tempContentSpec2.type & 0x0f) {
05336:
05337:                    // Choice:Any NSRecurseCheckCardinality
05338:                    case XMLContentSpec.CONTENTSPECNODE_ANY:
05339:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER:
05340:                    case XMLContentSpec.CONTENTSPECNODE_ANY_NS: {
05341:                        checkNSRecurseCheckCardinality(csIndex1, tempVector1,
05342:                                derivedScope, csIndex2);
05343:                        return;
05344:                    }
05345:
05346:                    case XMLContentSpec.CONTENTSPECNODE_ALL: {
05347:                        checkRecurseUnordered(csIndex1, tempVector1,
05348:                                derivedScope, csIndex2, tempVector2, baseScope,
05349:                                bInfo);
05350:                        return;
05351:                    }
05352:
05353:                    case XMLContentSpec.CONTENTSPECNODE_SEQ: {
05354:                        checkRecurse(csIndex1, tempVector1, derivedScope,
05355:                                csIndex2, tempVector2, baseScope, bInfo);
05356:                        return;
05357:                    }
05358:
05359:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE: {
05360:                        checkMapAndSum(csIndex1, tempVector1, derivedScope,
05361:                                csIndex2, tempVector2, baseScope, bInfo);
05362:                        return;
05363:                    }
05364:
05365:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
05366:                        throw new ParticleRecoverableError(
05367:                                "cos-particle-restrict: Forbidden restriction: Seq:Elt");
05368:                    }
05369:
05370:                    default: {
05371:                        throw new ParticleRecoverableError(
05372:                                "internal Xerces error");
05373:                    }
05374:                    }
05375:                }
05376:
05377:                }
05378:
05379:            }
05380:
05381:            private int checkForPointlessOccurrences(int csIndex,
05382:                    Vector tempVector) {
05383:
05384:                // Note:  instead of using a Vector, we should use a growable array of int.
05385:                // To be cleaned up in release 1.4.1. (LM)
05386:
05387:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
05388:
05389:                if (tempContentSpec1.otherValue == -2) {
05390:                    gatherChildren(tempContentSpec1.type,
05391:                            tempContentSpec1.value, tempVector);
05392:                    if (tempVector.size() == 1) {
05393:                        Integer returnVal = (Integer) (tempVector.elementAt(0));
05394:                        return returnVal.intValue();
05395:                    }
05396:                    return csIndex;
05397:                }
05398:
05399:                int type = tempContentSpec1.type;
05400:                int value = tempContentSpec1.value;
05401:                int otherValue = tempContentSpec1.otherValue;
05402:
05403:                gatherChildren(type, value, tempVector);
05404:                gatherChildren(type, otherValue, tempVector);
05405:
05406:                return csIndex;
05407:            }
05408:
05409:            private void gatherChildren(int parentType, int csIndex,
05410:                    Vector tempVector) {
05411:
05412:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
05413:                int min = fSchemaGrammar.getContentSpecMinOccurs(csIndex);
05414:                int max = fSchemaGrammar.getContentSpecMaxOccurs(csIndex);
05415:                int left = tempContentSpec1.value;
05416:                int right = tempContentSpec1.otherValue;
05417:                int type = tempContentSpec1.type;
05418:
05419:                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF
05420:                        || (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY
05421:                        || (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS
05422:                        || (type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
05423:                    tempVector.addElement(new Integer(csIndex));
05424:                } else if (!(min == 1 && max == 1)) {
05425:                    tempVector.addElement(new Integer(csIndex));
05426:                } else if (right == -2) {
05427:                    gatherChildren(type, left, tempVector);
05428:                } else if (parentType == type) {
05429:                    gatherChildren(type, left, tempVector);
05430:                    gatherChildren(type, right, tempVector);
05431:                } else {
05432:                    tempVector.addElement(new Integer(csIndex));
05433:                }
05434:
05435:            }
05436:
05437:            private void checkNameAndTypeOK(int csIndex1, int derivedScope,
05438:                    int csIndex2, int baseScope, ComplexTypeInfo bInfo)
05439:                    throws Exception {
05440:
05441:                fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
05442:                fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
05443:
05444:                int localpart1 = tempContentSpec1.value;
05445:                int uri1 = tempContentSpec1.otherValue;
05446:                int localpart2 = tempContentSpec2.value;
05447:                int uri2 = tempContentSpec2.otherValue;
05448:
05449:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05450:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05451:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05452:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05453:
05454:                //start the checking...
05455:                if (!(localpart1 == localpart2 && uri1 == uri2)) {
05456:
05457:                    // we have non-matching names.   Check substitution groups.
05458:                    if (fSComp == null)
05459:                        fSComp = new SubstitutionGroupComparator(
05460:                                fGrammarResolver, fStringPool, fErrorReporter);
05461:                    if (!checkSubstitutionGroups(localpart1, uri1, localpart2,
05462:                            uri2))
05463:                        throw new ParticleRecoverableError(
05464:                                "rcase-nameAndTypeOK.1:  Element name/uri in restriction does not match that of corresponding base element");
05465:                }
05466:
05467:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05468:                    throw new ParticleRecoverableError(
05469:                            "rcase-nameAndTypeOK.3:  Element occurrence range not a restriction of base element's range: element is "
05470:                                    + fStringPool.toString(localpart1));
05471:                }
05472:
05473:                SchemaGrammar aGrammar = fSchemaGrammar;
05474:
05475:                // get the element decl indices for the remainder...
05476:                String schemaURI = fStringPool.toString(uri1);
05477:                if (!schemaURI.equals(fTargetNSURIString)
05478:                        && schemaURI.length() != 0)
05479:                    aGrammar = (SchemaGrammar) fGrammarResolver
05480:                            .getGrammar(schemaURI);
05481:
05482:                int eltndx1 = findElement(derivedScope, uri1, localpart1,
05483:                        aGrammar, null);
05484:                if (eltndx1 < 0)
05485:                    return;
05486:
05487:                int eltndx2 = findElement(baseScope, uri2, localpart2,
05488:                        aGrammar, bInfo);
05489:                if (eltndx2 < 0)
05490:                    return;
05491:
05492:                int miscFlags1 = ((SchemaGrammar) aGrammar)
05493:                        .getElementDeclMiscFlags(eltndx1);
05494:                int miscFlags2 = ((SchemaGrammar) aGrammar)
05495:                        .getElementDeclMiscFlags(eltndx2);
05496:                boolean element1IsNillable = (miscFlags1 & SchemaSymbols.NILLABLE) != 0;
05497:                boolean element2IsNillable = (miscFlags2 & SchemaSymbols.NILLABLE) != 0;
05498:                boolean element2IsFixed = (miscFlags2 & SchemaSymbols.FIXED) != 0;
05499:                boolean element1IsFixed = (miscFlags1 & SchemaSymbols.FIXED) != 0;
05500:                String element1Value = aGrammar.getElementDefaultValue(eltndx1);
05501:                String element2Value = aGrammar.getElementDefaultValue(eltndx2);
05502:
05503:                if (!(element2IsNillable || !element1IsNillable)) {
05504:                    throw new ParticleRecoverableError(
05505:                            "rcase-nameAndTypeOK.2:  Element "
05506:                                    + fStringPool.toString(localpart1)
05507:                                    + " is nillable in the restriction but not the base");
05508:                }
05509:
05510:                if (!(element2Value == null || !element2IsFixed || (element1IsFixed && element1Value
05511:                        .equals(element2Value)))) {
05512:                    throw new ParticleRecoverableError(
05513:                            "rcase-nameAndTypeOK.4:  Element "
05514:                                    + fStringPool.toString(localpart1)
05515:                                    + " is either not fixed, or is not fixed with the same value as in the base");
05516:                }
05517:
05518:                // check disallowed substitutions
05519:                int blockSet1 = ((SchemaGrammar) aGrammar)
05520:                        .getElementDeclBlockSet(eltndx1);
05521:                int blockSet2 = ((SchemaGrammar) aGrammar)
05522:                        .getElementDeclBlockSet(eltndx2);
05523:                if (((blockSet1 & blockSet2) != blockSet2)
05524:                        || (blockSet1 == 0 && blockSet2 != 0))
05525:                    throw new ParticleRecoverableError(
05526:                            "rcase-nameAndTypeOK.6:  Element "
05527:                                    + fStringPool.toString(localpart1)
05528:                                    + "'s disallowed subsitutions are not a superset of those of the base element's");
05529:
05530:                // Need element decls for the remainder of the checks
05531:                aGrammar.getElementDecl(eltndx1, fTempElementDecl);
05532:                aGrammar.getElementDecl(eltndx2, fTempElementDecl2);
05533:
05534:                // check identity constraints
05535:                checkIDConstraintRestriction(fTempElementDecl,
05536:                        fTempElementDecl2, aGrammar, localpart1, localpart2);
05537:
05538:                // check that the derived element's type is derived from the base's. - TO BE DONE
05539:                checkTypesOK(fTempElementDecl, fTempElementDecl2, eltndx1,
05540:                        eltndx2, aGrammar, fStringPool.toString(localpart1));
05541:
05542:            }
05543:
05544:            private void checkTypesOK(XMLElementDecl derived,
05545:                    XMLElementDecl base, int dndx, int bndx,
05546:                    SchemaGrammar aGrammar, String elementName)
05547:                    throws Exception {
05548:
05549:                ComplexTypeInfo tempType = ((SchemaGrammar) aGrammar)
05550:                        .getElementComplexTypeInfo(dndx);
05551:                ComplexTypeInfo bType = ((SchemaGrammar) aGrammar)
05552:                        .getElementComplexTypeInfo(bndx);
05553:                if (derived.type == XMLElementDecl.TYPE_SIMPLE) {
05554:
05555:                    if (base.type != XMLElementDecl.TYPE_SIMPLE
05556:                            && base.type != XMLElementDecl.TYPE_ANY)
05557:                        throw new ParticleRecoverableError(
05558:                                "rcase-nameAndTypeOK.6:  Derived element "
05559:                                        + elementName
05560:                                        + " has a type that does not derive from that of the base");
05561:
05562:                    if (tempType == null) {
05563:                        if (!(checkSimpleTypeDerivationOK(
05564:                                derived.datatypeValidator,
05565:                                base.datatypeValidator))
05566:                                && !(bType == null && base.datatypeValidator == null))
05567:                            throw new ParticleRecoverableError(
05568:                                    "rcase-nameAndTypeOK.6:  Derived element "
05569:                                            + elementName
05570:                                            + " has a type that does not derive from that of the base");
05571:                        return;
05572:                    }
05573:                }
05574:
05575:                for (; tempType != null; tempType = tempType.baseComplexTypeInfo) {
05576:                    if (bType != null
05577:                            && tempType.typeName.equals(bType.typeName))
05578:                        break;
05579:                    if (tempType.derivedBy != SchemaSymbols.RESTRICTION) {
05580:                        throw new ParticleRecoverableError(
05581:                                "rcase-nameAndTypeOK.6:  Derived element "
05582:                                        + elementName
05583:                                        + " has a type that does not derive from that of the base");
05584:                    }
05585:                }
05586:
05587:                if (tempType == null
05588:                        && !(bType == null && base.datatypeValidator == null)) {
05589:                    throw new ParticleRecoverableError(
05590:                            "rcase-nameAndTypeOK.6:  Derived element "
05591:                                    + elementName
05592:                                    + " has a type that does not derive from that of the base");
05593:                }
05594:            }
05595:
05596:            private void checkIDConstraintRestriction(
05597:                    XMLElementDecl derivedElemDecl,
05598:                    XMLElementDecl baseElemDecl, SchemaGrammar grammar,
05599:                    int derivedElemName, int baseElemName) throws Exception {
05600:                // this method throws no errors if the ID constraints on
05601:                // the derived element are a logical subset of those on the
05602:                // base element--that is, those that are present are
05603:                // identical to ones in the base element.
05604:                Vector derivedUnique = derivedElemDecl.unique;
05605:                Vector baseUnique = baseElemDecl.unique;
05606:                if (derivedUnique.size() > baseUnique.size()) {
05607:                    throw new ParticleRecoverableError(
05608:                            "rcase-nameAndTypeOK.5:  derived element "
05609:                                    + fStringPool.toString(derivedElemName)
05610:                                    + " has fewer <unique> Identity Constraints than the base element"
05611:                                    + fStringPool.toString(baseElemName));
05612:                } else {
05613:                    boolean found = true;
05614:                    for (int i = 0; i < derivedUnique.size() && found; i++) {
05615:                        Unique id = (Unique) derivedUnique.elementAt(i);
05616:                        found = false;
05617:                        for (int j = 0; j < baseUnique.size(); j++) {
05618:                            if (id.equals((Unique) baseUnique.elementAt(j))) {
05619:                                found = true;
05620:                                break;
05621:                            }
05622:                        }
05623:                    }
05624:                    if (!found) {
05625:                        throw new ParticleRecoverableError(
05626:                                "rcase-nameAndTypeOK.5:  derived element "
05627:                                        + fStringPool.toString(derivedElemName)
05628:                                        + " has a <unique> Identity Constraint that does not appear on the base element"
05629:                                        + fStringPool.toString(baseElemName));
05630:                    }
05631:                }
05632:
05633:                Vector derivedKey = derivedElemDecl.key;
05634:                Vector baseKey = baseElemDecl.key;
05635:                if (derivedKey.size() > baseKey.size()) {
05636:                    throw new ParticleRecoverableError(
05637:                            "rcase-nameAndTypeOK.5:  derived element "
05638:                                    + fStringPool.toString(derivedElemName)
05639:                                    + " has fewer <key> Identity Constraints than the base element"
05640:                                    + fStringPool.toString(baseElemName));
05641:                } else {
05642:                    boolean found = true;
05643:                    for (int i = 0; i < derivedKey.size() && found; i++) {
05644:                        Key id = (Key) derivedKey.elementAt(i);
05645:                        found = false;
05646:                        for (int j = 0; j < baseKey.size(); j++) {
05647:                            if (id.equals((Key) baseKey.elementAt(j))) {
05648:                                found = true;
05649:                                break;
05650:                            }
05651:                        }
05652:                    }
05653:                    if (!found) {
05654:                        throw new ParticleRecoverableError(
05655:                                "rcase-nameAndTypeOK.5:  derived element "
05656:                                        + fStringPool.toString(derivedElemName)
05657:                                        + " has a <key> Identity Constraint that does not appear on the base element"
05658:                                        + fStringPool.toString(baseElemName));
05659:                    }
05660:                }
05661:
05662:                Vector derivedKeyRef = derivedElemDecl.keyRef;
05663:                Vector baseKeyRef = baseElemDecl.keyRef;
05664:                if (derivedKeyRef.size() > baseKeyRef.size()) {
05665:                    throw new ParticleRecoverableError(
05666:                            "rcase-nameAndTypeOK.5:  derived element "
05667:                                    + fStringPool.toString(derivedElemName)
05668:                                    + " has fewer <keyref> Identity Constraints than the base element"
05669:                                    + fStringPool.toString(baseElemName));
05670:                } else {
05671:                    boolean found = true;
05672:                    for (int i = 0; i < derivedKeyRef.size() && found; i++) {
05673:                        KeyRef id = (KeyRef) derivedKeyRef.elementAt(i);
05674:                        found = false;
05675:                        for (int j = 0; j < baseKeyRef.size(); j++) {
05676:                            if (id.equals((KeyRef) baseKeyRef.elementAt(j))) {
05677:                                found = true;
05678:                                break;
05679:                            }
05680:                        }
05681:                    }
05682:                    if (!found) {
05683:                        throw new ParticleRecoverableError(
05684:                                "rcase-nameAndTypeOK.5:  derived element "
05685:                                        + fStringPool.toString(derivedElemName)
05686:                                        + " has a <keyref> Identity Constraint that does not appear on the base element"
05687:                                        + fStringPool.toString(baseElemName));
05688:                    }
05689:                }
05690:            } // checkIDConstraintRestriction
05691:
05692:            private boolean checkSubstitutionGroups(int local1, int uri1,
05693:                    int local2, int uri2) throws Exception {
05694:
05695:                // check if either name is in the other's substitution group
05696:                QName name1 = new QName(-1, local1, local1, uri1);
05697:                QName name2 = new QName(-1, local2, local2, uri2);
05698:
05699:                if (fSComp.isEquivalentTo(name1, name2)
05700:                        || fSComp.isEquivalentTo(name2, name1))
05701:                    return true;
05702:                else
05703:                    return false;
05704:
05705:            }
05706:
05707:            private boolean checkOccurrenceRange(int min1, int max1, int min2,
05708:                    int max2) {
05709:
05710:                if ((min1 >= min2)
05711:                        && ((max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED) || (max1 != SchemaSymbols.OCCURRENCE_UNBOUNDED && max1 <= max2)))
05712:                    return true;
05713:                else
05714:                    return false;
05715:            }
05716:
05717:            private int findElement(int scope, int uriIndex, int nameIndex,
05718:                    SchemaGrammar gr, ComplexTypeInfo bInfo) {
05719:
05720:                // check for element at given scope first
05721:                int elementDeclIndex = gr.getElementDeclIndex(uriIndex,
05722:                        nameIndex, scope);
05723:
05724:                // if not found, check at global scope
05725:                if (elementDeclIndex == -1) {
05726:                    elementDeclIndex = gr.getElementDeclIndex(nameIndex, -1);
05727:
05728:                    // if still not found, and base is specified, look it up there
05729:                    if (elementDeclIndex == -1 && bInfo != null) {
05730:                        ComplexTypeInfo baseInfo = bInfo;
05731:                        while (baseInfo != null) {
05732:                            elementDeclIndex = gr.getElementDeclIndex(
05733:                                    nameIndex, baseInfo.scopeDefined);
05734:                            if (elementDeclIndex > -1)
05735:                                break;
05736:                            baseInfo = baseInfo.baseComplexTypeInfo;
05737:                        }
05738:                    }
05739:
05740:                }
05741:                return elementDeclIndex;
05742:            }
05743:
05744:            private void checkNSCompat(int csIndex1, int derivedScope,
05745:                    int csIndex2) throws Exception {
05746:
05747:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05748:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05749:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05750:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05751:
05752:                // check Occurrence ranges
05753:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05754:                    throw new ParticleRecoverableError(
05755:                            "rcase-NSCompat.2:  Element occurrence range not a restriction of base any element's range");
05756:                }
05757:
05758:                fSchemaGrammar.getContentSpec(csIndex1, tempContentSpec1);
05759:                int uri = tempContentSpec1.otherValue;
05760:
05761:                // check wildcard subset
05762:                if (!wildcardEltAllowsNamespace(csIndex2, uri))
05763:                    throw new ParticleRecoverableError(
05764:                            "rcase-NSCompat.1:  Element's namespace not allowed by wildcard in base");
05765:
05766:            }
05767:
05768:            private boolean wildcardEltAllowsNamespace(int wildcardNode,
05769:                    int uriIndex) {
05770:
05771:                fSchemaGrammar.getContentSpec(wildcardNode, tempContentSpec1);
05772:                if ((tempContentSpec1.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY)
05773:                    return true;
05774:
05775:                if ((tempContentSpec1.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
05776:                    if (uriIndex == tempContentSpec1.otherValue)
05777:                        return true;
05778:                } else { // must be ANY_OTHER
05779:                    if (uriIndex != tempContentSpec1.otherValue
05780:                            && uriIndex != StringPool.EMPTY_STRING)
05781:                        return true;
05782:                }
05783:
05784:                return false;
05785:            }
05786:
05787:            private void checkNSSubset(int csIndex1, int csIndex2)
05788:                    throws Exception {
05789:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05790:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05791:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05792:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05793:
05794:                // check Occurrence ranges
05795:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05796:                    throw new ParticleRecoverableError(
05797:                            "rcase-NSSubset.2:  Wildcard's occurrence range not a restriction of base wildcard's range");
05798:                }
05799:
05800:                if (!wildcardEltSubset(csIndex1, csIndex2))
05801:                    throw new ParticleRecoverableError(
05802:                            "rcase-NSSubset.1:  Wildcard is not a subset of corresponding wildcard in base");
05803:
05804:            }
05805:
05806:            private boolean wildcardEltSubset(int wildcardNode,
05807:                    int wildcardBaseNode) {
05808:
05809:                fSchemaGrammar.getContentSpec(wildcardNode, tempContentSpec1);
05810:                fSchemaGrammar.getContentSpec(wildcardBaseNode,
05811:                        tempContentSpec2);
05812:
05813:                if ((tempContentSpec2.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY)
05814:                    return true;
05815:
05816:                if ((tempContentSpec1.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
05817:                    if ((tempContentSpec2.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER
05818:                            && tempContentSpec1.otherValue == tempContentSpec2.otherValue)
05819:                        return true;
05820:                }
05821:
05822:                if ((tempContentSpec1.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS) {
05823:                    if ((tempContentSpec2.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_NS
05824:                            && tempContentSpec1.otherValue == tempContentSpec2.otherValue)
05825:                        return true;
05826:
05827:                    if ((tempContentSpec2.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER
05828:                            && tempContentSpec1.otherValue != tempContentSpec2.otherValue)
05829:                        return true;
05830:
05831:                }
05832:
05833:                return false;
05834:            }
05835:
05836:            private void checkRecurseAsIfGroup(int csIndex1, int derivedScope,
05837:                    int csIndex2, Vector tempVector2, int baseScope,
05838:                    ComplexTypeInfo bInfo) throws Exception {
05839:
05840:                fSchemaGrammar.getContentSpec(csIndex2, tempContentSpec2);
05841:
05842:                //  Treat the element as if it were in a group of the same type as csindex2
05843:                int indexOfGrp = fSchemaGrammar.addContentSpecNode(
05844:                        tempContentSpec2.type, csIndex1, -2, false);
05845:                Vector tmpVector = new Vector();
05846:                tmpVector.addElement(new Integer(csIndex1));
05847:
05848:                if (tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_ALL
05849:                        || tempContentSpec2.type == XMLContentSpec.CONTENTSPECNODE_SEQ)
05850:                    checkRecurse(indexOfGrp, tmpVector, derivedScope, csIndex2,
05851:                            tempVector2, baseScope, bInfo);
05852:                else
05853:                    checkRecurseLax(indexOfGrp, tmpVector, derivedScope,
05854:                            csIndex2, tempVector2, baseScope, bInfo);
05855:
05856:                tmpVector = null;
05857:            }
05858:
05859:            private void checkNSRecurseCheckCardinality(int csIndex1,
05860:                    Vector tempVector1, int derivedScope, int csIndex2)
05861:                    throws Exception {
05862:
05863:                // Implement total range check
05864:                int min1 = minEffectiveTotalRange(csIndex1);
05865:                int max1 = maxEffectiveTotalRange(csIndex1);
05866:
05867:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05868:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05869:
05870:                // check Occurrence ranges
05871:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05872:                    throw new ParticleRecoverableError(
05873:                            "rcase-NSSubset.2:  Wildcard's occurrence range not a restriction of base wildcard's range");
05874:                }
05875:
05876:                if (!wildcardEltSubset(csIndex1, csIndex2))
05877:                    throw new ParticleRecoverableError(
05878:                            "rcase-NSSubset.1:  Wildcard is not a subset of corresponding wildcard in base");
05879:                // Check that each member of the group is a valid restriction of the wildcard
05880:                int count = tempVector1.size();
05881:                for (int i = 0; i < count; i++) {
05882:                    Integer particle1 = (Integer) tempVector1.elementAt(i);
05883:                    checkParticleDerivationOK(particle1.intValue(),
05884:                            derivedScope, csIndex2, -1, null);
05885:                }
05886:
05887:            }
05888:
05889:            private void checkRecurse(int csIndex1, Vector tempVector1,
05890:                    int derivedScope, int csIndex2, Vector tempVector2,
05891:                    int baseScope, ComplexTypeInfo bInfo) throws Exception {
05892:
05893:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05894:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05895:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05896:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05897:
05898:                // check Occurrence ranges
05899:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05900:                    throw new ParticleRecoverableError(
05901:                            "rcase-Recurse.1:  Occurrence range of group is not a valid restriction of occurence range of base group");
05902:                }
05903:
05904:                int count1 = tempVector1.size();
05905:                int count2 = tempVector2.size();
05906:
05907:                int current = 0;
05908:                label: for (int i = 0; i < count1; i++) {
05909:
05910:                    Integer particle1 = (Integer) tempVector1.elementAt(i);
05911:                    for (int j = current; j < count2; j++) {
05912:                        Integer particle2 = (Integer) tempVector2.elementAt(j);
05913:                        current += 1;
05914:                        try {
05915:                            checkParticleDerivationOK(particle1.intValue(),
05916:                                    derivedScope, particle2.intValue(),
05917:                                    baseScope, bInfo);
05918:                            continue label;
05919:                        } catch (ParticleRecoverableError e) {
05920:                            if (!particleEmptiable(particle2.intValue()))
05921:                                throw new ParticleRecoverableError(
05922:                                        "rcase-Recurse.2:  There is not a complete functional mapping between the particles");
05923:                        }
05924:                    }
05925:                    throw new ParticleRecoverableError(
05926:                            "rcase-Recurse.2:  There is not a complete functional mapping between the particles");
05927:                }
05928:
05929:                // Now, see if there are some elements in the base we didn't match up
05930:                for (int j = current; j < count2; j++) {
05931:                    Integer particle2 = (Integer) tempVector2.elementAt(j);
05932:                    if (!particleEmptiable(particle2.intValue())) {
05933:                        throw new ParticleRecoverableError(
05934:                                "rcase-Recurse.2:  There is not a complete functional mapping between the particles");
05935:                    }
05936:                }
05937:
05938:            }
05939:
05940:            private void checkRecurseUnordered(int csIndex1,
05941:                    Vector tempVector1, int derivedScope, int csIndex2,
05942:                    Vector tempVector2, int baseScope, ComplexTypeInfo bInfo)
05943:                    throws Exception {
05944:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05945:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05946:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05947:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05948:
05949:                // check Occurrence ranges
05950:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05951:                    throw new ParticleRecoverableError(
05952:                            "rcase-RecurseUnordered.1:  Occurrence range of group is not a valid restriction of occurence range of base group");
05953:                }
05954:
05955:                int count1 = tempVector1.size();
05956:                int count2 = tempVector2.size();
05957:
05958:                boolean foundIt[] = new boolean[count2];
05959:
05960:                label: for (int i = 0; i < count1; i++) {
05961:
05962:                    Integer particle1 = (Integer) tempVector1.elementAt(i);
05963:                    for (int j = 0; j < count2; j++) {
05964:                        Integer particle2 = (Integer) tempVector2.elementAt(j);
05965:                        try {
05966:                            checkParticleDerivationOK(particle1.intValue(),
05967:                                    derivedScope, particle2.intValue(),
05968:                                    baseScope, bInfo);
05969:                            if (foundIt[j])
05970:                                throw new ParticleRecoverableError(
05971:                                        "rcase-RecurseUnordered.2:  There is not a complete functional mapping between the particles");
05972:                            else
05973:                                foundIt[j] = true;
05974:
05975:                            continue label;
05976:                        } catch (ParticleRecoverableError e) {
05977:                        }
05978:                    }
05979:                    // didn't find a match.  Detect an error
05980:                    throw new ParticleRecoverableError(
05981:                            "rcase-RecurseUnordered.2:  There is not a complete functional mapping between the particles");
05982:                }
05983:
05984:            }
05985:
05986:            private void checkRecurseLax(int csIndex1, Vector tempVector1,
05987:                    int derivedScope, int csIndex2, Vector tempVector2,
05988:                    int baseScope, ComplexTypeInfo bInfo) throws Exception {
05989:
05990:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1);
05991:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
05992:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
05993:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
05994:
05995:                // check Occurrence ranges
05996:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
05997:                    throw new ParticleRecoverableError(
05998:                            "rcase-RecurseLax.1:  Occurrence range of group is not a valid restriction of occurence range of base group");
05999:                }
06000:
06001:                int count1 = tempVector1.size();
06002:                int count2 = tempVector2.size();
06003:
06004:                int current = 0;
06005:                label: for (int i = 0; i < count1; i++) {
06006:
06007:                    Integer particle1 = (Integer) tempVector1.elementAt(i);
06008:                    for (int j = current; j < count2; j++) {
06009:                        Integer particle2 = (Integer) tempVector2.elementAt(j);
06010:                        current += 1;
06011:                        try {
06012:                            checkParticleDerivationOK(particle1.intValue(),
06013:                                    derivedScope, particle2.intValue(),
06014:                                    baseScope, bInfo);
06015:                            continue label;
06016:                        } catch (ParticleRecoverableError e) {
06017:                        }
06018:                    }
06019:                    // didn't find a match.  Detect an error
06020:                    throw new ParticleRecoverableError(
06021:                            "rcase-Recurse.2:  There is not a complete functional mapping between the particles");
06022:
06023:                }
06024:
06025:            }
06026:
06027:            private void checkMapAndSum(int csIndex1, Vector tempVector1,
06028:                    int derivedScope, int csIndex2, Vector tempVector2,
06029:                    int baseScope, ComplexTypeInfo bInfo) throws Exception {
06030:
06031:                // See if the sequence group is a valid restriction of the choice
06032:
06033:                // Here is an example of a valid restriction:
06034:                //   <choice minOccurs="2">
06035:                //       <a/>
06036:                //       <b/>
06037:                //       <c/>
06038:                //   </choice>
06039:                //
06040:                //   <sequence>
06041:                //        <b/>
06042:                //        <a/>
06043:                //   </sequence>
06044:
06045:                // check the occurrence ranges
06046:                // Occurrence range for the sequence:
06047:                // min1 = (length of particles) * min of sequence
06048:                // max1 = (length of particles) * max of sequence  (or unbounded)
06049:                // min2 = minOccurs of choice
06050:                // max2 = maxOccurs of choice
06051:
06052:                int count1 = tempVector1.size();
06053:                int count2 = tempVector2.size();
06054:                int min1 = fSchemaGrammar.getContentSpecMinOccurs(csIndex1)
06055:                        * count1;
06056:                int max1 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex1);
06057:                if (max1 != SchemaSymbols.OCCURRENCE_UNBOUNDED)
06058:                    max1 = max1 * count1;
06059:                int min2 = fSchemaGrammar.getContentSpecMinOccurs(csIndex2);
06060:                int max2 = fSchemaGrammar.getContentSpecMaxOccurs(csIndex2);
06061:
06062:                // check Occurrence ranges
06063:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
06064:                    throw new ParticleRecoverableError(
06065:                            "rcase-MapAndSum.2:  Occurrence range of group is not a valid restriction of occurence range of base group");
06066:                }
06067:
06068:                label: for (int i = 0; i < count1; i++) {
06069:
06070:                    Integer particle1 = (Integer) tempVector1.elementAt(i);
06071:                    for (int j = 0; j < count2; j++) {
06072:                        Integer particle2 = (Integer) tempVector2.elementAt(j);
06073:                        try {
06074:                            checkParticleDerivationOK(particle1.intValue(),
06075:                                    derivedScope, particle2.intValue(),
06076:                                    baseScope, bInfo);
06077:
06078:                            continue label;
06079:                        } catch (ParticleRecoverableError e) {
06080:                        }
06081:                    }
06082:                    // didn't find a match.  Detect an error
06083:                    throw new ParticleRecoverableError(
06084:                            "rcase-MapAndSum.1:  There is not a complete functional mapping between the particles");
06085:                }
06086:            }
06087:
06088:            private int importContentSpec(SchemaGrammar aGrammar,
06089:                    int contentSpecHead) throws Exception {
06090:                XMLContentSpec ctsp = new XMLContentSpec();
06091:                aGrammar.getContentSpec(contentSpecHead, ctsp);
06092:                int left = -1;
06093:                int right = -1;
06094:                if (ctsp.type == ctsp.CONTENTSPECNODE_LEAF
06095:                        || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY
06096:                        || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY_NS
06097:                        || (ctsp.type & 0x0f) == ctsp.CONTENTSPECNODE_ANY_OTHER) {
06098:                    left = fSchemaGrammar.addContentSpecNode(ctsp.type,
06099:                            ctsp.value, ctsp.otherValue, false);
06100:                } else if (ctsp.type == -1)
06101:                    // case where type being extended has no content
06102:                    return -2;
06103:                else {
06104:                    if (ctsp.value == -1) {
06105:                        left = -1;
06106:                    } else {
06107:                        left = importContentSpec(aGrammar, ctsp.value);
06108:                    }
06109:
06110:                    if (ctsp.otherValue == -1) {
06111:                        right = -1;
06112:                    } else {
06113:                        right = importContentSpec(aGrammar, ctsp.otherValue);
06114:                    }
06115:                    left = fSchemaGrammar.addContentSpecNode(ctsp.type, left,
06116:                            right, false);
06117:                }
06118:
06119:                if (fFullConstraintChecking) {
06120:                    fSchemaGrammar.setContentSpecMaxOccurs(left, aGrammar
06121:                            .getContentSpecMaxOccurs(contentSpecHead));
06122:                    fSchemaGrammar.setContentSpecMinOccurs(left, aGrammar
06123:                            .getContentSpecMinOccurs(contentSpecHead));
06124:                }
06125:                return left;
06126:            }
06127:
06128:            private int handleOccurrences(int index, Element particle)
06129:                    throws Exception {
06130:                // Pass through, indicating we're not processing an <all>
06131:                return handleOccurrences(index, particle, NOT_ALL_CONTEXT);
06132:            }
06133:
06134:            // Checks constraints for minOccurs, maxOccurs and expands content model
06135:            // accordingly
06136:            private int handleOccurrences(int index, Element particle,
06137:                    int allContextFlags) throws Exception {
06138:
06139:                // if index is invalid, return
06140:                if (index < 0)
06141:                    return index;
06142:
06143:                String minOccurs = particle.getAttribute(
06144:                        SchemaSymbols.ATT_MINOCCURS).trim();
06145:                String maxOccurs = particle.getAttribute(
06146:                        SchemaSymbols.ATT_MAXOCCURS).trim();
06147:                boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0);
06148:                boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0);
06149:                boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0);
06150:                boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0);
06151:
06152:                // Neither minOccurs nor maxOccurs may be specified
06153:                // for the child of a model group definition.
06154:                if (isGroupChild
06155:                        && (minOccurs.length() != 0 || maxOccurs.length() != 0)) {
06156:                    Element group = (Element) particle.getParentNode();
06157:                    Object[] args = new Object[] {
06158:                            group.getAttribute(SchemaSymbols.ATT_NAME),
06159:                            particle.getNodeName() };
06160:                    reportSchemaError(SchemaMessageProvider.MinMaxOnGroupChild,
06161:                            args);
06162:                    minOccurs = (maxOccurs = "1");
06163:                }
06164:
06165:                // If minOccurs=maxOccurs=0, no component is specified
06166:                if (minOccurs.equals("0") && maxOccurs.equals("0")) {
06167:                    return -2;
06168:                }
06169:
06170:                int min = 1, max = 1;
06171:
06172:                if (minOccurs.length() == 0) {
06173:                    minOccurs = "1";
06174:                }
06175:                if (maxOccurs.length() == 0) {
06176:                    maxOccurs = "1";
06177:                }
06178:
06179:                // For the elements referenced in an <all>, minOccurs attribute
06180:                // must be zero or one, and maxOccurs attribute must be one.
06181:                // For a complex type definition that contains an <all> or a
06182:                // reference a <group> whose model group is an all model group,
06183:                // minOccurs and maxOccurs must be one.
06184:                if (processingAllEl || groupRefWithAll || processingAllGP) {
06185:                    if ((processingAllGP || groupRefWithAll || !minOccurs
06186:                            .equals("0"))
06187:                            && !minOccurs.equals("1")) {
06188:                        int minMsg;
06189:
06190:                        if (processingAllEl) {
06191:                            minMsg = SchemaMessageProvider.BadMinMaxForAllElem;
06192:                        } else if (processingAllGP) {
06193:                            minMsg = SchemaMessageProvider.BadMinMaxForAllGp;
06194:                        } else {
06195:                            minMsg = SchemaMessageProvider.BadMinMaxForGroupWithAll;
06196:                        }
06197:
06198:                        reportSchemaError(minMsg, new Object[] { "minOccurs",
06199:                                minOccurs });
06200:                        minOccurs = "1";
06201:                    }
06202:
06203:                    if (!maxOccurs.equals("1")) {
06204:                        int maxMsg;
06205:
06206:                        if (processingAllEl) {
06207:                            maxMsg = SchemaMessageProvider.BadMinMaxForAllElem;
06208:                        } else if (processingAllGP) {
06209:                            maxMsg = SchemaMessageProvider.BadMinMaxForAllGp;
06210:                        } else {
06211:                            maxMsg = SchemaMessageProvider.BadMinMaxForGroupWithAll;
06212:                        }
06213:
06214:                        reportSchemaError(maxMsg, new Object[] { "maxOccurs",
06215:                                maxOccurs });
06216:                        maxOccurs = "1";
06217:                    }
06218:                }
06219:
06220:                try {
06221:                    min = Integer.parseInt(minOccurs);
06222:                } catch (Exception e) {
06223:                    reportSchemaError(
06224:                            SchemaMessageProvider.GenericError,
06225:                            new Object[] { "illegal value for minOccurs or maxOccurs : '"
06226:                                    + e.getMessage() + "' " });
06227:                }
06228:
06229:                if (maxOccurs.equals("unbounded")) {
06230:                    max = SchemaSymbols.OCCURRENCE_UNBOUNDED;
06231:                } else {
06232:                    try {
06233:                        max = Integer.parseInt(maxOccurs);
06234:                    } catch (Exception e) {
06235:                        reportSchemaError(
06236:                                SchemaMessageProvider.GenericError,
06237:                                new Object[] { "illegal value for minOccurs or maxOccurs : '"
06238:                                        + e.getMessage() + "' " });
06239:                    }
06240:
06241:                    // Check that minOccurs isn't greater than maxOccurs.
06242:                    // p-props-correct 2.1
06243:                    if (min > max) {
06244:                        reportGenericSchemaError("p-props-correct:2.1 Value of minOccurs '"
06245:                                + minOccurs
06246:                                + "' must not be greater than value of maxOccurs '"
06247:                                + maxOccurs + "'");
06248:                    }
06249:
06250:                    if (max < 1) {
06251:                        reportGenericSchemaError("p-props-correct:2.2 Value of maxOccurs "
06252:                                + maxOccurs
06253:                                + " is invalid.  It must be greater than or equal to 1");
06254:                    }
06255:                }
06256:
06257:                if (fSchemaGrammar.getDeferContentSpecExpansion()) {
06258:                    fSchemaGrammar.setContentSpecMinOccurs(index, min);
06259:                    fSchemaGrammar.setContentSpecMaxOccurs(index, max);
06260:                    return index;
06261:                } else {
06262:                    return fSchemaGrammar.expandContentModel(index, min, max);
06263:                }
06264:
06265:            }
06266:
06267:            /**
06268:             * Traverses Schema attribute declaration.
06269:             *
06270:             *       <attribute
06271:             *         default = string
06272:             *         fixed = string
06273:             *         form = (qualified | unqualified)
06274:             *         id = ID
06275:             *         name = NCName
06276:             *         ref = QName
06277:             *         type = QName
06278:             *         use = (optional | prohibited | required) : optional
06279:             *         {any attributes with non-schema namespace ...}>
06280:             *         Content: (annotation? , simpleType?)
06281:             *       <attribute/>
06282:             *
06283:             * @param attributeDecl: the declaration of the attribute under consideration
06284:             * @param typeInfo: Contains the index of the element to which the attribute declaration is attached.
06285:             * @param referredTo:  true iff traverseAttributeDecl was called because
06286:             *		of encountering a ``ref''property (used
06287:             *		to suppress error-reporting).
06288:             * @return 0 if the attribute schema is validated successfully, otherwise -1
06289:             * @exception Exception
06290:             */
06291:            private int traverseAttributeDecl(Element attrDecl,
06292:                    ComplexTypeInfo typeInfo, boolean referredTo)
06293:                    throws Exception {
06294:
06295:                // General Attribute Checking
06296:                int scope = isTopLevel(attrDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
06297:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
06298:                Hashtable attrValues = generalCheck(attrDecl, scope);
06299:
06300:                ////// Get declared fields of the attribute
06301:                String defaultStr = attrDecl
06302:                        .getAttribute(SchemaSymbols.ATT_DEFAULT);
06303:                String fixedStr = attrDecl
06304:                        .getAttribute(SchemaSymbols.ATT_FIXED);
06305:                String formStr = attrDecl.getAttribute(SchemaSymbols.ATT_FORM);//form attribute
06306:                String attNameStr = attrDecl
06307:                        .getAttribute(SchemaSymbols.ATT_NAME);
06308:                String refStr = attrDecl.getAttribute(SchemaSymbols.ATT_REF);
06309:                String datatypeStr = attrDecl
06310:                        .getAttribute(SchemaSymbols.ATT_TYPE);
06311:                String useStr = attrDecl.getAttribute(SchemaSymbols.ATT_USE);
06312:                Element simpleTypeChild = findAttributeSimpleType(attrDecl);
06313:
06314:                Attr defaultAtt = attrDecl
06315:                        .getAttributeNode(SchemaSymbols.ATT_DEFAULT);
06316:                Attr fixedAtt = attrDecl
06317:                        .getAttributeNode(SchemaSymbols.ATT_FIXED);
06318:                Attr formAtt = attrDecl
06319:                        .getAttributeNode(SchemaSymbols.ATT_FORM);
06320:                Attr attNameAtt = attrDecl
06321:                        .getAttributeNode(SchemaSymbols.ATT_NAME);
06322:                Attr refAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_REF);
06323:                Attr datatypeAtt = attrDecl
06324:                        .getAttributeNode(SchemaSymbols.ATT_TYPE);
06325:                Attr useAtt = attrDecl.getAttributeNode(SchemaSymbols.ATT_USE);
06326:
06327:                checkEnumerationRequiredNotation(attNameStr, datatypeStr);
06328:
06329:                ////// define attribute declaration Schema components
06330:                int attName; // attribute name indexed in the string pool
06331:                int uriIndex; // indexed for target namespace uri
06332:                QName attQName; // QName combining attName and uriIndex
06333:
06334:                // attribute type
06335:                int attType;
06336:                boolean attIsList = false;
06337:                int dataTypeSymbol = -1;
06338:                String localpart = null;
06339:
06340:                // validator
06341:                DatatypeValidator dv;
06342:                boolean dvIsDerivedFromID = false;
06343:
06344:                // value constraints and use type
06345:                int attValueAndUseType = 0;
06346:                int attValueConstraint = -1; // indexed value in a string pool
06347:
06348:                ////// Check W3C's PR-Structure 3.2.3
06349:                // --- Constraints on XML Representations of Attribute Declarations
06350:                boolean isAttrTopLevel = isTopLevel(attrDecl);
06351:                boolean isOptional = false;
06352:                boolean isProhibited = false;
06353:                boolean isRequired = false;
06354:
06355:                StringBuffer errorContext = new StringBuffer(30);
06356:                errorContext.append(" -- ");
06357:                if (typeInfo == null) {
06358:                    errorContext.append("(global attribute) ");
06359:                } else if (typeInfo.typeName == null) {
06360:                    errorContext.append("(local attribute) ");
06361:                } else {
06362:                    errorContext.append("(attribute) ").append(
06363:                            typeInfo.typeName).append("/");
06364:                }
06365:                errorContext.append(attNameStr).append(' ').append(refStr);
06366:
06367:                if (useStr.length() == 0
06368:                        || useStr.equals(SchemaSymbols.ATTVAL_OPTIONAL)) {
06369:                    attValueAndUseType |= XMLAttributeDecl.USE_TYPE_OPTIONAL;
06370:                    isOptional = true;
06371:                } else if (useStr.equals(SchemaSymbols.ATTVAL_PROHIBITED)) {
06372:                    attValueAndUseType |= XMLAttributeDecl.USE_TYPE_PROHIBITED;
06373:                    isProhibited = true;
06374:                } else if (useStr.equals(SchemaSymbols.ATTVAL_REQUIRED)) {
06375:                    attValueAndUseType |= XMLAttributeDecl.USE_TYPE_REQUIRED;
06376:                    isRequired = true;
06377:                } else {
06378:                    reportGenericSchemaError("An attribute cannot declare \""
06379:                            + SchemaSymbols.ATT_USE + "\" as \"" + useStr
06380:                            + "\"" + errorContext);
06381:                }
06382:
06383:                if (defaultAtt != null && fixedAtt != null) {
06384:                    reportGenericSchemaError("src-attribute.1: \""
06385:                            + SchemaSymbols.ATT_DEFAULT + "\" and \""
06386:                            + SchemaSymbols.ATT_FIXED
06387:                            + "\" cannot be both present" + errorContext);
06388:                } else if (defaultAtt != null && !isOptional) {
06389:                    reportGenericSchemaError("src-attribute.2: If both \""
06390:                            + SchemaSymbols.ATT_DEFAULT + "\" and \""
06391:                            + SchemaSymbols.ATT_USE + "\" "
06392:                            + "are present for an attribute declaration, \""
06393:                            + SchemaSymbols.ATT_USE + "\" can only be \""
06394:                            + SchemaSymbols.ATTVAL_OPTIONAL + "\", not \""
06395:                            + useStr + "\"." + errorContext);
06396:                }
06397:
06398:                if (!isAttrTopLevel) {
06399:                    if ((refAtt == null) == (attNameAtt == null)) {
06400:                        reportGenericSchemaError("src-attribute.3.1: When the attribute's parent is not <schema> , one of \""
06401:                                + SchemaSymbols.ATT_REF
06402:                                + "\" and \""
06403:                                + SchemaSymbols.ATT_NAME
06404:                                + "\" should be declared, but not both."
06405:                                + errorContext);
06406:                        return -1;
06407:                    } else if ((refAtt != null)
06408:                            && (simpleTypeChild != null || formAtt != null || datatypeAtt != null)) {
06409:                        reportGenericSchemaError("src-attribute.3.2: When the attribute's parent is not <schema> and \""
06410:                                + SchemaSymbols.ATT_REF
06411:                                + "\" is present, "
06412:                                + "all of <"
06413:                                + SchemaSymbols.ELT_SIMPLETYPE
06414:                                + ">, "
06415:                                + SchemaSymbols.ATT_FORM
06416:                                + " and "
06417:                                + SchemaSymbols.ATT_TYPE
06418:                                + " must be absent."
06419:                                + errorContext);
06420:                    }
06421:                }
06422:
06423:                if (datatypeAtt != null && simpleTypeChild != null) {
06424:                    reportGenericSchemaError("src-attribute.4: \""
06425:                            + SchemaSymbols.ATT_TYPE + "\" and <"
06426:                            + SchemaSymbols.ELT_SIMPLETYPE
06427:                            + "> cannot both be present" + errorContext);
06428:                }
06429:
06430:                ////// Check W3C's PR-Structure 3.2.2
06431:                // --- XML Representation of Attribute Declaration Schema Components
06432:
06433:                // check case-dependent attribute declaration schema components
06434:                if (isAttrTopLevel) {
06435:                    //// global attributes
06436:                    // set name component
06437:                    attName = fStringPool.addSymbol(attNameStr);
06438:                    if (fTargetNSURIString.length() == 0) {
06439:                        uriIndex = StringPool.EMPTY_STRING;
06440:                    } else {
06441:                        uriIndex = fTargetNSURI;
06442:                    }
06443:
06444:                    // attQName = new QName(-1,attName,attName,uriIndex);
06445:                    // Above line replaced by following 2 to work around a JIT problem.
06446:                    attQName = new QName();
06447:                    attQName.setValues(-1, attName, attName, uriIndex);
06448:
06449:                } else if (refAtt == null) {
06450:                    //// local attributes
06451:                    // set name component
06452:                    attName = fStringPool.addSymbol(attNameStr);
06453:                    if ((formStr.length() > 0 && formStr
06454:                            .equals(SchemaSymbols.ATTVAL_QUALIFIED))
06455:                            || (formStr.length() == 0 && fAttributeDefaultQualified)) {
06456:                        uriIndex = fTargetNSURI;
06457:                    } else {
06458:                        uriIndex = StringPool.EMPTY_STRING;
06459:                    }
06460:                    // attQName = new QName(-1,attName,attName,uriIndex);
06461:                    // Above line replaced by following 2 to work around a JIT problem.
06462:                    attQName = new QName();
06463:                    attQName.setValues(-1, attName, attName, uriIndex);
06464:                } else {
06465:                    //// locally referenced global attributes
06466:                    String prefix;
06467:                    int colonptr = refStr.indexOf(":");
06468:                    if (colonptr > 0) {
06469:                        prefix = refStr.substring(0, colonptr);
06470:                        localpart = refStr.substring(colonptr + 1);
06471:                    } else {
06472:                        prefix = "";
06473:                        localpart = refStr;
06474:                    }
06475:
06476:                    String uriStr = resolvePrefixToURI(prefix);
06477:
06478:                    if (!uriStr.equals(fTargetNSURIString)) {
06479:                        addAttributeDeclFromAnotherSchema(localpart, uriStr,
06480:                                typeInfo, defaultAtt != null, fixedAtt != null,
06481:                                fixedStr, attValueAndUseType);
06482:                        return 0;
06483:                    }
06484:
06485:                    Element referredAttribute = getTopLevelComponentByName(
06486:                            SchemaSymbols.ELT_ATTRIBUTE, localpart);
06487:                    if (referredAttribute != null) {
06488:                        // don't need to traverse ref'd attribute if we're global; just make sure it's there...
06489:                        traverseAttributeDecl(referredAttribute, typeInfo, true);
06490:
06491:                        Attr referFixedAttr = referredAttribute
06492:                                .getAttributeNode(SchemaSymbols.ATT_FIXED);
06493:                        String referFixed = referFixedAttr == null ? null
06494:                                : referFixedAttr.getValue();
06495:                        if (referFixed != null
06496:                                && (defaultAtt != null || fixedAtt != null
06497:                                        && !referFixed.equals(fixedStr))) {
06498:                            reportGenericSchemaError("au-props-correct.2: If the {attribute declaration} has a fixed {value constraint}, then if the attribute use itself has a {value constraint}, it must also be fixed and its value must match that of the {attribute declaration}'s {value constraint}"
06499:                                    + errorContext);
06500:                        }
06501:
06502:                        // this nasty hack needed to ``override'' the
06503:                        // global attribute with "use" and "fixed" on the ref'ing attribute
06504:                        if ((typeInfo != null)
06505:                                && (!isOptional || fixedStr.length() > 0)) {
06506:                            int referredAttName = fStringPool
06507:                                    .addSymbol(referredAttribute
06508:                                            .getAttribute(SchemaSymbols.ATT_NAME));
06509:                            uriIndex = StringPool.EMPTY_STRING;
06510:                            if (fTargetNSURIString.length() > 0) {
06511:                                uriIndex = fTargetNSURI;
06512:                            }
06513:                            QName referredAttQName = new QName(-1,
06514:                                    referredAttName, referredAttName, uriIndex);
06515:
06516:                            int tempIndex = fSchemaGrammar
06517:                                    .getAttributeDeclIndex(
06518:                                            typeInfo.templateElementIndex,
06519:                                            referredAttQName);
06520:                            XMLAttributeDecl referredAttrDecl = new XMLAttributeDecl();
06521:                            fSchemaGrammar.getAttributeDecl(tempIndex,
06522:                                    referredAttrDecl);
06523:
06524:                            boolean updated = false;
06525:
06526:                            int useDigits = XMLAttributeDecl.USE_TYPE_OPTIONAL
06527:                                    | XMLAttributeDecl.USE_TYPE_PROHIBITED
06528:                                    | XMLAttributeDecl.USE_TYPE_REQUIRED;
06529:
06530:                            int valueDigits = XMLAttributeDecl.VALUE_CONSTRAINT_DEFAULT
06531:                                    | XMLAttributeDecl.VALUE_CONSTRAINT_FIXED;
06532:
06533:                            if (!isOptional
06534:                                    && (referredAttrDecl.defaultType & useDigits) != (attValueAndUseType & useDigits)) {
06535:                                if (referredAttrDecl.defaultType != XMLAttributeDecl.USE_TYPE_PROHIBITED) {
06536:                                    referredAttrDecl.defaultType |= useDigits;
06537:                                    referredAttrDecl.defaultType ^= useDigits; // clear the use
06538:                                    referredAttrDecl.defaultType |= (attValueAndUseType & useDigits);
06539:                                    updated = true;
06540:                                }
06541:                            }
06542:
06543:                            if (fixedStr.length() > 0) {
06544:                                if ((referredAttrDecl.defaultType & XMLAttributeDecl.VALUE_CONSTRAINT_FIXED) == 0) {
06545:                                    referredAttrDecl.defaultType |= valueDigits;
06546:                                    referredAttrDecl.defaultType ^= valueDigits; // clear the value
06547:                                    referredAttrDecl.defaultType |= XMLAttributeDecl.VALUE_CONSTRAINT_FIXED;
06548:                                    referredAttrDecl.defaultValue = fixedStr;
06549:                                    updated = true;
06550:                                }
06551:                            }
06552:
06553:                            if (updated) {
06554:                                fSchemaGrammar.setAttributeDecl(
06555:                                        typeInfo.templateElementIndex,
06556:                                        tempIndex, referredAttrDecl);
06557:                            }
06558:                        }
06559:                    } else if (fAttributeDeclRegistry.get(localpart) != null) {
06560:                        addAttributeDeclFromAnotherSchema(localpart, uriStr,
06561:                                typeInfo, defaultAtt != null, fixedAtt != null,
06562:                                fixedStr, attValueAndUseType);
06563:                    } else {
06564:                        // REVISIT: Localize
06565:                        reportGenericSchemaError("Couldn't find top level attribute "
06566:                                + refStr + errorContext);
06567:                    }
06568:                    return 0;
06569:                }
06570:
06571:                if (uriIndex == fXsiURI) {
06572:                    reportGenericSchemaError("no-xsi: The {target namespace} of an attribute declaration must not match "
06573:                            + SchemaSymbols.URI_XSI + errorContext);
06574:                }
06575:
06576:                // validation of attribute type is same for each case of declaration
06577:                if (simpleTypeChild != null) {
06578:                    attType = XMLAttributeDecl.TYPE_SIMPLE;
06579:                    dataTypeSymbol = traverseSimpleTypeDecl(simpleTypeChild);
06580:                    localpart = fStringPool.toString(dataTypeSymbol);
06581:                    dv = fDatatypeRegistry.getDatatypeValidator(localpart);
06582:                } else if (datatypeStr.length() != 0) {
06583:                    dataTypeSymbol = fStringPool.addSymbol(datatypeStr);
06584:                    String prefix;
06585:                    int colonptr = datatypeStr.indexOf(":");
06586:                    if (colonptr > 0) {
06587:                        prefix = datatypeStr.substring(0, colonptr);
06588:                        localpart = datatypeStr.substring(colonptr + 1);
06589:                    } else {
06590:                        prefix = "";
06591:                        localpart = datatypeStr;
06592:                    }
06593:                    String typeURI = resolvePrefixToURI(prefix);
06594:
06595:                    if (typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
06596:                        dv = getDatatypeValidator(
06597:                                SchemaSymbols.URI_SCHEMAFORSCHEMA, localpart);
06598:
06599:                        if (localpart.equals("ID")) {
06600:                            attType = XMLAttributeDecl.TYPE_ID;
06601:                        } else if (localpart.equals("IDREF")) {
06602:                            attType = XMLAttributeDecl.TYPE_IDREF;
06603:                        } else if (localpart.equals("IDREFS")) {
06604:                            attType = XMLAttributeDecl.TYPE_IDREF;
06605:                            attIsList = true;
06606:                        } else if (localpart.equals("ENTITY")) {
06607:                            attType = XMLAttributeDecl.TYPE_ENTITY;
06608:                        } else if (localpart.equals("ENTITIES")) {
06609:                            attType = XMLAttributeDecl.TYPE_ENTITY;
06610:                            attIsList = true;
06611:                        } else if (localpart.equals("NMTOKEN")) {
06612:                            attType = XMLAttributeDecl.TYPE_NMTOKEN;
06613:                        } else if (localpart.equals("NMTOKENS")) {
06614:                            attType = XMLAttributeDecl.TYPE_NMTOKEN;
06615:                            attIsList = true;
06616:                        } else if (localpart.equals(SchemaSymbols.ELT_NOTATION)) {
06617:                            attType = XMLAttributeDecl.TYPE_NOTATION;
06618:                        } else {
06619:                            attType = XMLAttributeDecl.TYPE_SIMPLE;
06620:                            if (dv == null && !referredTo) {
06621:                                // REVISIT:  localize
06622:                                reportGenericSchemaError("attribute "
06623:                                        + attNameStr
06624:                                        + " has a type ("
06625:                                        + datatypeStr
06626:                                        + ") which is not recognized as one of the predefined schema datatypes");
06627:                            }
06628:                        }
06629:                    } else { //isn't of the schema for schemas namespace...
06630:                        attType = XMLAttributeDecl.TYPE_SIMPLE;
06631:                        // check if the type is from the same Schema
06632:
06633:                        dv = getDatatypeValidator(typeURI, localpart);
06634:                        if (dv == null && typeURI.equals(fTargetNSURIString)) {
06635:                            Element topleveltype = getTopLevelComponentByName(
06636:                                    SchemaSymbols.ELT_SIMPLETYPE, localpart);
06637:                            if (topleveltype != null) {
06638:                                traverseSimpleTypeDecl(topleveltype);
06639:                                dv = getDatatypeValidator(typeURI, localpart);
06640:                            } else if (!referredTo) {
06641:                                // REVISIT: Localize
06642:                                reportGenericSchemaError("simpleType not found : "
06643:                                        + "("
06644:                                        + typeURI
06645:                                        + ":"
06646:                                        + localpart
06647:                                        + ")"
06648:                                        + errorContext);
06649:                            }
06650:                        }
06651:                        if (dv == null && !referredTo) {
06652:                            // REVISIT:  localize
06653:                            reportGenericSchemaError("attribute " + attNameStr
06654:                                    + " has an unrecognized type "
06655:                                    + datatypeStr);
06656:                        }
06657:                    }
06658:                } else {
06659:                    attType = XMLAttributeDecl.TYPE_SIMPLE;
06660:                    localpart = "string";
06661:                    dataTypeSymbol = fStringPool.addSymbol(localpart);
06662:                    dv = fDatatypeRegistry.getDatatypeValidator(localpart);
06663:                } // if(...Type)
06664:
06665:                // validation of data constraint is same for each case of declaration
06666:                if (defaultStr.length() > 0) {
06667:                    attValueAndUseType |= XMLAttributeDecl.VALUE_CONSTRAINT_DEFAULT;
06668:                    attValueConstraint = fStringPool.addString(defaultStr);
06669:                } else if (fixedStr.length() > 0) {
06670:                    attValueAndUseType |= XMLAttributeDecl.VALUE_CONSTRAINT_FIXED;
06671:                    attValueConstraint = fStringPool.addString(fixedStr);
06672:                }
06673:
06674:                ////// Check W3C's PR-Structure 3.2.6
06675:                // --- Constraints on Attribute Declaration Schema Components
06676:                // check default value is valid for the datatype.
06677:                if (attType == XMLAttributeDecl.TYPE_SIMPLE
06678:                        && attValueConstraint != -1) {
06679:                    try {
06680:                        if (dv != null) {
06681:                            if (defaultStr.length() > 0) {
06682:                                //REVISIT
06683:                                dv.validate(defaultStr, null);
06684:                            } else {
06685:                                dv.validate(fixedStr, null);
06686:                            }
06687:                        } else if (!referredTo)
06688:                            reportSchemaError(
06689:                                    SchemaMessageProvider.NoValidatorFor,
06690:                                    new Object[] { datatypeStr });
06691:                    } catch (InvalidDatatypeValueException idve) {
06692:                        if (!referredTo)
06693:                            reportSchemaError(
06694:                                    SchemaMessageProvider.IncorrectDefaultType,
06695:                                    new Object[] {
06696:                                            attrDecl
06697:                                                    .getAttribute(SchemaSymbols.ATT_NAME),
06698:                                            idve.getMessage() }); //a-props-correct.2
06699:                    }
06700:                }
06701:
06702:                // check the coexistence of ID and value constraint
06703:                dvIsDerivedFromID = ((dv != null) && dv instanceof  IDDatatypeValidator);
06704:                if (dvIsDerivedFromID && attValueConstraint != -1) {
06705:                    reportGenericSchemaError("a-props-correct.3: If type definition is or is derived from ID ,"
06706:                            + "there must not be a value constraint"
06707:                            + errorContext);
06708:                }
06709:
06710:                if (attNameStr.equals("xmlns")) {
06711:                    reportGenericSchemaError("no-xmlns: The {name} of an attribute declaration must not match 'xmlns'"
06712:                            + errorContext);
06713:                }
06714:
06715:                ////// every contraints were matched.  Now register the attribute declaration
06716:                //put the top-levels in the attribute decl registry.
06717:                if (isAttrTopLevel) {
06718:                    fTempAttributeDecl.datatypeValidator = dv;
06719:                    fTempAttributeDecl.name.setValues(attQName);
06720:                    fTempAttributeDecl.type = attType;
06721:                    fTempAttributeDecl.defaultType = attValueAndUseType;
06722:                    fTempAttributeDecl.list = attIsList;
06723:                    if (attValueConstraint != -1) {
06724:                        fTempAttributeDecl.defaultValue = fStringPool
06725:                                .toString(attValueConstraint);
06726:                    } else {
06727:                        fTempAttributeDecl.defaultValue = null;
06728:                    }
06729:                    fAttributeDeclRegistry.put(attNameStr,
06730:                            new XMLAttributeDecl(fTempAttributeDecl));
06731:                }
06732:
06733:                // add attribute to attr decl pool in fSchemaGrammar,
06734:                if (typeInfo != null) {
06735:
06736:                    // check that there aren't duplicate attributes
06737:                    int temp = fSchemaGrammar.getAttributeDeclIndex(
06738:                            typeInfo.templateElementIndex, attQName);
06739:                    if (temp > -1) {
06740:                        reportGenericSchemaError("ct-props-correct.4:  Duplicate attribute "
06741:                                + fStringPool.toString(attQName.rawname)
06742:                                + " in type definition");
06743:                    }
06744:
06745:                    // check that there aren't multiple attributes with type derived from ID
06746:                    if (dvIsDerivedFromID) {
06747:                        if (typeInfo.containsAttrTypeID()) {
06748:                            reportGenericSchemaError("ct-props-correct.5: More than one attribute derived from type ID cannot appear in the same complex type definition.");
06749:                        }
06750:                        typeInfo.setContainsAttrTypeID();
06751:                    }
06752:                    fSchemaGrammar.addAttDef(typeInfo.templateElementIndex,
06753:                            attQName, attType, dataTypeSymbol,
06754:                            attValueAndUseType, fStringPool
06755:                                    .toString(attValueConstraint), dv,
06756:                            attIsList);
06757:                }
06758:
06759:                return 0;
06760:            } // end of method traverseAttribute
06761:
06762:            private int addAttributeDeclFromAnotherSchema(String name,
06763:                    String uriStr, ComplexTypeInfo typeInfo) throws Exception {
06764:                Grammar grammar = fGrammarResolver.getGrammar(uriStr);
06765:                if (uriStr == null || !(grammar instanceof  SchemaGrammar)) {
06766:                    // REVISIT: Localize
06767:                    reportGenericSchemaError("no attribute named \"" + name
06768:                            + "\" was defined in schema : " + uriStr);
06769:                    return -1;
06770:                }
06771:                SchemaGrammar aGrammar = (SchemaGrammar) grammar;
06772:
06773:                Hashtable attrRegistry = aGrammar.getAttributeDeclRegistry();
06774:                if (attrRegistry == null) {
06775:                    // REVISIT: Localize
06776:                    reportGenericSchemaError("no attribute named \"" + name
06777:                            + "\" was defined in schema : " + uriStr);
06778:                    return -1;
06779:                }
06780:
06781:                XMLAttributeDecl referredAttrDecl = (XMLAttributeDecl) attrRegistry
06782:                        .get(name);
06783:
06784:                if (referredAttrDecl == null) {
06785:                    // REVISIT: Localize
06786:                    reportGenericSchemaError("no attribute named \"" + name
06787:                            + "\" was defined in schema : " + uriStr);
06788:                    return -1;
06789:                }
06790:
06791:                if (typeInfo != null) {
06792:
06793:                    // check that there aren't duplicate attributes
06794:                    int temp = fSchemaGrammar.getAttributeDeclIndex(
06795:                            typeInfo.templateElementIndex,
06796:                            referredAttrDecl.name);
06797:                    if (temp > -1) {
06798:                        reportGenericSchemaError("ct-props-correct.4:  Duplicate attribute "
06799:                                + fStringPool
06800:                                        .toString(referredAttrDecl.name.rawname)
06801:                                + " in type definition");
06802:                    }
06803:
06804:                    // check that there aren't multiple attributes with type derived from ID
06805:                    if (referredAttrDecl.datatypeValidator != null
06806:                            && referredAttrDecl.datatypeValidator instanceof  IDDatatypeValidator) {
06807:                        if (typeInfo.containsAttrTypeID()) {
06808:                            reportGenericSchemaError("ct-props-correct.5: More than one attribute derived from type ID cannot appear in the same complex type definition");
06809:                        }
06810:                        typeInfo.setContainsAttrTypeID();
06811:                    }
06812:
06813:                    fSchemaGrammar.addAttDef(typeInfo.templateElementIndex,
06814:                            referredAttrDecl.name, referredAttrDecl.type, -1,
06815:                            referredAttrDecl.defaultType,
06816:                            referredAttrDecl.defaultValue,
06817:                            referredAttrDecl.datatypeValidator,
06818:                            referredAttrDecl.list);
06819:                }
06820:
06821:                return 0;
06822:            }
06823:
06824:            private int addAttributeDeclFromAnotherSchema(String name,
06825:                    String uriStr, ComplexTypeInfo typeInfo,
06826:                    boolean hasDefault, boolean hasFixed, String fixedValue,
06827:                    int attValueAndUseType) throws Exception {
06828:                Grammar grammar = fGrammarResolver.getGrammar(uriStr);
06829:                if (uriStr == null || !(grammar instanceof  SchemaGrammar)) {
06830:                    // REVISIT: Localize
06831:                    reportGenericSchemaError("no attribute named \"" + name
06832:                            + "\" was defined in schema : " + uriStr);
06833:                    return -1;
06834:                }
06835:                SchemaGrammar aGrammar = (SchemaGrammar) grammar;
06836:
06837:                Hashtable attrRegistry = aGrammar.getAttributeDeclRegistry();
06838:                if (attrRegistry == null) {
06839:                    // REVISIT: Localize
06840:                    reportGenericSchemaError("no attribute named \"" + name
06841:                            + "\" was defined in schema : " + uriStr);
06842:                    return -1;
06843:                }
06844:
06845:                XMLAttributeDecl referredAttrDecl = (XMLAttributeDecl) attrRegistry
06846:                        .get(name);
06847:
06848:                if (referredAttrDecl == null) {
06849:                    // REVISIT: Localize
06850:                    reportGenericSchemaError("no attribute named \"" + name
06851:                            + "\" was defined in schema : " + uriStr);
06852:                    return -1;
06853:                }
06854:
06855:                referredAttrDecl = new XMLAttributeDecl(referredAttrDecl);
06856:
06857:                if (typeInfo != null) {
06858:
06859:                    // check that there aren't duplicate attributes
06860:                    int temp = fSchemaGrammar.getAttributeDeclIndex(
06861:                            typeInfo.templateElementIndex,
06862:                            referredAttrDecl.name);
06863:                    if (temp > -1) {
06864:                        reportGenericSchemaError("ct-props-correct.4:  Duplicate attribute "
06865:                                + fStringPool
06866:                                        .toString(referredAttrDecl.name.rawname)
06867:                                + " in type definition");
06868:                    }
06869:
06870:                    // check that there aren't multiple attributes with type derived from ID
06871:                    if (referredAttrDecl.datatypeValidator != null
06872:                            && referredAttrDecl.datatypeValidator instanceof  IDDatatypeValidator) {
06873:                        if (typeInfo.containsAttrTypeID()) {
06874:                            reportGenericSchemaError("ct-props-correct.5: More than one attribute derived from type ID cannot appear in the same complex type definition");
06875:                        }
06876:                        typeInfo.setContainsAttrTypeID();
06877:                    }
06878:
06879:                    /**
06880:                     * Copied (and modified) the following code from traverseAttributeDecl
06881:                     * because we also need to override "use" and "fixed" of the attribute
06882:                     * from another namespace. - sandyg
06883:                     */
06884:                    boolean isReferFixed = (referredAttrDecl.defaultType & XMLAttributeDecl.DEFAULT_TYPE_FIXED) != 0;
06885:                    String referFixed = isReferFixed ? null
06886:                            : referredAttrDecl.defaultValue;
06887:                    if (referFixed != null
06888:                            && (hasDefault || hasFixed
06889:                                    && !referFixed.equals(fixedValue))) {
06890:                        reportGenericSchemaError("au-props-correct.2: If the {attribute declaration} has a fixed {value constraint}, then if the attribute use itself has a {value constraint}, it must also be fixed and its value must match that of the {attribute declaration}'s {value constraint}");
06891:                    }
06892:
06893:                    // this nasty hack needed to ``override'' the
06894:                    // global attribute with "use" and "fixed" on the ref'ing attribute
06895:                    if ((attValueAndUseType & XMLAttributeDecl.USE_TYPE_OPTIONAL) == 0
06896:                            || fixedValue.length() > 0) {
06897:
06898:                        int useDigits = XMLAttributeDecl.USE_TYPE_OPTIONAL
06899:                                | XMLAttributeDecl.USE_TYPE_PROHIBITED
06900:                                | XMLAttributeDecl.USE_TYPE_REQUIRED;
06901:
06902:                        int valueDigits = XMLAttributeDecl.VALUE_CONSTRAINT_DEFAULT
06903:                                | XMLAttributeDecl.VALUE_CONSTRAINT_FIXED;
06904:
06905:                        if ((attValueAndUseType & XMLAttributeDecl.USE_TYPE_OPTIONAL) == 0
06906:                                && (referredAttrDecl.defaultType & useDigits) != (attValueAndUseType & useDigits)) {
06907:                            if (referredAttrDecl.defaultType != XMLAttributeDecl.USE_TYPE_PROHIBITED) {
06908:                                referredAttrDecl.defaultType |= useDigits;
06909:                                referredAttrDecl.defaultType ^= useDigits; // clear the use
06910:                                referredAttrDecl.defaultType |= (attValueAndUseType & useDigits);
06911:                            }
06912:                        }
06913:
06914:                        if (fixedValue.length() > 0) {
06915:                            if ((referredAttrDecl.defaultType & XMLAttributeDecl.VALUE_CONSTRAINT_FIXED) == 0) {
06916:                                referredAttrDecl.defaultType |= valueDigits;
06917:                                referredAttrDecl.defaultType ^= valueDigits; // clear the value
06918:                                referredAttrDecl.defaultType |= XMLAttributeDecl.VALUE_CONSTRAINT_FIXED;
06919:                                referredAttrDecl.defaultValue = fixedValue;
06920:                            }
06921:                        }
06922:                    }
06923:                    //***************************************
06924:
06925:                    fSchemaGrammar.addAttDef(typeInfo.templateElementIndex,
06926:                            referredAttrDecl.name, referredAttrDecl.type, -1,
06927:                            referredAttrDecl.defaultType,
06928:                            referredAttrDecl.defaultValue,
06929:                            referredAttrDecl.datatypeValidator,
06930:                            referredAttrDecl.list);
06931:                }
06932:
06933:                return 0;
06934:            }
06935:
06936:            /*
06937:             *
06938:             * <attributeGroup
06939:             *   id = ID
06940:             *   name = NCName
06941:             *   ref = QName>
06942:             *   Content: (annotation?, (attribute|attributeGroup)*, anyAttribute?)
06943:             * </>
06944:             *
06945:             */
06946:            private int traverseAttributeGroupDecl(Element attrGrpDecl,
06947:                    ComplexTypeInfo typeInfo, Vector anyAttDecls)
06948:                    throws Exception {
06949:                // General Attribute Checking
06950:                int scope = isTopLevel(attrGrpDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
06951:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
06952:                Hashtable attrValues = generalCheck(attrGrpDecl, scope);
06953:
06954:                // attributeGroup name
06955:                String attGrpNameStr = attrGrpDecl
06956:                        .getAttribute(SchemaSymbols.ATT_NAME);
06957:                int attGrpName = fStringPool.addSymbol(attGrpNameStr);
06958:
06959:                String ref = attrGrpDecl.getAttribute(SchemaSymbols.ATT_REF);
06960:                Element child = checkContent(attrGrpDecl, XUtil
06961:                        .getFirstChildElement(attrGrpDecl), true);
06962:
06963:                if (ref.length() != 0) {
06964:                    if (isTopLevel(attrGrpDecl))
06965:                        // REVISIT:  localize
06966:                        reportGenericSchemaError("An attributeGroup with \"ref\" present must not have <schema> or <redefine> as its parent");
06967:                    if (attGrpNameStr.length() != 0)
06968:                        // REVISIT:  localize
06969:                        reportGenericSchemaError("attributeGroup "
06970:                                + attGrpNameStr
06971:                                + " cannot refer to another attributeGroup, but it refers to "
06972:                                + ref);
06973:                    if (child != null)
06974:                        // REVISIT:  localize
06975:                        reportGenericSchemaError("An attributeGroup with \"ref\" present must be empty");
06976:
06977:                    String prefix = "";
06978:                    String localpart = ref;
06979:                    int colonptr = ref.indexOf(":");
06980:                    if (colonptr > 0) {
06981:                        prefix = ref.substring(0, colonptr);
06982:                        localpart = ref.substring(colonptr + 1);
06983:                    }
06984:                    String uriStr = resolvePrefixToURI(prefix);
06985:                    if (!uriStr.equals(fTargetNSURIString)) {
06986:
06987:                        traverseAttributeGroupDeclFromAnotherSchema(localpart,
06988:                                uriStr, typeInfo, anyAttDecls);
06989:
06990:                        return -1;
06991:                        // TO DO
06992:                        // REVISIT: different NS, not supported yet.
06993:                        // REVISIT: Localize
06994:                        //reportGenericSchemaError("Feature not supported: see an attribute from different NS");
06995:                    } else {
06996:                        Element parent = (Element) attrGrpDecl.getParentNode();
06997:                        //if (parent.getLocalName().equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) &&
06998:                        //    parent.getAttribute(SchemaSymbols.ATT_NAME).equals(localpart)) {
06999:                        // Check if we are in the middle of traversing this attribute group (i.e. circular references)
07000:                        // ??? the spec only mentioned direct circular ref
07001:                        if (fCurrentAttrGroupNameStack.search(localpart) > -1) {
07002:                            if (!((Element) parent.getParentNode())
07003:                                    .getLocalName().equals(
07004:                                            SchemaSymbols.ELT_REDEFINE)) {
07005:                                reportGenericSchemaError("src-attribute_group.3: Circular attribute group reference is disallowed outside <redefine> -- "
07006:                                        + ref);
07007:                            }
07008:                            return -1;
07009:                        }
07010:                    }
07011:
07012:                    if (typeInfo != null) {
07013:                        // only do this if we're traversing because we were ref'd here; when we come
07014:                        // upon this decl by itself we're just validating.
07015:                        Element referredAttrGrp = getTopLevelComponentByName(
07016:                                SchemaSymbols.ELT_ATTRIBUTEGROUP, localpart);
07017:                        if (referredAttrGrp != null) {
07018:                            traverseAttributeGroupDecl(referredAttrGrp,
07019:                                    typeInfo, anyAttDecls);
07020:                        } else {
07021:                            // REVISIT: Localize
07022:                            reportGenericSchemaError("Couldn't find top level attributeGroup "
07023:                                    + ref);
07024:                        }
07025:                        return -1;
07026:                    }
07027:                } else if (attGrpNameStr.length() == 0)
07028:                    // REVISIT:  localize
07029:                    reportGenericSchemaError("an attributeGroup must have a name or a ref attribute present");
07030:
07031:                fCurrentAttrGroupNameStack.push(attGrpNameStr);
07032:
07033:                for (; child != null; child = XUtil
07034:                        .getNextSiblingElement(child)) {
07035:
07036:                    if (child.getLocalName()
07037:                            .equals(SchemaSymbols.ELT_ATTRIBUTE)) {
07038:                        traverseAttributeDecl(child, typeInfo, false);
07039:                    } else if (child.getLocalName().equals(
07040:                            SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
07041:                        NamespacesScope currScope = (NamespacesScope) fNamespacesScope
07042:                                .clone();
07043:                        //	if(typeInfo != null)
07044:                        // only do this if we're traversing because we were ref'd here; when we come
07045:                        // upon this decl by itself we're just validating.
07046:                        traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
07047:                        fNamespacesScope = currScope;
07048:                    } else
07049:                        break;
07050:                }
07051:
07052:                fCurrentAttrGroupNameStack.pop();
07053:
07054:                if (child != null) {
07055:                    if (child.getLocalName().equals(
07056:                            SchemaSymbols.ELT_ANYATTRIBUTE)) {
07057:                        if (anyAttDecls != null) {
07058:                            anyAttDecls.addElement(traverseAnyAttribute(child));
07059:                        }
07060:                        if (XUtil.getNextSiblingElement(child) != null)
07061:                            // REVISIT:  localize
07062:                            reportGenericSchemaError("src-attribute_group.0: The content of an attributeGroup declaration must match (annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
07063:                        return -1;
07064:                    } else
07065:                        // REVISIT:  localize
07066:                        reportGenericSchemaError("src-attribute_group.0: The content of an attributeGroup declaration must match (annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
07067:                }
07068:                return -1;
07069:            } // end of method traverseAttributeGroup
07070:
07071:            private int traverseAttributeGroupDeclFromAnotherSchema(
07072:                    String attGrpName, String uriStr, ComplexTypeInfo typeInfo,
07073:                    Vector anyAttDecls) throws Exception {
07074:
07075:                Grammar grammar = fGrammarResolver.getGrammar(uriStr);
07076:                if (uriStr == null || grammar == null
07077:                        || !(grammar instanceof  SchemaGrammar)) {
07078:                    // REVISIT: Localize
07079:                    reportGenericSchemaError("!!Schema not found in #traverseAttributeGroupDeclFromAnotherSchema, schema uri : "
07080:                            + uriStr);
07081:                    return -1;
07082:                }
07083:                SchemaGrammar aGrammar = (SchemaGrammar) grammar;
07084:
07085:                // attribute name
07086:                Element attGrpDecl = (Element) aGrammar.topLevelAttrGrpDecls
07087:                        .get((Object) attGrpName);
07088:                if (attGrpDecl == null) {
07089:                    // REVISIT: Localize
07090:                    reportGenericSchemaError("no attribute group named \""
07091:                            + attGrpName + "\" was defined in schema : "
07092:                            + uriStr);
07093:                    return -1;
07094:                }
07095:
07096:                NamespacesScope saveNSMapping = fNamespacesScope;
07097:                int saveTargetNSUri = fTargetNSURI;
07098:                fTargetNSURI = fStringPool.addSymbol(aGrammar
07099:                        .getTargetNamespaceURI());
07100:                fNamespacesScope = aGrammar.getNamespacesScope();
07101:
07102:                // attribute type
07103:                int attType = -1;
07104:                int enumeration = -1;
07105:
07106:                Element child = checkContent(attGrpDecl, XUtil
07107:                        .getFirstChildElement(attGrpDecl), true);
07108:                for (; child != null; child = XUtil
07109:                        .getNextSiblingElement(child)) {
07110:
07111:                    //child attribute couldn't be a top-level attribute DEFINITION,
07112:                    if (child.getLocalName()
07113:                            .equals(SchemaSymbols.ELT_ATTRIBUTE)) {
07114:                        String childAttName = child
07115:                                .getAttribute(SchemaSymbols.ATT_NAME);
07116:                        if (childAttName.length() > 0) {
07117:                            Hashtable attDeclRegistry = aGrammar
07118:                                    .getAttributeDeclRegistry();
07119:                            if ((attDeclRegistry != null)
07120:                                    && (attDeclRegistry
07121:                                            .get((Object) childAttName) != null)) {
07122:                                addAttributeDeclFromAnotherSchema(childAttName,
07123:                                        uriStr, typeInfo);
07124:                                fNamespacesScope = saveNSMapping;
07125:                                fTargetNSURI = saveTargetNSUri;
07126:                                return -1;
07127:                            } else {
07128:                                traverseAttributeDecl(child, typeInfo, false);
07129:                            }
07130:                        } else
07131:                            traverseAttributeDecl(child, typeInfo, false);
07132:                    } else if (child.getLocalName().equals(
07133:                            SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
07134:                        traverseAttributeGroupDecl(child, typeInfo, anyAttDecls);
07135:                    } else if (child.getLocalName().equals(
07136:                            SchemaSymbols.ELT_ANYATTRIBUTE)) {
07137:                        anyAttDecls.addElement(traverseAnyAttribute(child));
07138:                        break;
07139:                    } else {
07140:                        // REVISIT: Localize
07141:                        reportGenericSchemaError("Invalid content for attributeGroup");
07142:                    }
07143:                }
07144:
07145:                fNamespacesScope = saveNSMapping;
07146:                fTargetNSURI = saveTargetNSUri;
07147:                if (child != null) {
07148:                    // REVISIT: Localize
07149:                    reportGenericSchemaError("Invalid content for attributeGroup");
07150:                }
07151:                return -1;
07152:            } // end of method traverseAttributeGroupFromAnotherSchema
07153:
07154:            // This simple method takes an attribute declaration as a parameter and
07155:            // returns null if there is no simpleType defined or the simpleType
07156:            // declaration if one exists.  It also throws an error if more than one
07157:            // <annotation> or <simpleType> group is present.
07158:            private Element findAttributeSimpleType(Element attrDecl)
07159:                    throws Exception {
07160:                Element child = checkContent(attrDecl, XUtil
07161:                        .getFirstChildElement(attrDecl), true);
07162:                // if there is only a annotatoin, then no simpleType
07163:                if (child == null)
07164:                    return null;
07165:                // if the current one is not simpleType, or there are more elements,
07166:                // report an error
07167:                if (!child.getLocalName().equals(SchemaSymbols.ELT_SIMPLETYPE)
07168:                        || XUtil.getNextSiblingElement(child) != null)
07169:                    //REVISIT: localize
07170:                    reportGenericSchemaError("src-attribute.0: the content must match (annotation?, (simpleType?)) -- attribute declaration '"
07171:                            + attrDecl.getAttribute(SchemaSymbols.ATT_NAME)
07172:                            + "'");
07173:                if (child.getLocalName().equals(SchemaSymbols.ELT_SIMPLETYPE))
07174:                    return child;
07175:                return null;
07176:            } // end findAttributeSimpleType
07177:
07178:            /**
07179:             * Traverse element declaration:
07180:             *  <element
07181:             *         abstract = boolean
07182:             *         block = #all or (possibly empty) subset of {substitutionGroup, extension, restriction}
07183:             *         default = string
07184:             *         substitutionGroup = QName
07185:             *         final = #all or (possibly empty) subset of {extension, restriction}
07186:             *         fixed = string
07187:             *         form = qualified | unqualified
07188:             *         id = ID
07189:             *         maxOccurs = string
07190:             *         minOccurs = nonNegativeInteger
07191:             *         name = NCName
07192:             *         nillable = boolean
07193:             *         ref = QName
07194:             *         type = QName>
07195:             *   Content: (annotation? , (simpleType | complexType)? , (unique | key | keyref)*)
07196:             *   </element>
07197:             *
07198:             *
07199:             *       The following are identity-constraint definitions
07200:             *        <unique
07201:             *         id = ID
07202:             *         name = NCName>
07203:             *         Content: (annotation? , (selector , field+))
07204:             *       </unique>
07205:             *
07206:             *       <key
07207:             *         id = ID
07208:             *         name = NCName>
07209:             *         Content: (annotation? , (selector , field+))
07210:             *       </key>
07211:             *
07212:             *       <keyref
07213:             *         id = ID
07214:             *         name = NCName
07215:             *         refer = QName>
07216:             *         Content: (annotation? , (selector , field+))
07217:             *       </keyref>
07218:             *
07219:             *       <selector>
07220:             *         Content: XPathExprApprox : An XPath expression
07221:             *       </selector>
07222:             *
07223:             *       <field>
07224:             *         Content: XPathExprApprox : An XPath expression
07225:             *       </field>
07226:             *
07227:             *
07228:             * @param elementDecl
07229:             * @return
07230:             * @exception Exception
07231:             */
07232:            private QName traverseElementDecl(Element elementDecl)
07233:                    throws Exception {
07234:
07235:                // General Attribute Checking
07236:                int scope = isTopLevel(elementDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
07237:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
07238:                Hashtable attrValues = generalCheck(elementDecl, scope);
07239:
07240:                int contentSpecType = -1;
07241:                int contentSpecNodeIndex = -1;
07242:                int typeNameIndex = -1;
07243:                int scopeDefined = -2; //signal a error if -2 gets gets through
07244:                //cause scope can never be -2.
07245:                DatatypeValidator dv = null;
07246:
07247:                String abstractStr = elementDecl
07248:                        .getAttribute(SchemaSymbols.ATT_ABSTRACT);
07249:                String blockStr = elementDecl
07250:                        .getAttribute(SchemaSymbols.ATT_BLOCK);
07251:                String defaultStr = elementDecl
07252:                        .getAttribute(SchemaSymbols.ATT_DEFAULT);
07253:                String finalStr = elementDecl
07254:                        .getAttribute(SchemaSymbols.ATT_FINAL);
07255:                String fixedStr = elementDecl
07256:                        .getAttribute(SchemaSymbols.ATT_FIXED);
07257:                String formStr = elementDecl
07258:                        .getAttribute(SchemaSymbols.ATT_FORM);
07259:                String maxOccursStr = elementDecl
07260:                        .getAttribute(SchemaSymbols.ATT_MAXOCCURS);
07261:                String minOccursStr = elementDecl
07262:                        .getAttribute(SchemaSymbols.ATT_MINOCCURS);
07263:                String nameStr = elementDecl
07264:                        .getAttribute(SchemaSymbols.ATT_NAME);
07265:                String nillableStr = elementDecl
07266:                        .getAttribute(SchemaSymbols.ATT_NILLABLE);
07267:                String refStr = elementDecl.getAttribute(SchemaSymbols.ATT_REF);
07268:                String substitutionGroupStr = elementDecl
07269:                        .getAttribute(SchemaSymbols.ATT_SUBSTITUTIONGROUP);
07270:                String typeStr = elementDecl
07271:                        .getAttribute(SchemaSymbols.ATT_TYPE);
07272:
07273:                checkEnumerationRequiredNotation(nameStr, typeStr);
07274:
07275:                if (DEBUGGING)
07276:                    System.out.println("traversing element decl : " + nameStr);
07277:
07278:                Attr abstractAtt = elementDecl
07279:                        .getAttributeNode(SchemaSymbols.ATT_ABSTRACT);
07280:                Attr blockAtt = elementDecl
07281:                        .getAttributeNode(SchemaSymbols.ATT_BLOCK);
07282:                Attr defaultAtt = elementDecl
07283:                        .getAttributeNode(SchemaSymbols.ATT_DEFAULT);
07284:                Attr finalAtt = elementDecl
07285:                        .getAttributeNode(SchemaSymbols.ATT_FINAL);
07286:                Attr fixedAtt = elementDecl
07287:                        .getAttributeNode(SchemaSymbols.ATT_FIXED);
07288:                Attr formAtt = elementDecl
07289:                        .getAttributeNode(SchemaSymbols.ATT_FORM);
07290:                Attr maxOccursAtt = elementDecl
07291:                        .getAttributeNode(SchemaSymbols.ATT_MAXOCCURS);
07292:                Attr minOccursAtt = elementDecl
07293:                        .getAttributeNode(SchemaSymbols.ATT_MINOCCURS);
07294:                Attr nameAtt = elementDecl
07295:                        .getAttributeNode(SchemaSymbols.ATT_NAME);
07296:                Attr nillableAtt = elementDecl
07297:                        .getAttributeNode(SchemaSymbols.ATT_NILLABLE);
07298:                Attr refAtt = elementDecl
07299:                        .getAttributeNode(SchemaSymbols.ATT_REF);
07300:                Attr substitutionGroupAtt = elementDecl
07301:                        .getAttributeNode(SchemaSymbols.ATT_SUBSTITUTIONGROUP);
07302:                Attr typeAtt = elementDecl
07303:                        .getAttributeNode(SchemaSymbols.ATT_TYPE);
07304:
07305:                if (defaultAtt != null && fixedAtt != null)
07306:                    // REVISIT:  localize
07307:                    reportGenericSchemaError("src-element.1: an element cannot have both \"fixed\" and \"default\" present at the same time");
07308:
07309:                String fromAnotherSchema = null;
07310:
07311:                if (isTopLevel(elementDecl)) {
07312:                    if (nameAtt == null)
07313:                        // REVISIT:  localize
07314:                        reportGenericSchemaError("globally-declared element must have a name");
07315:                    else if (refAtt != null)
07316:                        // REVISIT:  localize
07317:                        reportGenericSchemaError("globally-declared element "
07318:                                + nameStr + " cannot have a ref attribute");
07319:
07320:                    int nameIndex = fStringPool.addSymbol(nameStr);
07321:                    int eltKey = fSchemaGrammar.getElementDeclIndex(
07322:                            fTargetNSURI, nameIndex, TOP_LEVEL_SCOPE);
07323:                    if (eltKey > -1) {
07324:                        return new QName(-1, nameIndex, nameIndex, fTargetNSURI);
07325:                    }
07326:                }
07327:
07328:                // parse out 'block', 'final', 'nillable', 'abstract'
07329:                if (blockAtt == null)
07330:                    blockStr = null;
07331:                int blockSet = parseBlockSet(blockStr);
07332:                if ((blockStr != null)
07333:                        && blockStr.length() != 0
07334:                        && (!blockStr.equals(SchemaSymbols.ATTVAL_POUNDALL) && (((blockSet & SchemaSymbols.RESTRICTION) == 0) && (((blockSet & SchemaSymbols.EXTENSION) == 0) && ((blockSet & SchemaSymbols.SUBSTITUTION) == 0)))))
07335:                    reportGenericSchemaError("The values of the 'block' attribute of an element must be either #all or a list of 'substitution', 'restriction' and 'extension'; "
07336:                            + blockStr + " was found");
07337:                if (finalAtt == null)
07338:                    finalStr = null;
07339:                int finalSet = parseFinalSet(finalStr);
07340:                if ((finalStr != null)
07341:                        && finalStr.length() != 0
07342:                        && (!finalStr.equals(SchemaSymbols.ATTVAL_POUNDALL) && (((finalSet & SchemaSymbols.RESTRICTION) == 0) && ((finalSet & SchemaSymbols.EXTENSION) == 0))))
07343:                    reportGenericSchemaError("The values of the 'final' attribute of an element must be either #all or a list of 'restriction' and 'extension'; "
07344:                            + finalStr + " was found");
07345:                boolean isNillable = nillableStr
07346:                        .equals(SchemaSymbols.ATTVAL_TRUE)
07347:                        || nillableStr.equals(SchemaSymbols.ATTVAL_TRUE_1);
07348:                boolean isAbstract = abstractStr
07349:                        .equals(SchemaSymbols.ATTVAL_TRUE)
07350:                        || abstractStr.equals(SchemaSymbols.ATTVAL_TRUE_1);
07351:                int elementMiscFlags = 0;
07352:                if (isNillable) {
07353:                    elementMiscFlags += SchemaSymbols.NILLABLE;
07354:                }
07355:                if (isAbstract) {
07356:                    elementMiscFlags += SchemaSymbols.ABSTRACT;
07357:                }
07358:                // make the property of the element's value being fixed also appear in elementMiscFlags
07359:                if (fixedAtt != null)
07360:                    elementMiscFlags += SchemaSymbols.FIXED;
07361:
07362:                //if this is a reference to a global element
07363:                if (refAtt != null) {
07364:                    //REVISIT top level check for ref
07365:                    if (abstractAtt != null || blockAtt != null
07366:                            || defaultAtt != null || finalAtt != null
07367:                            || fixedAtt != null || formAtt != null
07368:                            || nillableAtt != null
07369:                            || substitutionGroupAtt != null || typeAtt != null)
07370:                        reportSchemaError(SchemaMessageProvider.BadAttWithRef,
07371:                                null); //src-element.2.2
07372:                    if (nameAtt != null)
07373:                        // REVISIT: Localize
07374:                        reportGenericSchemaError("src-element.2.1: element "
07375:                                + nameStr + " cannot also have a ref attribute");
07376:
07377:                    Element child = XUtil.getFirstChildElement(elementDecl);
07378:                    if (child != null
07379:                            && child.getLocalName().equals(
07380:                                    SchemaSymbols.ELT_ANNOTATION)) {
07381:                        if (XUtil.getNextSiblingElement(child) != null)
07382:                            reportSchemaError(
07383:                                    SchemaMessageProvider.NoContentForRef, null);
07384:                        else
07385:                            traverseAnnotationDecl(child);
07386:                    } else if (child != null)
07387:                        reportSchemaError(
07388:                                SchemaMessageProvider.NoContentForRef, null);
07389:                    String prefix = "";
07390:                    String localpart = refStr;
07391:                    int colonptr = refStr.indexOf(":");
07392:                    if (colonptr > 0) {
07393:                        prefix = refStr.substring(0, colonptr);
07394:                        localpart = refStr.substring(colonptr + 1);
07395:                    }
07396:                    int localpartIndex = fStringPool.addSymbol(localpart);
07397:                    String uriString = resolvePrefixToURI(prefix);
07398:                    QName eltName = new QName(prefix != null ? fStringPool
07399:                            .addSymbol(prefix) : -1, localpartIndex,
07400:                            fStringPool.addSymbol(refStr),
07401:                            uriString != null ? fStringPool
07402:                                    .addSymbol(uriString)
07403:                                    : StringPool.EMPTY_STRING);
07404:
07405:                    //if from another schema, just return the element QName
07406:                    if (!uriString.equals(fTargetNSURIString)) {
07407:                        return eltName;
07408:                    }
07409:
07410:                    int elementIndex = fSchemaGrammar.getElementDeclIndex(
07411:                            eltName, TOP_LEVEL_SCOPE);
07412:                    //if not found, traverse the top level element that if referenced
07413:
07414:                    if (elementIndex == -1) {
07415:                        Element targetElement = getTopLevelComponentByName(
07416:                                SchemaSymbols.ELT_ELEMENT, localpart);
07417:                        if (targetElement == null) {
07418:                            // REVISIT: Localize
07419:                            reportGenericSchemaError("Element " + localpart
07420:                                    + " not found in the Schema");
07421:                            //REVISIT, for now, the QName anyway
07422:                            return eltName;
07423:                            //return new QName(-1,fStringPool.addSymbol(localpart), -1, fStringPool.addSymbol(uriString));
07424:                        } else {
07425:                            // Problem with recursive decls if we attempt the traversal now.
07426:                            //eltName= traverseElementDecl(targetElement);
07427:
07428:                        }
07429:                    }
07430:
07431:                    if (fCurrentScope != TOP_LEVEL_SCOPE) {
07432:                        if (fFullConstraintChecking) {
07433:                            // Add the name to a list of top-level elements we'll need to check later
07434:                            // for consistency wrt type
07435:                            fTopLevelElementsRefdFromGroup.addElement(eltName);
07436:                            fTopLevelElementsRefdFromGroup
07437:                                    .addElement(new Integer(fCurrentScope));
07438:                        }
07439:
07440:                    }
07441:
07442:                    return eltName;
07443:                } else if (nameAtt == null)
07444:                    // REVISIT: Localize
07445:                    reportGenericSchemaError("src-element.2.1: a local element must have a name or a ref attribute present");
07446:
07447:                // Handle the substitutionGroup
07448:                Element substitutionGroupElementDecl = null;
07449:                int substitutionGroupElementDeclIndex = -1;
07450:                boolean noErrorSoFar = true;
07451:
07452:                //
07453:                // resolving the type for this element right here
07454:                //
07455:
07456:                ComplexTypeInfo typeInfo = null;
07457:
07458:                // element has a single child element, either a datatype or a type, null if primitive
07459:                Element child = XUtil.getFirstChildElement(elementDecl);
07460:
07461:                if (child != null
07462:                        && child.getLocalName().equals(
07463:                                SchemaSymbols.ELT_ANNOTATION)) {
07464:                    traverseAnnotationDecl(child);
07465:                    child = XUtil.getNextSiblingElement(child);
07466:                }
07467:                if (child != null
07468:                        && child.getLocalName().equals(
07469:                                SchemaSymbols.ELT_ANNOTATION))
07470:                    // REVISIT: Localize
07471:                    reportGenericSchemaError("element declarations can contain at most one annotation Element Information Item");
07472:
07473:                boolean haveAnonType = false;
07474:
07475:                // Handle Anonymous type if there is one
07476:                if (child != null) {
07477:
07478:                    String childName = child.getLocalName();
07479:
07480:                    if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) {
07481:                        if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
07482:                            noErrorSoFar = false;
07483:                            // REVISIT: Localize
07484:                            reportGenericSchemaError("anonymous complexType in element '"
07485:                                    + nameStr + "' has a name attribute");
07486:                        }
07487:
07488:                        else {
07489:                            // Determine what the type name will be
07490:                            String anonTypeName = genAnonTypeName(child);
07491:                            if (fCurrentTypeNameStack
07492:                                    .search((Object) anonTypeName) > -1) {
07493:                                // A recursing element using an anonymous type
07494:
07495:                                int uriInd = StringPool.EMPTY_STRING;
07496:                                if (formStr
07497:                                        .equals(SchemaSymbols.ATTVAL_QUALIFIED)
07498:                                        || fElementDefaultQualified) {
07499:                                    uriInd = fTargetNSURI;
07500:                                }
07501:                                int nameIndex = fStringPool.addSymbol(nameStr);
07502:                                QName tempQName = new QName(-1, nameIndex,
07503:                                        nameIndex, uriInd);
07504:                                int eltIndex = fSchemaGrammar.addElementDecl(
07505:                                        tempQName, fCurrentScope,
07506:                                        fCurrentScope, -1, -1, -1, null);
07507:                                fElementRecurseComplex
07508:                                        .addElement(new ElementInfo(eltIndex,
07509:                                                anonTypeName));
07510:                                return tempQName;
07511:
07512:                            } else {
07513:                                typeNameIndex = traverseComplexTypeDecl(child);
07514:                                if (typeNameIndex != -1) {
07515:                                    typeInfo = (ComplexTypeInfo) fComplexTypeRegistry
07516:                                            .get(fStringPool
07517:                                                    .toString(typeNameIndex));
07518:                                } else {
07519:                                    noErrorSoFar = false;
07520:                                    // REVISIT: Localize
07521:                                    reportGenericSchemaError("traverse complexType error in element '"
07522:                                            + nameStr + "'");
07523:                                }
07524:                            }
07525:                        }
07526:
07527:                        haveAnonType = true;
07528:                        child = XUtil.getNextSiblingElement(child);
07529:                    } else if (childName.equals(SchemaSymbols.ELT_SIMPLETYPE)) {
07530:                        if (child.getAttribute(SchemaSymbols.ATT_NAME).length() > 0) {
07531:                            noErrorSoFar = false;
07532:                            // REVISIT: Localize
07533:                            reportGenericSchemaError("anonymous simpleType in element '"
07534:                                    + nameStr + "' has a name attribute");
07535:                        } else
07536:                            typeNameIndex = traverseSimpleTypeDecl(child);
07537:                        if (typeNameIndex != -1) {
07538:                            dv = fDatatypeRegistry
07539:                                    .getDatatypeValidator(fStringPool
07540:                                            .toString(typeNameIndex));
07541:                        } else {
07542:                            noErrorSoFar = false;
07543:                            // REVISIT: Localize
07544:                            reportGenericSchemaError("traverse simpleType error in element '"
07545:                                    + nameStr + "'");
07546:                        }
07547:                        contentSpecType = XMLElementDecl.TYPE_SIMPLE;
07548:                        haveAnonType = true;
07549:                        child = XUtil.getNextSiblingElement(child);
07550:                    } else if (typeAtt == null) { // "ur-typed" leaf
07551:                        contentSpecType = XMLElementDecl.TYPE_ANY;
07552:                        //REVISIT: is this right?
07553:                        //contentSpecType = fStringPool.addSymbol("UR_TYPE");
07554:                        // set occurrence count
07555:                        contentSpecNodeIndex = -1;
07556:                    }
07557:                    // see if there's something here; it had better be key, keyref or unique.
07558:                    if (child != null)
07559:                        childName = child.getLocalName();
07560:                    while ((child != null)
07561:                            && ((childName.equals(SchemaSymbols.ELT_KEY))
07562:                                    || (childName
07563:                                            .equals(SchemaSymbols.ELT_KEYREF)) || (childName
07564:                                    .equals(SchemaSymbols.ELT_UNIQUE)))) {
07565:                        child = XUtil.getNextSiblingElement(child);
07566:                        if (child != null) {
07567:                            childName = child.getLocalName();
07568:                        }
07569:                    }
07570:                    if (child != null) {
07571:                        // REVISIT: Localize
07572:                        noErrorSoFar = false;
07573:                        reportGenericSchemaError("src-element.0: the content of an element information item must match (annotation?, (simpleType | complexType)?, (unique | key | keyref)*)");
07574:                    }
07575:                }
07576:
07577:                // handle type="" here
07578:                if (haveAnonType && (typeAtt != null)) {
07579:                    noErrorSoFar = false;
07580:                    // REVISIT: Localize
07581:                    reportGenericSchemaError("src-element.3: Element '"
07582:                            + nameStr
07583:                            + "' have both a type attribute and a annoymous type child");
07584:                }
07585:                // type specified as an attribute and no child is type decl.
07586:                else if (typeAtt != null) {
07587:                    String prefix = "";
07588:                    String localpart = typeStr;
07589:                    int colonptr = typeStr.indexOf(":");
07590:                    if (colonptr > 0) {
07591:                        prefix = typeStr.substring(0, colonptr);
07592:                        localpart = typeStr.substring(colonptr + 1);
07593:                    }
07594:                    String typeURI = resolvePrefixToURI(prefix);
07595:
07596:                    if (!(typeURI.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) && localpart
07597:                            .equals("anyType"))) {
07598:                        // check if the type is from the same Schema
07599:                        if (!typeURI.equals(fTargetNSURIString)
07600:                                && !typeURI
07601:                                        .equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
07602:                            fromAnotherSchema = typeURI;
07603:                            typeInfo = getTypeInfoFromNS(typeURI, localpart);
07604:                            if (typeInfo == null) {
07605:                                dv = getTypeValidatorFromNS(typeURI, localpart);
07606:                                if (dv == null) {
07607:                                    //TO DO: report error here;
07608:                                    noErrorSoFar = false;
07609:                                    reportGenericSchemaError("Could not find type "
07610:                                            + localpart
07611:                                            + " in schema "
07612:                                            + typeURI);
07613:                                }
07614:                            }
07615:                        } else {
07616:                            typeInfo = (ComplexTypeInfo) fComplexTypeRegistry
07617:                                    .get(typeURI + "," + localpart);
07618:                            if (typeInfo == null) {
07619:                                dv = getDatatypeValidator(typeURI, localpart);
07620:                                if (dv == null)
07621:                                    if (typeURI
07622:                                            .equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
07623:                                            && !fTargetNSURIString
07624:                                                    .equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
07625:                                        noErrorSoFar = false;
07626:                                        // REVISIT: Localize
07627:                                        reportGenericSchemaError("type not found : "
07628:                                                + typeURI + ":" + localpart);
07629:                                    } else {
07630:                                        Element topleveltype = getTopLevelComponentByName(
07631:                                                SchemaSymbols.ELT_COMPLEXTYPE,
07632:                                                localpart);
07633:                                        if (topleveltype != null) {
07634:                                            if (fCurrentTypeNameStack
07635:                                                    .search((Object) localpart) > -1) {
07636:                                                //then we found a recursive element using complexType.
07637:                                                // REVISIT: this will be broken when recursing happens between 2 schemas
07638:                                                int uriInd = StringPool.EMPTY_STRING;
07639:                                                if (formStr
07640:                                                        .equals(SchemaSymbols.ATTVAL_QUALIFIED)
07641:                                                        || fElementDefaultQualified) {
07642:                                                    uriInd = fTargetNSURI;
07643:                                                }
07644:                                                int nameIndex = fStringPool
07645:                                                        .addSymbol(nameStr);
07646:                                                QName tempQName = new QName(-1,
07647:                                                        nameIndex, nameIndex,
07648:                                                        uriInd);
07649:                                                int eltIndex = fSchemaGrammar
07650:                                                        .addElementDecl(
07651:                                                                tempQName,
07652:                                                                fCurrentScope,
07653:                                                                fCurrentScope,
07654:                                                                -1, -1, -1,
07655:                                                                null);
07656:                                                fElementRecurseComplex
07657:                                                        .addElement(new ElementInfo(
07658:                                                                eltIndex,
07659:                                                                localpart));
07660:                                                return tempQName;
07661:                                            } else {
07662:                                                // Squirrel away the baseTypeNameStack.
07663:                                                Stack savedbaseNameStack = null;
07664:                                                if (!fBaseTypeNameStack
07665:                                                        .isEmpty()) {
07666:                                                    savedbaseNameStack = fBaseTypeNameStack;
07667:                                                    fBaseTypeNameStack = new Stack();
07668:                                                }
07669:                                                typeNameIndex = traverseComplexTypeDecl(
07670:                                                        topleveltype, true);
07671:                                                if (savedbaseNameStack != null)
07672:                                                    fBaseTypeNameStack = savedbaseNameStack;
07673:                                                typeInfo = (ComplexTypeInfo) fComplexTypeRegistry
07674:                                                        .get(fStringPool
07675:                                                                .toString(typeNameIndex));
07676:                                            }
07677:                                        } else {
07678:                                            topleveltype = getTopLevelComponentByName(
07679:                                                    SchemaSymbols.ELT_SIMPLETYPE,
07680:                                                    localpart);
07681:                                            if (topleveltype != null) {
07682:                                                typeNameIndex = traverseSimpleTypeDecl(topleveltype);
07683:                                                dv = getDatatypeValidator(
07684:                                                        typeURI, localpart);
07685:                                            } else {
07686:                                                noErrorSoFar = false;
07687:                                                // REVISIT: Localize
07688:                                                reportGenericSchemaError("type not found : "
07689:                                                        + typeURI
07690:                                                        + ":"
07691:                                                        + localpart);
07692:                                            }
07693:
07694:                                        }
07695:
07696:                                    }
07697:                            }
07698:                        }
07699:                    }
07700:                }
07701:                // now we need to make sure that our substitution (if any)
07702:                // is valid, now that we have all the requisite type-related info.
07703:                String substitutionGroupUri = null;
07704:                String substitutionGroupLocalpart = null;
07705:                String substitutionGroupFullName = null;
07706:                ComplexTypeInfo substitutionGroupEltTypeInfo = null;
07707:                DatatypeValidator substitutionGroupEltDV = null;
07708:                SchemaGrammar subGrammar = fSchemaGrammar;
07709:                boolean ignoreSub = false;
07710:
07711:                if (substitutionGroupStr.length() > 0) {
07712:                    if (refAtt != null)
07713:                        // REVISIT: Localize
07714:                        reportGenericSchemaError("a local element cannot have a substitutionGroup");
07715:                    substitutionGroupUri = resolvePrefixToURI(getPrefix(substitutionGroupStr));
07716:                    substitutionGroupLocalpart = getLocalPart(substitutionGroupStr);
07717:                    substitutionGroupFullName = substitutionGroupUri + ","
07718:                            + substitutionGroupLocalpart;
07719:
07720:                    if (!substitutionGroupUri.equals(fTargetNSURIString)) {
07721:                        Grammar grammar = fGrammarResolver
07722:                                .getGrammar(substitutionGroupUri);
07723:                        if (grammar != null && grammar instanceof  SchemaGrammar) {
07724:                            subGrammar = (SchemaGrammar) grammar;
07725:                            substitutionGroupElementDeclIndex = subGrammar
07726:                                    .getElementDeclIndex(
07727:                                            fStringPool
07728:                                                    .addSymbol(substitutionGroupUri),
07729:                                            fStringPool
07730:                                                    .addSymbol(substitutionGroupLocalpart),
07731:                                            TOP_LEVEL_SCOPE);
07732:                            if (substitutionGroupElementDeclIndex <= -1) {
07733:                                // REVISIT:  localize
07734:                                noErrorSoFar = false;
07735:                                reportGenericSchemaError("couldn't find substitutionGroup "
07736:                                        + substitutionGroupLocalpart
07737:                                        + " referenced by element "
07738:                                        + nameStr
07739:                                        + " in the SchemaGrammar "
07740:                                        + substitutionGroupUri);
07741:
07742:                            } else {
07743:                                substitutionGroupEltTypeInfo = getElementDeclTypeInfoFromNS(
07744:                                        substitutionGroupUri,
07745:                                        substitutionGroupLocalpart);
07746:                                if (substitutionGroupEltTypeInfo == null) {
07747:                                    substitutionGroupEltDV = getElementDeclTypeValidatorFromNS(
07748:                                            substitutionGroupUri,
07749:                                            substitutionGroupLocalpart);
07750:                                    /*if (substitutionGroupEltDV == null) {
07751:                                        //TO DO: report error here;
07752:                                        noErrorSoFar = false;
07753:                                        reportGenericSchemaError("Could not find type for element '" +substitutionGroupLocalpart
07754:                                                         + "' in schema '" + substitutionGroupUri+"'");
07755:                                    }*/
07756:                                }
07757:                            }
07758:                        } else {
07759:                            // REVISIT:  locallize
07760:                            noErrorSoFar = false;
07761:                            reportGenericSchemaError("couldn't find a schema grammar with target namespace '"
07762:                                    + substitutionGroupUri
07763:                                    + "' for element '"
07764:                                    + substitutionGroupStr + "'");
07765:                        }
07766:                    } else {
07767:                        substitutionGroupElementDecl = getTopLevelComponentByName(
07768:                                SchemaSymbols.ELT_ELEMENT,
07769:                                substitutionGroupLocalpart);
07770:                        if (substitutionGroupElementDecl == null) {
07771:                            substitutionGroupElementDeclIndex = fSchemaGrammar
07772:                                    .getElementDeclIndex(
07773:                                            fTargetNSURI,
07774:                                            getLocalPartIndex(substitutionGroupStr),
07775:                                            TOP_LEVEL_SCOPE);
07776:                            if (substitutionGroupElementDeclIndex == -1) {
07777:                                noErrorSoFar = false;
07778:                                // REVISIT: Localize
07779:                                reportGenericSchemaError("unable to locate substitutionGroup affiliation element "
07780:                                        + substitutionGroupStr
07781:                                        + " in element declaration " + nameStr);
07782:                            }
07783:                        } else {
07784:                            substitutionGroupElementDeclIndex = fSchemaGrammar
07785:                                    .getElementDeclIndex(
07786:                                            fTargetNSURI,
07787:                                            getLocalPartIndex(substitutionGroupStr),
07788:                                            TOP_LEVEL_SCOPE);
07789:
07790:                            if (substitutionGroupElementDeclIndex == -1) {
07791:                                // check for mutual recursion!
07792:                                if (fSubstitutionGroupRecursionRegistry
07793:                                        .contains(fTargetNSURIString
07794:                                                + ","
07795:                                                + substitutionGroupElementDecl
07796:                                                        .getAttribute(SchemaSymbols.ATT_NAME))) {
07797:                                    ignoreSub = true;
07798:                                } else {
07799:                                    fSubstitutionGroupRecursionRegistry
07800:                                            .addElement(fTargetNSURIString
07801:                                                    + ","
07802:                                                    + substitutionGroupElementDecl
07803:                                                            .getAttribute(SchemaSymbols.ATT_NAME));
07804:                                    traverseElementDecl(substitutionGroupElementDecl);
07805:                                    substitutionGroupElementDeclIndex = fSchemaGrammar
07806:                                            .getElementDeclIndex(
07807:                                                    fTargetNSURI,
07808:                                                    getLocalPartIndex(substitutionGroupStr),
07809:                                                    TOP_LEVEL_SCOPE);
07810:                                    fSubstitutionGroupRecursionRegistry
07811:                                            .removeElement((Object) fTargetNSURIString
07812:                                                    + ","
07813:                                                    + substitutionGroupElementDecl
07814:                                                            .getAttribute(SchemaSymbols.ATT_NAME));
07815:                                }
07816:                            }
07817:                        }
07818:
07819:                        if (!ignoreSub
07820:                                && substitutionGroupElementDeclIndex != -1) {
07821:                            substitutionGroupEltTypeInfo = fSchemaGrammar
07822:                                    .getElementComplexTypeInfo(substitutionGroupElementDeclIndex);
07823:                            if (substitutionGroupEltTypeInfo == null) {
07824:                                fSchemaGrammar.getElementDecl(
07825:                                        substitutionGroupElementDeclIndex,
07826:                                        fTempElementDecl);
07827:                                substitutionGroupEltDV = fTempElementDecl.datatypeValidator;
07828:                                /*if (substitutionGroupEltDV == null) {
07829:                                    //TO DO: report error here;
07830:                                    noErrorSoFar = false;
07831:                                    reportGenericSchemaError("Could not find type for element '" +substitutionGroupLocalpart
07832:                                                             + "' in schema '" + substitutionGroupUri+"'");
07833:                                }*/
07834:                            }
07835:                        }
07836:                    }
07837:                    if (substitutionGroupElementDeclIndex <= -1)
07838:                        ignoreSub = true;
07839:                    if (!ignoreSub)
07840:                        checkSubstitutionGroupOK(elementDecl,
07841:                                substitutionGroupElementDecl, noErrorSoFar,
07842:                                substitutionGroupElementDeclIndex, subGrammar,
07843:                                typeInfo, substitutionGroupEltTypeInfo, dv,
07844:                                substitutionGroupEltDV);
07845:                }
07846:
07847:                // this element is ur-type, check its substitutionGroup affiliation.
07848:                // if there is substitutionGroup affiliation and not type definition found for this element,
07849:                // then grab substitutionGroup affiliation's type and give it to this element
07850:                if (noErrorSoFar && typeInfo == null && dv == null) {
07851:                    typeInfo = substitutionGroupEltTypeInfo;
07852:                    dv = substitutionGroupEltDV;
07853:                }
07854:
07855:                boolean isAnyType = false;
07856:                if (typeInfo == null && dv == null) {
07857:                    if (noErrorSoFar) {
07858:                        // Actually this Element's type definition is ur-type;
07859:                        isAnyType = true;
07860:                        contentSpecType = XMLElementDecl.TYPE_ANY;
07861:                    } else {
07862:                        noErrorSoFar = false;
07863:                        // REVISIT: Localize
07864:                        reportGenericSchemaError("untyped element : " + nameStr);
07865:                    }
07866:                }
07867:
07868:                // if element belongs to a compelx type
07869:                if (typeInfo != null) {
07870:                    contentSpecNodeIndex = typeInfo.contentSpecHandle;
07871:                    contentSpecType = typeInfo.contentType;
07872:                    scopeDefined = typeInfo.scopeDefined;
07873:                    dv = typeInfo.datatypeValidator;
07874:                }
07875:
07876:                // if element belongs to a simple type
07877:                if (dv != null) {
07878:                    contentSpecType = XMLElementDecl.TYPE_SIMPLE;
07879:                    if (typeInfo == null) {
07880:                        fromAnotherSchema = null; // not to switch schema in this case
07881:                    }
07882:                }
07883:
07884:                // Now we can handle validation etc. of default and fixed attributes,
07885:                // since we finally have all the type information.
07886:                if (fixedAtt != null)
07887:                    defaultStr = fixedStr;
07888:                if (defaultStr.length() != 0) {
07889:                    if (typeInfo != null
07890:                            && (typeInfo.contentType != XMLElementDecl.TYPE_MIXED_SIMPLE
07891:                                    && typeInfo.contentType != XMLElementDecl.TYPE_MIXED_COMPLEX && typeInfo.contentType != XMLElementDecl.TYPE_SIMPLE)) {
07892:                        // REVISIT: Localize
07893:                        reportGenericSchemaError("e-props-correct.2.1: element "
07894:                                + nameStr
07895:                                + " has a fixed or default value and must have a mixed or simple content model");
07896:                    }
07897:                    if (typeInfo != null
07898:                            && (typeInfo.contentType == XMLElementDecl.TYPE_MIXED_SIMPLE || typeInfo.contentType == XMLElementDecl.TYPE_MIXED_COMPLEX)) {
07899:                        if (!particleEmptiable(typeInfo.contentSpecHandle))
07900:                            reportGenericSchemaError("e-props-correct.2.2.2: for element "
07901:                                    + nameStr
07902:                                    + ", the {content type} is mixed, then the {content type}'s particle must be emptiable");
07903:                    }
07904:
07905:                    try {
07906:                        if (dv != null) {
07907:                            dv.validate(defaultStr, null);
07908:                        }
07909:                    } catch (InvalidDatatypeValueException ide) {
07910:                        reportGenericSchemaError("e-props-correct.2: invalid fixed or default value '"
07911:                                + defaultStr + "' in element " + nameStr);
07912:                    }
07913:                }
07914:
07915:                if (defaultStr.length() != 0 && dv != null
07916:                        && dv instanceof  IDDatatypeValidator) {
07917:                    reportGenericSchemaError("e-props-correct.4: If the {type definition} or {type definition}'s {content type} is or is derived from ID then there must not be a {value constraint} -- element "
07918:                            + nameStr);
07919:                }
07920:
07921:                //
07922:                // Create element decl
07923:                //
07924:
07925:                int elementNameIndex = fStringPool.addSymbol(nameStr);
07926:                int localpartIndex = elementNameIndex;
07927:                int uriIndex = StringPool.EMPTY_STRING;
07928:                int enclosingScope = fCurrentScope;
07929:
07930:                //refer to 4.3.2 in "XML Schema Part 1: Structures"
07931:                if (isTopLevel(elementDecl)) {
07932:                    uriIndex = fTargetNSURI;
07933:                    enclosingScope = TOP_LEVEL_SCOPE;
07934:                } else if (!formStr.equals(SchemaSymbols.ATTVAL_UNQUALIFIED)
07935:                        && ((formStr.equals(SchemaSymbols.ATTVAL_QUALIFIED) || fElementDefaultQualified))) {
07936:
07937:                    uriIndex = fTargetNSURI;
07938:                }
07939:
07940:                QName eltQName = new QName(-1, localpartIndex,
07941:                        elementNameIndex, uriIndex);
07942:
07943:                // Check if an element exists at this scope.
07944:                // If it does, check it against the type of the new element
07945:                int existingEltNdx = fSchemaGrammar.getElementDeclIndex(
07946:                        eltQName.uri, eltQName.localpart, enclosingScope);
07947:
07948:                if (existingEltNdx > -1) {
07949:                    if (!checkDuplicateElementTypes(existingEltNdx, typeInfo,
07950:                            dv)) {
07951:                        noErrorSoFar = false;
07952:
07953:                        reportGenericSchemaError("duplicate element decl in the same scope with different types : "
07954:                                + fStringPool.toString(localpartIndex));
07955:
07956:                    }
07957:                }
07958:
07959:                // add element decl to pool
07960:
07961:                int attrListHead = -1;
07962:
07963:                // copy up attribute decls from type object
07964:                if (typeInfo != null) {
07965:                    attrListHead = typeInfo.attlistHead;
07966:                }
07967:                int elementIndex = fSchemaGrammar.addElementDecl(eltQName,
07968:                        enclosingScope, scopeDefined, contentSpecType,
07969:                        contentSpecNodeIndex, attrListHead, dv);
07970:                // for anyType, we add an attribute wildcard for this element
07971:                if (isAnyType) {
07972:                    fSchemaGrammar.addAttDef(elementIndex,
07973:                    // name
07974:                            new QName(),
07975:                            // type (namespace constaint)
07976:                            XMLAttributeDecl.TYPE_ANY_ANY,
07977:                            // enumeration (namespace list)
07978:                            -1,
07979:                            // defaultType (process contents)
07980:                            XMLAttributeDecl.PROCESSCONTENTS_STRICT,
07981:                            // defaultValue
07982:                            null,
07983:                            // datatypeValidator
07984:                            null,
07985:                            // list
07986:                            false);
07987:                }
07988:
07989:                if (DEBUGGING) {
07990:                    /***/
07991:                    System.out.println("########elementIndex:" + elementIndex
07992:                            + " (" + fStringPool.toString(eltQName.uri) + ","
07993:                            + fStringPool.toString(eltQName.localpart) + ")"
07994:                            + " eltType:" + typeStr + " contentSpecType:"
07995:                            + contentSpecType + " SpecNodeIndex:"
07996:                            + contentSpecNodeIndex + " enclosingScope: "
07997:                            + enclosingScope + " scopeDefined: " + scopeDefined
07998:                            + "\n");
07999:                    /***/
08000:                }
08001:
08002:                fSchemaGrammar
08003:                        .setElementComplexTypeInfo(elementIndex, typeInfo);
08004:                // REVISIT: should we report error if typeInfo was null?
08005:
08006:                // mark element if its type belongs to different Schema.
08007:                fSchemaGrammar.setElementFromAnotherSchemaURI(elementIndex,
08008:                        fromAnotherSchema);
08009:
08010:                // set BlockSet, FinalSet, Nillable and Abstract for this element decl
08011:                fSchemaGrammar.setElementDeclBlockSet(elementIndex, blockSet);
08012:                fSchemaGrammar.setElementDeclFinalSet(elementIndex, finalSet);
08013:                fSchemaGrammar.setElementDeclMiscFlags(elementIndex,
08014:                        elementMiscFlags);
08015:                fSchemaGrammar.setElementDefault(elementIndex, defaultStr);
08016:
08017:                // setSubstitutionGroupElementFullName
08018:                fSchemaGrammar.setElementDeclSubstitutionGroupAffFullName(
08019:                        elementIndex, substitutionGroupFullName);
08020:
08021:                // substitutionGroup: double-direction
08022:                if (substitutionGroupStr.length() > 0 && !ignoreSub) {
08023:                    subGrammar.addElementDeclOneSubstitutionGroupQName(
08024:                            substitutionGroupElementDeclIndex, eltQName,
08025:                            fSchemaGrammar, elementIndex);
08026:                }
08027:
08028:                //
08029:                // key/keyref/unique processing
08030:                //
08031:
08032:                Element ic = XUtil.getFirstChildElementNS(elementDecl,
08033:                        IDENTITY_CONSTRAINTS);
08034:                if (ic != null) {
08035:                    Integer elementIndexObj = new Integer(elementIndex);
08036:                    Vector identityConstraints = (Vector) fIdentityConstraints
08037:                            .get(elementIndexObj);
08038:                    if (identityConstraints == null) {
08039:                        identityConstraints = new Vector();
08040:                        fIdentityConstraints.put(elementIndexObj,
08041:                                identityConstraints);
08042:                    }
08043:                    while (ic != null) {
08044:                        if (DEBUG_IC_DATATYPES) {
08045:                            System.out
08046:                                    .println("<ICD>: adding ic for later traversal: "
08047:                                            + ic);
08048:                        }
08049:                        identityConstraints.addElement(ic);
08050:                        ic = XUtil.getNextSiblingElementNS(ic,
08051:                                IDENTITY_CONSTRAINTS);
08052:                    }
08053:                }
08054:
08055:                return eltQName;
08056:
08057:            }// end of method traverseElementDecl(Element)
08058:
08059:            private boolean checkDuplicateElementTypes(int eltNdx,
08060:                    ComplexTypeInfo typeInfo, DatatypeValidator dv) {
08061:
08062:                fSchemaGrammar.getElementDecl(eltNdx, fTempElementDecl);
08063:                DatatypeValidator edv = fTempElementDecl.datatypeValidator;
08064:                ComplexTypeInfo eTypeInfo = fSchemaGrammar
08065:                        .getElementComplexTypeInfo(eltNdx);
08066:                if (((eTypeInfo != null) && (eTypeInfo != typeInfo))
08067:                        || ((edv != null) && (edv != dv)))
08068:                    return false;
08069:                else
08070:                    return true;
08071:
08072:            }
08073:
08074:            private void traverseIdentityNameConstraintsFor(int elementIndex,
08075:                    Vector identityConstraints) throws Exception {
08076:
08077:                // iterate over identity constraints for this element
08078:                int size = identityConstraints != null ? identityConstraints
08079:                        .size() : 0;
08080:                if (size > 0) {
08081:                    // REVISIT: Use cached copy. -Ac
08082:                    XMLElementDecl edecl = new XMLElementDecl();
08083:                    fSchemaGrammar.getElementDecl(elementIndex, edecl);
08084:                    for (int i = 0; i < size; i++) {
08085:                        Element ic = (Element) identityConstraints.elementAt(i);
08086:                        String icName = ic.getLocalName();
08087:                        if (icName.equals(SchemaSymbols.ELT_KEY)) {
08088:                            traverseKey(ic, edecl);
08089:                        } else if (icName.equals(SchemaSymbols.ELT_UNIQUE)) {
08090:                            traverseUnique(ic, edecl);
08091:                        }
08092:                        fSchemaGrammar.setElementDecl(elementIndex, edecl);
08093:
08094:                    } // loop over vector elements
08095:
08096:                } // if size > 0
08097:
08098:            } // traverseIdentityNameConstraints(Vector)
08099:
08100:            private void traverseIdentityRefConstraintsFor(int elementIndex,
08101:                    Vector identityConstraints) throws Exception {
08102:
08103:                // iterate over identity constraints for this element
08104:                int size = identityConstraints != null ? identityConstraints
08105:                        .size() : 0;
08106:                if (size > 0) {
08107:                    // REVISIT: Use cached copy. -Ac
08108:                    XMLElementDecl edecl = new XMLElementDecl();
08109:                    fSchemaGrammar.getElementDecl(elementIndex, edecl);
08110:                    for (int i = 0; i < size; i++) {
08111:                        Element ic = (Element) identityConstraints.elementAt(i);
08112:                        String icName = ic.getLocalName();
08113:                        if (icName.equals(SchemaSymbols.ELT_KEYREF)) {
08114:                            traverseKeyRef(ic, edecl);
08115:                        }
08116:                        fSchemaGrammar.setElementDecl(elementIndex, edecl);
08117:
08118:                    } // loop over vector elements
08119:
08120:                } // if size > 0
08121:
08122:            } // traverseIdentityRefConstraints(Vector)
08123:
08124:            private void traverseUnique(Element uElem, XMLElementDecl eDecl)
08125:                    throws Exception {
08126:
08127:                // General Attribute Checking
08128:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
08129:                Hashtable attrValues = generalCheck(uElem, scope);
08130:
08131:                // create identity constraint
08132:                String uName = uElem.getAttribute(SchemaSymbols.ATT_NAME);
08133:                if (DEBUG_IDENTITY_CONSTRAINTS) {
08134:                    System.out.println("<IC>: traverseUnique(\""
08135:                            + uElem.getNodeName() + "\") [" + uName + ']');
08136:                }
08137:                String eName = getElementNameFor(uElem);
08138:                Unique unique = new Unique(uName, eName);
08139:                if (fIdentityConstraintNames.get(fTargetNSURIString + ","
08140:                        + uName) != null) {
08141:                    reportGenericSchemaError("More than one identity constraint named "
08142:                            + uName);
08143:                }
08144:                fIdentityConstraintNames.put(fTargetNSURIString + "," + uName,
08145:                        unique);
08146:
08147:                // get selector and fields
08148:                traverseIdentityConstraint(unique, uElem);
08149:
08150:                // add to element decl
08151:                eDecl.unique.addElement(unique);
08152:
08153:            } // traverseUnique(Element,XMLElementDecl)
08154:
08155:            private void traverseKey(Element kElem, XMLElementDecl eDecl)
08156:                    throws Exception {
08157:
08158:                // General Attribute Checking
08159:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
08160:                Hashtable attrValues = generalCheck(kElem, scope);
08161:
08162:                // create identity constraint
08163:                String kName = kElem.getAttribute(SchemaSymbols.ATT_NAME);
08164:                if (DEBUG_IDENTITY_CONSTRAINTS) {
08165:                    System.out.println("<IC>: traverseKey(\""
08166:                            + kElem.getNodeName() + "\") [" + kName + ']');
08167:                }
08168:                String eName = getElementNameFor(kElem);
08169:                Key key = new Key(kName, eName);
08170:                if (fIdentityConstraintNames.get(fTargetNSURIString + ","
08171:                        + kName) != null) {
08172:                    reportGenericSchemaError("More than one identity constraint named "
08173:                            + kName);
08174:                }
08175:                fIdentityConstraintNames.put(fTargetNSURIString + "," + kName,
08176:                        key);
08177:
08178:                // get selector and fields
08179:                traverseIdentityConstraint(key, kElem);
08180:
08181:                // add to element decl
08182:                eDecl.key.addElement(key);
08183:
08184:            } // traverseKey(Element,XMLElementDecl)
08185:
08186:            private void traverseKeyRef(Element krElem, XMLElementDecl eDecl)
08187:                    throws Exception {
08188:
08189:                // General Attribute Checking
08190:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
08191:                Hashtable attrValues = generalCheck(krElem, scope);
08192:
08193:                // create identity constraint
08194:                String krName = krElem.getAttribute(SchemaSymbols.ATT_NAME);
08195:                String kName = krElem.getAttribute(SchemaSymbols.ATT_REFER);
08196:                if (DEBUG_IDENTITY_CONSTRAINTS) {
08197:                    System.out.println("<IC>: traverseKeyRef(\""
08198:                            + krElem.getNodeName() + "\") [" + krName + ','
08199:                            + kName + ']');
08200:                }
08201:
08202:                if (fIdentityConstraintNames.get(fTargetNSURIString + ","
08203:                        + krName) != null) {
08204:                    reportGenericSchemaError("More than one identity constraint named "
08205:                            + krName);
08206:                }
08207:
08208:                // verify that key reference "refer" attribute is valid
08209:                String prefix = "";
08210:                String localpart = kName;
08211:                int colonptr = kName.indexOf(":");
08212:                if (colonptr > 0) {
08213:                    prefix = kName.substring(0, colonptr);
08214:                    localpart = kName.substring(colonptr + 1);
08215:                }
08216:                String uriStr = resolvePrefixToURI(prefix);
08217:                IdentityConstraint kId = (IdentityConstraint) fIdentityConstraintNames
08218:                        .get(uriStr + "," + localpart);
08219:                if (kId == null) {
08220:                    reportSchemaError(
08221:                            SchemaMessageProvider.KeyRefReferNotFound,
08222:                            new Object[] { krName, kName });
08223:                    return;
08224:                }
08225:
08226:                String eName = getElementNameFor(krElem);
08227:                KeyRef keyRef = new KeyRef(krName, kId, eName);
08228:
08229:                // add to element decl
08230:                traverseIdentityConstraint(keyRef, krElem);
08231:                if (keyRef.getFieldCount() != kId.getFieldCount()) {
08232:                    reportSchemaError(
08233:                            SchemaMessageProvider.CardinalityNotEqual,
08234:                            new Object[] { krName, kName });
08235:                    return;
08236:                }
08237:
08238:                // add key reference to element decl
08239:                eDecl.keyRef.addElement(keyRef);
08240:                // store in fIdentityConstraintNames so can flag schemas in which multiple
08241:                // keyrefs with the same name are present.
08242:                fIdentityConstraintNames.put(fTargetNSURIString + "," + krName,
08243:                        keyRef);
08244:
08245:            } // traverseKeyRef(Element,XMLElementDecl)
08246:
08247:            private void traverseIdentityConstraint(IdentityConstraint ic,
08248:                    Element icElem) throws Exception {
08249:
08250:                // General Attribute Checking
08251:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
08252:                Hashtable attrValues = generalCheck(icElem, scope);
08253:
08254:                // check for <annotation> and get selector
08255:                Element sElem = XUtil.getFirstChildElement(icElem);
08256:                if (sElem == null) {
08257:                    // REVISIT: localize
08258:                    reportGenericSchemaError("The content of an identity constraint must match (annotation?, selector, field+)");
08259:                    return;
08260:                }
08261:                sElem = checkContent(icElem, sElem, false);
08262:                // General Attribute Checking
08263:                attrValues = generalCheck(sElem, scope);
08264:
08265:                if (!sElem.getLocalName().equals(SchemaSymbols.ELT_SELECTOR)) {
08266:                    // REVISIT: localize
08267:                    reportGenericSchemaError("The content of an identity constraint must match (annotation?, selector, field+)");
08268:                }
08269:                // and make sure <selector>'s content is fine:
08270:                checkContent(icElem, XUtil.getFirstChildElement(sElem), true);
08271:
08272:                String sText = sElem.getAttribute(SchemaSymbols.ATT_XPATH);
08273:                sText = sText.trim();
08274:                Selector.XPath sXpath = null;
08275:                try {
08276:                    // REVISIT: Must get ruling from XML Schema working group
08277:                    //          regarding whether steps in the XPath must be
08278:                    //          fully qualified if the grammar has a target
08279:                    //          namespace. -Ac
08280:                    //          RESOLUTION: Yes.
08281:                    sXpath = new Selector.XPath(sText, fStringPool,
08282:                            fNamespacesScope);
08283:                    Selector selector = new Selector(sXpath, ic);
08284:                    if (DEBUG_IDENTITY_CONSTRAINTS) {
08285:                        System.out.println("<IC>:   selector: " + selector);
08286:                    }
08287:                    ic.setSelector(selector);
08288:                } catch (XPathException e) {
08289:                    // REVISIT: Add error message.
08290:                    reportGenericSchemaError(e.getMessage());
08291:                    return;
08292:                }
08293:
08294:                // get fields
08295:                Element fElem = XUtil.getNextSiblingElement(sElem);
08296:                if (fElem == null) {
08297:                    // REVISIT:  localize
08298:                    reportGenericSchemaError("The content of an identity constraint must match (annotation?, selector, field+)");
08299:                }
08300:                while (fElem != null) {
08301:                    // General Attribute Checking
08302:                    attrValues = generalCheck(fElem, scope);
08303:
08304:                    if (!fElem.getLocalName().equals(SchemaSymbols.ELT_FIELD))
08305:                        // REVISIT: localize
08306:                        reportGenericSchemaError("The content of an identity constraint must match (annotation?, selector, field+)");
08307:                    // and make sure <field>'s content is fine:
08308:                    checkContent(icElem, XUtil.getFirstChildElement(fElem),
08309:                            true);
08310:                    String fText = fElem.getAttribute(SchemaSymbols.ATT_XPATH);
08311:                    fText = fText.trim();
08312:                    try {
08313:                        // REVISIT: Must get ruling from XML Schema working group
08314:                        //          regarding whether steps in the XPath must be
08315:                        //          fully qualified if the grammar has a target
08316:                        //          namespace. -Ac
08317:                        //          RESOLUTION: Yes.
08318:                        Field.XPath fXpath = new Field.XPath(fText,
08319:                                fStringPool, fNamespacesScope);
08320:                        // REVISIT: Get datatype validator. -Ac
08321:                        // cannot statically determine type of field; not just because of descendant/union
08322:                        // but because of <any> and <anyAttribute>.  - NG
08323:                        // DatatypeValidator validator = getDatatypeValidatorFor(parent, sXpath, fXpath);
08324:                        // if (DEBUG_IC_DATATYPES) {
08325:                        //  System.out.println("<ICD>: datatype validator: "+validator);
08326:                        // }
08327:                        // must find DatatypeValidator in the Validator...
08328:                        Field field = new Field(fXpath, ic);
08329:                        if (DEBUG_IDENTITY_CONSTRAINTS) {
08330:                            System.out.println("<IC>:   field:    " + field);
08331:                        }
08332:                        ic.addField(field);
08333:                    } catch (XPathException e) {
08334:                        // REVISIT: Add error message.
08335:                        reportGenericSchemaError(e.getMessage());
08336:                        return;
08337:                    }
08338:                    fElem = XUtil.getNextSiblingElement(fElem);
08339:                }
08340:
08341:            } // traverseIdentityConstraint(IdentityConstraint,Element)
08342:
08343:            /* This code is no longer used because datatypes can't be found statically for ID constraints.
08344:            private DatatypeValidator getDatatypeValidatorFor(Element element,
08345:                                                              Selector.XPath sxpath,
08346:                                                              Field.XPath fxpath)
08347:                throws Exception {
08348:
08349:                // variables
08350:                String ename = element.getAttribute("name");
08351:                if (DEBUG_IC_DATATYPES) {
08352:                    System.out.println("<ICD>: XMLValidator#getDatatypeValidatorFor("+
08353:                                       ename+','+sxpath+','+fxpath+')');
08354:                }
08355:                int localpart = fStringPool.addSymbol(ename);
08356:                String targetNamespace = fSchemaRootElement.getAttribute("targetNamespace");
08357:                int uri = fStringPool.addSymbol(targetNamespace);
08358:                int edeclIndex = fSchemaGrammar.getElementDeclIndex(uri, localpart,
08359:                                                                    Grammar.TOP_LEVEL_SCOPE);
08360:
08361:                // walk selector
08362:                XPath.LocationPath spath = sxpath.getLocationPath();
08363:                XPath.Step[] ssteps = spath.steps;
08364:                for (int i = 0; i < ssteps.length; i++) {
08365:                    XPath.Step step = ssteps[i];
08366:                    XPath.Axis axis = step.axis;
08367:                    XPath.NodeTest nodeTest = step.nodeTest;
08368:                    switch (axis.type) {
08369:                        case XPath.Axis.ATTRIBUTE: {
08370:                            // REVISIT: Add message. -Ac
08371:                            reportGenericSchemaError("not allowed to select attribute");
08372:                            return null;
08373:                        }
08374:                        case XPath.Axis.CHILD: {
08375:                            int index = fSchemaGrammar.getElementDeclIndex(nodeTest.name, edeclIndex);
08376:                            if (index == -1) {
08377:                                index = fSchemaGrammar.getElementDeclIndex(nodeTest.name, Grammar.TOP_LEVEL_SCOPE);
08378:                            }
08379:                            if (index == -1) {
08380:                                // REVISIT: Add message. -Ac
08381:                                reportGenericSchemaError("no such element \""+fStringPool.toString(nodeTest.name.rawname)+'"');
08382:                                return null;
08383:                            }
08384:                            edeclIndex = index;
08385:                            break;
08386:                        }
08387:                        case XPath.Axis.SELF: {
08388:                            // no-op
08389:                            break;
08390:                        }
08391:                        default: {
08392:                            // REVISIT: Add message. -Ac
08393:                            reportGenericSchemaError("invalid selector axis");
08394:                            return null;
08395:                        }
08396:                    }
08397:                }
08398:
08399:                // walk field
08400:                XPath.LocationPath fpath = fxpath.getLocationPath();
08401:                XPath.Step[] fsteps = fpath.steps;
08402:                for (int i = 0; i < fsteps.length; i++) {
08403:                    XPath.Step step = fsteps[i];
08404:                    XPath.Axis axis = step.axis;
08405:                    XPath.NodeTest nodeTest = step.nodeTest;
08406:                    switch (axis.type) {
08407:                        case XPath.Axis.ATTRIBUTE: {
08408:                            if (i != fsteps.length - 1) {
08409:                                // REVISIT: Add message. -Ac
08410:                                reportGenericSchemaError("attribute must be last step");
08411:                                return null;
08412:                            }
08413:                            // look up validator
08414:                            int adeclIndex = fSchemaGrammar.getAttributeDeclIndex(edeclIndex, nodeTest.name);
08415:                            if (adeclIndex == -1) {
08416:                                // REVISIT: Add message. -Ac
08417:                                reportGenericSchemaError("no such attribute \""+fStringPool.toString(nodeTest.name.rawname)+'"');
08418:                            }
08419:                            XMLAttributeDecl adecl = new XMLAttributeDecl();
08420:                            fSchemaGrammar.getAttributeDecl(adeclIndex, adecl);
08421:                            DatatypeValidator validator = adecl.datatypeValidator;
08422:                            return validator;
08423:                        }
08424:                        case XPath.Axis.CHILD: {
08425:                            int index = fSchemaGrammar.getElementDeclIndex(nodeTest.name, edeclIndex);
08426:                            if (index == -1) {
08427:                                index = fSchemaGrammar.getElementDeclIndex(nodeTest.name, Grammar.TOP_LEVEL_SCOPE);
08428:                            }
08429:                            if (index == -1) {
08430:                                // REVISIT: Add message. -Ac
08431:                                reportGenericSchemaError("no such element \""+fStringPool.toString(nodeTest.name.rawname)+'"');
08432:                                return null;
08433:                            }
08434:                            edeclIndex = index;
08435:                            if (i < fsteps.length - 1) {
08436:                                break;
08437:                            }
08438:                            // NOTE: Let fall through to self case so that we
08439:                            //       avoid duplicating code. -Ac
08440:                        }
08441:                        case XPath.Axis.SELF: {
08442:                            // look up validator, if needed
08443:                            if (i == fsteps.length - 1) {
08444:                                XMLElementDecl edecl = new XMLElementDecl();
08445:                                fSchemaGrammar.getElementDecl(edeclIndex, edecl);
08446:                                if (edecl.type != XMLElementDecl.TYPE_SIMPLE) {
08447:                                    // REVISIT: Add message. -Ac
08448:                                    reportGenericSchemaError("selected element is not of simple type");
08449:                                    return null;
08450:                                }
08451:                                DatatypeValidator validator = edecl.datatypeValidator;
08452:                                if (validator == null) validator = new StringDatatypeValidator();
08453:                                return validator;
08454:                            }
08455:                            break;
08456:                        }
08457:                        default: {
08458:                            // REVISIT: Add message. -Ac
08459:                            reportGenericSchemaError("invalid selector axis");
08460:                            return null;
08461:                        }
08462:                    }
08463:                }
08464:
08465:                // no validator!
08466:                // REVISIT: Add message. -Ac
08467:                reportGenericSchemaError("No datatype validator for field "+fxpath+
08468:                                         " of element "+ename);
08469:                return null;
08470:
08471:            } // getDatatypeValidatorFor(XPath):DatatypeValidator
08472:             */// back in to live code...
08473:            private String getElementNameFor(Element icnode) {
08474:                Element enode = (Element) icnode.getParentNode();
08475:                String ename = enode.getAttribute("name");
08476:                if (ename.length() == 0) {
08477:                    ename = enode.getAttribute("ref");
08478:                }
08479:                return ename;
08480:            } // getElementNameFor(Element):String
08481:
08482:            int getLocalPartIndex(String fullName) {
08483:                int colonAt = fullName.indexOf(":");
08484:                String localpart = fullName;
08485:                if (colonAt > -1) {
08486:                    localpart = fullName.substring(colonAt + 1);
08487:                }
08488:                return fStringPool.addSymbol(localpart);
08489:            }
08490:
08491:            String getLocalPart(String fullName) {
08492:                int colonAt = fullName.indexOf(":");
08493:                String localpart = fullName;
08494:                if (colonAt > -1) {
08495:                    localpart = fullName.substring(colonAt + 1);
08496:                }
08497:                return localpart;
08498:            }
08499:
08500:            int getPrefixIndex(String fullName) {
08501:                int colonAt = fullName.indexOf(":");
08502:                String prefix = "";
08503:                if (colonAt > -1) {
08504:                    prefix = fullName.substring(0, colonAt);
08505:                }
08506:                return fStringPool.addSymbol(prefix);
08507:            }
08508:
08509:            String getPrefix(String fullName) {
08510:                int colonAt = fullName.indexOf(":");
08511:                String prefix = "";
08512:                if (colonAt > -1) {
08513:                    prefix = fullName.substring(0, colonAt);
08514:                }
08515:                return prefix;
08516:            }
08517:
08518:            private void checkSubstitutionGroupOK(Element elementDecl,
08519:                    Element substitutionGroupElementDecl, boolean noErrorSoFar,
08520:                    int substitutionGroupElementDeclIndex,
08521:                    SchemaGrammar substitutionGroupGrammar,
08522:                    ComplexTypeInfo typeInfo,
08523:                    ComplexTypeInfo substitutionGroupEltTypeInfo,
08524:                    DatatypeValidator dv,
08525:                    DatatypeValidator substitutionGroupEltDV) throws Exception {
08526:
08527:                // if final="#all" or final="extension restriction"
08528:                // then it can't be substituted at all (according to 3.3.1)
08529:                // ??? REVISIT: but it's not mentioned in 3.3.6, where it should be.
08530:                int finalSet = substitutionGroupGrammar
08531:                        .getElementDeclFinalSet(substitutionGroupElementDeclIndex);
08532:                if ((finalSet & SchemaSymbols.RESTRICTION) != 0
08533:                        && (finalSet & SchemaSymbols.EXTENSION) != 0) {
08534:                    reportGenericSchemaError("element "
08535:                            + elementDecl.getAttribute(SchemaSymbols.ATT_NAME)
08536:                            + " cannot be part of the substitution group headed by "
08537:                            + substitutionGroupElementDecl
08538:                                    .getAttribute(SchemaSymbols.ATT_NAME));
08539:                }
08540:
08541:                // here we must do two things:
08542:                // 1.  Make sure there actually *is* a relation between the types of
08543:                // the element being nominated and the element doing the nominating;
08544:                // (see PR 3.3.6 point #3 in the first tableau, for instance; this
08545:                // and the corresponding tableaux from 3.4.6 and 3.14.6 rule out the nominated
08546:                // element having an anonymous type declaration.
08547:                // 2.  Make sure the nominated element allows itself to be nominated by
08548:                // an element with the given type-relation.
08549:                // Note:  we assume that (complex|simple)Type processing checks
08550:                // whether the type in question allows itself to
08551:                // be modified as this element desires.
08552:
08553:                // Check for type relationship;
08554:                // that is, make sure that the type we're deriving has some relationship
08555:                // to substitutionGroupElt's type.
08556:                if (typeInfo != null) {
08557:                    // if the two types are the same, just return
08558:                    if (substitutionGroupEltTypeInfo == typeInfo)
08559:                        return;
08560:                    int derivationMethod = typeInfo.derivedBy;
08561:                    if (typeInfo.baseComplexTypeInfo == null) {
08562:                        if (typeInfo.baseDataTypeValidator != null) { // take care of complexType based on simpleType case...
08563:                            if (!checkSimpleTypeDerivationOK(
08564:                                    typeInfo.baseDataTypeValidator,
08565:                                    substitutionGroupEltDV)
08566:                                    && !(substitutionGroupEltTypeInfo == null && substitutionGroupEltDV == null)) {
08567:                                // REVISIT:  localize
08568:                                reportGenericSchemaError("Element "
08569:                                        + elementDecl
08570:                                                .getAttribute(SchemaSymbols.ATT_NAME)
08571:                                        + " has a type which does not derive from the type of the element at the head of the substitution group");
08572:                                noErrorSoFar = false;
08573:                            } else { // now let's see if substitutionGroup element allows this:
08574:                                if ((derivationMethod & finalSet) != 0) {
08575:                                    noErrorSoFar = false;
08576:                                    // REVISIT:  localize
08577:                                    reportGenericSchemaError("element "
08578:                                            + elementDecl
08579:                                                    .getAttribute(SchemaSymbols.ATT_NAME)
08580:                                            + " cannot be part of the substitution group headed by "
08581:                                            + substitutionGroupElementDecl
08582:                                                    .getAttribute(SchemaSymbols.ATT_NAME));
08583:                                }
08584:                            }
08585:                        } else if (!(substitutionGroupEltTypeInfo == null && substitutionGroupEltDV == null)) {
08586:                            // REVISIT:  localize
08587:                            reportGenericSchemaError("Element "
08588:                                    + elementDecl
08589:                                            .getAttribute(SchemaSymbols.ATT_NAME)
08590:                                    + " which is part of a substitution must have a type which derives from the type of the element at the head of the substitution group");
08591:                            noErrorSoFar = false;
08592:                        }
08593:                    } else {
08594:                        ComplexTypeInfo subTypeInfo = typeInfo;
08595:                        for (; subTypeInfo != null
08596:                                && substitutionGroupEltTypeInfo != null
08597:                                && subTypeInfo != substitutionGroupEltTypeInfo; subTypeInfo = subTypeInfo.baseComplexTypeInfo)
08598:                            ;
08599:                        if (subTypeInfo == null
08600:                                || (substitutionGroupEltTypeInfo == null && substitutionGroupEltDV != null)) { // then this type isn't in the chain...
08601:                            // REVISIT:  localize
08602:                            reportGenericSchemaError("Element "
08603:                                    + elementDecl
08604:                                            .getAttribute(SchemaSymbols.ATT_NAME)
08605:                                    + " has a type which does not derive from the type of the element at the head of the substitution group");
08606:                            noErrorSoFar = false;
08607:                        } else { // type is fine; does substitutionElement allow this?
08608:                            if ((derivationMethod & finalSet) != 0) {
08609:                                noErrorSoFar = false;
08610:                                // REVISIT:  localize
08611:                                reportGenericSchemaError("element "
08612:                                        + elementDecl
08613:                                                .getAttribute(SchemaSymbols.ATT_NAME)
08614:                                        + " cannot be part of the substitution group headed by "
08615:                                        + substitutionGroupElementDecl
08616:                                                .getAttribute(SchemaSymbols.ATT_NAME));
08617:                            }
08618:                        }
08619:                    }
08620:                } else if (dv != null) { // do simpleType case...
08621:                    // if the two types are the same, just return
08622:                    if (dv == substitutionGroupEltDV)
08623:                        return;
08624:                    // first, check for type relation.
08625:                    if (!(checkSimpleTypeDerivationOK(dv,
08626:                            substitutionGroupEltDV))
08627:                            && !(substitutionGroupEltTypeInfo == null && substitutionGroupEltDV == null)) {
08628:                        // REVISIT:  localize
08629:                        reportGenericSchemaError("Element "
08630:                                + elementDecl
08631:                                        .getAttribute(SchemaSymbols.ATT_NAME)
08632:                                + " has a type which does not derive from the type of the element at the head of the substitution group");
08633:                        noErrorSoFar = false;
08634:                    } else { // now let's see if substitutionGroup element allows this:
08635:                        if ((SchemaSymbols.RESTRICTION & finalSet) != 0) {
08636:                            noErrorSoFar = false;
08637:                            // REVISIT:  localize
08638:                            reportGenericSchemaError("element "
08639:                                    + elementDecl
08640:                                            .getAttribute(SchemaSymbols.ATT_NAME)
08641:                                    + " cannot be part of the substitution group headed by "
08642:                                    + substitutionGroupElementDecl
08643:                                            .getAttribute(SchemaSymbols.ATT_NAME));
08644:                        }
08645:                    }
08646:                }
08647:            }
08648:
08649:            //
08650:            // A utility method to check whether a particular datatypevalidator d, was validly
08651:            // derived from another datatypevalidator, b
08652:            //
08653:            private boolean checkSimpleTypeDerivationOK(DatatypeValidator d,
08654:                    DatatypeValidator b) {
08655:                // if b is anySimpleType, then the derivation is OK.
08656:                if (b instanceof  AnySimpleType)
08657:                    return true;
08658:
08659:                DatatypeValidator dTemp = d;
08660:                for (; dTemp != null; dTemp = dTemp.getBaseValidator()) {
08661:                    // WARNING!!!  This uses comparison by reference andTemp is thus inherently suspect!
08662:                    if (dTemp == b)
08663:                        break;
08664:                }
08665:                if (dTemp == null) {
08666:                    // now if b is a union, then we can
08667:                    // derive from it if we derive from any of its members' types.
08668:                    if (b instanceof  UnionDatatypeValidator) {
08669:                        // d must derive from one of its members...
08670:                        Vector subUnionMemberDV = ((UnionDatatypeValidator) b)
08671:                                .getBaseValidators();
08672:                        int subUnionSize = subUnionMemberDV.size();
08673:                        boolean found = false;
08674:                        for (int i = 0; i < subUnionSize && !found; i++) {
08675:                            DatatypeValidator dTempSub = (DatatypeValidator) subUnionMemberDV
08676:                                    .elementAt(i);
08677:                            // if dTempSub is anySimpleType, then the derivation is OK.
08678:                            if (dTempSub instanceof  AnySimpleType)
08679:                                return true;
08680:
08681:                            DatatypeValidator dTempOrig = d;
08682:                            for (; dTempOrig != null; dTempOrig = dTempOrig
08683:                                    .getBaseValidator()) {
08684:                                // WARNING!!!  This uses comparison by reference andTemp is thus inherently suspect!
08685:                                if (dTempSub == dTempOrig) {
08686:                                    found = true;
08687:                                    break;
08688:                                }
08689:                            }
08690:                        }
08691:                        if (!found) {
08692:                            return false;
08693:                        }
08694:                    } else {
08695:                        return false;
08696:                    }
08697:                }
08698:
08699:                return true;
08700:            }
08701:
08702:            // this originally-simple method is much -complicated by the fact that, when we're
08703:            // redefining something, we've not only got to look at the space of the thing
08704:            // we're redefining but at the original schema too.
08705:            // The idea is to start from the top, then go down through
08706:            // our list of schemas until we find what we aant.
08707:            // This should not often be necessary, because we've processed
08708:            // all redefined schemas, but three are conditions in which
08709:            // not all elements so redefined may have been promoted to
08710:            // the topmost level.
08711:            private Element getTopLevelComponentByName(
08712:                    String componentCategory, String name) throws Exception {
08713:                Element child = null;
08714:                SchemaInfo curr = fSchemaInfoListRoot;
08715:                for (; curr != null || curr == fSchemaInfoListRoot; curr = curr
08716:                        .getNext()) {
08717:                    if (curr != null)
08718:                        curr.restore();
08719:                    if (componentCategory.equals(SchemaSymbols.ELT_GROUP)) {
08720:                        child = (Element) fSchemaGrammar.topLevelGroupDecls
08721:                                .get(name);
08722:                    } else if (componentCategory
08723:                            .equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)
08724:                            && fSchemaInfoListRoot == null) {
08725:                        child = (Element) fSchemaGrammar.topLevelAttrGrpDecls
08726:                                .get(name);
08727:                    } else if (componentCategory
08728:                            .equals(SchemaSymbols.ELT_ATTRIBUTE)) {
08729:                        child = (Element) fSchemaGrammar.topLevelAttrDecls
08730:                                .get(name);
08731:                    }
08732:
08733:                    if (child != null) {
08734:                        break;
08735:                    }
08736:
08737:                    child = XUtil.getFirstChildElement(fSchemaRootElement);
08738:
08739:                    if (child == null) {
08740:                        continue;
08741:                    }
08742:
08743:                    while (child != null) {
08744:                        if (child.getLocalName().equals(componentCategory)) {
08745:                            if (child.getAttribute(SchemaSymbols.ATT_NAME)
08746:                                    .equals(name)) {
08747:                                break;
08748:                            }
08749:                        } else if (fRedefineSucceeded
08750:                                && child.getLocalName().equals(
08751:                                        SchemaSymbols.ELT_REDEFINE)) {
08752:                            Element gChild = XUtil.getFirstChildElement(child);
08753:                            while (gChild != null) {
08754:                                if (gChild.getLocalName().equals(
08755:                                        componentCategory)) {
08756:                                    if (gChild.getAttribute(
08757:                                            SchemaSymbols.ATT_NAME)
08758:                                            .equals(name)) {
08759:                                        break;
08760:                                    }
08761:                                }
08762:                                gChild = XUtil.getNextSiblingElement(gChild);
08763:                            }
08764:                            if (gChild != null) {
08765:                                child = gChild;
08766:                                break;
08767:                            }
08768:                        }
08769:                        child = XUtil.getNextSiblingElement(child);
08770:                    }
08771:                    if (child != null || fSchemaInfoListRoot == null)
08772:                        break;
08773:                }
08774:                // have to reset fSchemaInfoList
08775:                if (curr != null)
08776:                    curr.restore();
08777:                else if (fSchemaInfoListRoot != null)
08778:                    fSchemaInfoListRoot.restore();
08779:                return child;
08780:            }
08781:
08782:            private boolean isTopLevel(Element component) {
08783:                String parentName = component.getParentNode().getLocalName();
08784:                return (parentName.endsWith(SchemaSymbols.ELT_SCHEMA))
08785:                        || (parentName.endsWith(SchemaSymbols.ELT_REDEFINE));
08786:            }
08787:
08788:            DatatypeValidator getTypeValidatorFromNS(String newSchemaURI,
08789:                    String localpart) throws Exception {
08790:                // The following impl is for the case where every Schema Grammar has its own instance of DatatypeRegistry.
08791:                // Now that we have only one DataTypeRegistry used by all schemas. this is not needed.
08792:                /*****
08793:                Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
08794:                if (grammar != null && grammar instanceof SchemaGrammar) {
08795:                    SchemaGrammar sGrammar = (SchemaGrammar) grammar;
08796:                    DatatypeValidator dv = (DatatypeValidator) fSchemaGrammar.getDatatypeRegistry().getDatatypeValidator(localpart);
08797:                    return dv;
08798:                }
08799:                else {
08800:                    reportGenericSchemaError("could not resolve URI : " + newSchemaURI + " to a SchemaGrammar in getTypeValidatorFromNS");
08801:                }
08802:                return null;
08803:                /*****/
08804:                return getDatatypeValidator(newSchemaURI, localpart);
08805:            }
08806:
08807:            ComplexTypeInfo getTypeInfoFromNS(String newSchemaURI,
08808:                    String localpart) throws Exception {
08809:                Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
08810:                if (grammar != null && grammar instanceof  SchemaGrammar) {
08811:                    SchemaGrammar sGrammar = (SchemaGrammar) grammar;
08812:                    ComplexTypeInfo typeInfo = (ComplexTypeInfo) sGrammar
08813:                            .getComplexTypeRegistry().get(
08814:                                    newSchemaURI + "," + localpart);
08815:                    return typeInfo;
08816:                } else {
08817:                    reportGenericSchemaError("could not resolve URI : "
08818:                            + newSchemaURI
08819:                            + " to a SchemaGrammar in getTypeInfoFromNS");
08820:                }
08821:                return null;
08822:            }
08823:
08824:            DatatypeValidator getElementDeclTypeValidatorFromNS(
08825:                    String newSchemaURI, String localpart) throws Exception {
08826:                Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
08827:                if (grammar != null && grammar instanceof  SchemaGrammar) {
08828:                    SchemaGrammar sGrammar = (SchemaGrammar) grammar;
08829:                    int eltIndex = sGrammar.getElementDeclIndex(fStringPool
08830:                            .addSymbol(newSchemaURI), fStringPool
08831:                            .addSymbol(localpart), TOP_LEVEL_SCOPE);
08832:
08833:                    DatatypeValidator dv = null;
08834:                    if (eltIndex > -1) {
08835:                        sGrammar.getElementDecl(eltIndex, fTempElementDecl);
08836:                        dv = fTempElementDecl.datatypeValidator;
08837:                    } else {
08838:                        reportGenericSchemaError("could not find global element : '"
08839:                                + localpart
08840:                                + " in the SchemaGrammar "
08841:                                + newSchemaURI);
08842:                    }
08843:                    return dv;
08844:                } else {
08845:                    reportGenericSchemaError("could not resolve URI : "
08846:                            + newSchemaURI
08847:                            + " to a SchemaGrammar in getELementDeclTypeValidatorFromNS");
08848:                }
08849:                return null;
08850:            }
08851:
08852:            ComplexTypeInfo getElementDeclTypeInfoFromNS(String newSchemaURI,
08853:                    String localpart) throws Exception {
08854:                Grammar grammar = fGrammarResolver.getGrammar(newSchemaURI);
08855:                if (grammar != null && grammar instanceof  SchemaGrammar) {
08856:                    SchemaGrammar sGrammar = (SchemaGrammar) grammar;
08857:                    int eltIndex = sGrammar.getElementDeclIndex(fStringPool
08858:                            .addSymbol(newSchemaURI), fStringPool
08859:                            .addSymbol(localpart), TOP_LEVEL_SCOPE);
08860:                    ComplexTypeInfo typeInfo = null;
08861:                    if (eltIndex > -1) {
08862:                        typeInfo = sGrammar.getElementComplexTypeInfo(eltIndex);
08863:                    } else {
08864:                        reportGenericSchemaError("could not find global element : '"
08865:                                + localpart
08866:                                + " in the SchemaGrammar "
08867:                                + newSchemaURI);
08868:
08869:                    }
08870:                    return typeInfo;
08871:                } else {
08872:                    reportGenericSchemaError("could not resolve URI : "
08873:                            + newSchemaURI
08874:                            + " to a SchemaGrammar in getElementDeclTypeInfoFromNS");
08875:                }
08876:                return null;
08877:            }
08878:
08879:            /**
08880:             * Traverses notation declaration
08881:             * and saves it in a registry.
08882:             * Notations are stored in registry with the following
08883:             * key: "uri:localname"
08884:             *
08885:             * @param notation child <notation>
08886:             * @return  local name of notation
08887:             * @exception Exception
08888:             */
08889:            private String traverseNotationDecl(Element notation)
08890:                    throws Exception {
08891:                // General Attribute Checking
08892:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
08893:                Hashtable attrValues = generalCheck(notation, scope);
08894:
08895:                String name = notation.getAttribute(SchemaSymbols.ATT_NAME);
08896:                String qualifiedName = name;
08897:                if (fTargetNSURIString.length() != 0) {
08898:                    qualifiedName = fTargetNSURIString + ":" + name;
08899:                }
08900:                if (fNotationRegistry.get(qualifiedName) != null) {
08901:                    return name;
08902:                }
08903:                String publicId = notation
08904:                        .getAttribute(SchemaSymbols.ATT_PUBLIC);
08905:                String systemId = notation
08906:                        .getAttribute(SchemaSymbols.ATT_SYSTEM);
08907:                if (publicId.length() == 0 && systemId.length() == 0) {
08908:                    //REVISIT: update error messages
08909:                    reportGenericSchemaError("<notation> declaration is invalid");
08910:                }
08911:                if (name.length() == 0) {
08912:                    //REVISIT: update error messages
08913:                    reportGenericSchemaError("<notation> declaration does not have a name");
08914:
08915:                }
08916:
08917:                fNotationRegistry.put(qualifiedName, name);
08918:
08919:                //we don't really care if something inside <notation> is wrong..
08920:                checkContent(notation, XUtil.getFirstChildElement(notation),
08921:                        true);
08922:
08923:                //REVISIT: wait for DOM L3 APIs to pass info to application
08924:                //REVISIT: SAX2 does not support notations. API should be changed.
08925:                return name;
08926:            }
08927:
08928:            /**
08929:             * This methods will traverse notation from current schema,
08930:             * as well as from included or imported schemas
08931:             *
08932:             * @param notationName
08933:             *               localName of notation
08934:             * @param uriStr uriStr for schema grammar
08935:             * @return  return local name for Notation (if found), otherwise
08936:             *         return empty string;
08937:             * @exception Exception
08938:             */
08939:            private String traverseNotationFromAnotherSchema(
08940:                    String notationName, String uriStr) throws Exception {
08941:
08942:                Grammar grammar = fGrammarResolver.getGrammar(uriStr);
08943:                if (uriStr == null || grammar == null
08944:                        || !(grammar instanceof  SchemaGrammar)) {
08945:                    // REVISIT: Localize
08946:                    reportGenericSchemaError("!!Schema not found in #traverseNotationDeclFromAnotherSchema, "
08947:                            + "schema uri: "
08948:                            + uriStr
08949:                            + ", groupName: "
08950:                            + notationName);
08951:                    return "";
08952:                }
08953:                SchemaGrammar aGrammar = (SchemaGrammar) grammar;
08954:
08955:                String savedNSURIString = fTargetNSURIString;
08956:                fTargetNSURIString = fStringPool.toString(fStringPool
08957:                        .addSymbol(aGrammar.getTargetNamespaceURI()));
08958:                if (DEBUGGING) {
08959:                    System.out.println("[traverseFromAnotherSchema]: "
08960:                            + fTargetNSURIString);
08961:                }
08962:
08963:                String qualifiedName = fTargetNSURIString + ":" + notationName;
08964:                String localName = (String) fNotationRegistry
08965:                        .get(qualifiedName);
08966:
08967:                if (localName != null) // we've already traversed this notation
08968:                    return localName;
08969:
08970:                //notation decl has not been traversed yet
08971:                Element notationDecl = (Element) aGrammar.topLevelNotationDecls
08972:                        .get((Object) notationName);
08973:                if (notationDecl == null) {
08974:                    // REVISIT: Localize
08975:                    reportGenericSchemaError("no notation named \""
08976:                            + notationName + "\" was defined in schema : "
08977:                            + uriStr);
08978:                    return "";
08979:                }
08980:
08981:                localName = traverseNotationDecl(notationDecl);
08982:                fTargetNSURIString = savedNSURIString;
08983:                return localName;
08984:
08985:            } // end of method traverseNotationFromAnotherSchema
08986:
08987:            /**
08988:             * Traverse Group Declaration.
08989:             *
08990:             * <group
08991:             *         id = ID
08992:             *         maxOccurs = string
08993:             *         minOccurs = nonNegativeInteger
08994:             *         name = NCName
08995:             *         ref = QName>
08996:             *   Content: (annotation? , (all | choice | sequence)?)
08997:             * <group/>
08998:             *
08999:             * @param elementDecl
09000:             * @return
09001:             * @exception Exception
09002:             */
09003:            private GroupInfo traverseGroupDecl(Element groupDecl)
09004:                    throws Exception {
09005:
09006:                // General Attribute Checking
09007:                int scope = isTopLevel(groupDecl) ? GeneralAttrCheck.ELE_CONTEXT_GLOBAL
09008:                        : GeneralAttrCheck.ELE_CONTEXT_LOCAL;
09009:                Hashtable attrValues = generalCheck(groupDecl, scope);
09010:
09011:                String groupName = groupDecl
09012:                        .getAttribute(SchemaSymbols.ATT_NAME);
09013:                String ref = groupDecl.getAttribute(SchemaSymbols.ATT_REF);
09014:                GroupInfo gInfo = null;
09015:                Element child = checkContent(groupDecl, XUtil
09016:                        .getFirstChildElement(groupDecl), true);
09017:
09018:                if (ref.length() != 0) {
09019:                    if (isTopLevel(groupDecl))
09020:                        // REVISIT:  localize
09021:                        reportGenericSchemaError("A group with \"ref\" present must not have <schema> or <redefine> as its parent");
09022:                    if (groupName.length() != 0)
09023:                        // REVISIT:  localize
09024:                        reportGenericSchemaError("group "
09025:                                + groupName
09026:                                + " cannot refer to another group, but it refers to "
09027:                                + ref);
09028:
09029:                    // there should be no children for <group ref="...">
09030:                    if (XUtil.getFirstChildElement(groupDecl) != null)
09031:                        reportGenericSchemaError("A group with \"ref\" present must not have children");
09032:                    String prefix = "";
09033:                    String localpart = ref;
09034:                    int colonptr = ref.indexOf(":");
09035:                    if (colonptr > 0) {
09036:                        prefix = ref.substring(0, colonptr);
09037:                        localpart = ref.substring(colonptr + 1);
09038:                    }
09039:                    int localpartIndex = fStringPool.addSymbol(localpart);
09040:
09041:                    String uriStr = resolvePrefixToURI(prefix);
09042:
09043:                    if (!uriStr.equals(fTargetNSURIString)) {
09044:                        gInfo = traverseGroupDeclFromAnotherSchema(localpart,
09045:                                uriStr);
09046:                        if (gInfo != null) {
09047:                            if (DEBUG_NEW_GROUP)
09048:                                findAndCreateElements(gInfo.contentSpecIndex,
09049:                                        gInfo.scope);
09050:                        }
09051:                        return gInfo;
09052:                    }
09053:
09054:                    try {
09055:                        gInfo = (GroupInfo) fGroupNameRegistry.get(uriStr + ","
09056:                                + localpart);
09057:                        if (gInfo != null) {
09058:                            // Ensure any LEAF elements are created at the
09059:                            // scope of the referencing type
09060:                            if (DEBUG_NEW_GROUP)
09061:                                findAndCreateElements(gInfo.contentSpecIndex,
09062:                                        gInfo.scope);
09063:                            return gInfo;
09064:                        }
09065:
09066:                    } catch (ClassCastException c) {
09067:                    }
09068:
09069:                    // Check if we are in the middle of traversing this group (i.e. circular references)
09070:                    if (fCurrentGroupNameStack.search((Object) localpart) > -1) {
09071:                        reportGenericSchemaError("mg-props-correct: Circular definition for group "
09072:                                + localpart);
09073:                        return null;
09074:                    }
09075:
09076:                    int contentSpecIndex = -1;
09077:                    Element referredGroup = getTopLevelComponentByName(
09078:                            SchemaSymbols.ELT_GROUP, localpart);
09079:                    if (referredGroup == null) {
09080:                        // REVISIT: Localize
09081:                        reportGenericSchemaError("Group " + localpart
09082:                                + " not found in the Schema");
09083:                        //REVISIT, this should be some custom Exception
09084:                        //throw new RuntimeException("Group " + localpart + " not found in the Schema");
09085:                    } else {
09086:                        gInfo = traverseGroupDecl(referredGroup);
09087:                    }
09088:
09089:                    // Now that we have a tree, ensure any LEAF elements are created at the
09090:                    // scope of the referencing type
09091:                    if (gInfo != null) {
09092:                        if (DEBUG_NEW_GROUP)
09093:                            findAndCreateElements(gInfo.contentSpecIndex,
09094:                                    gInfo.scope);
09095:                    }
09096:                    return gInfo;
09097:
09098:                } else if (groupName.length() == 0)
09099:                    // REVISIT: Localize
09100:                    reportGenericSchemaError("a <group> must have a name or a ref present");
09101:
09102:                String qualifiedGroupName = fTargetNSURIString + ","
09103:                        + groupName;
09104:                try {
09105:                    gInfo = (GroupInfo) fGroupNameRegistry
09106:                            .get(qualifiedGroupName);
09107:                    if (gInfo != null) {
09108:                        // Ensure any LEAF elements are created at the
09109:                        // scope of the referencing type
09110:                        if (DEBUG_NEW_GROUP)
09111:                            findAndCreateElements(gInfo.contentSpecIndex,
09112:                                    gInfo.scope);
09113:                        return gInfo;
09114:                    }
09115:
09116:                } catch (ClassCastException c) {
09117:                }
09118:
09119:                // if we're here then we're traversing a top-level group that we've never seen before.
09120:                // Push the group name onto a stack, so that we can check for circular groups
09121:                fCurrentGroupNameStack.push(groupName);
09122:
09123:                // Save the scope and set the current scope to -1
09124:                int savedScope = fCurrentScope;
09125:                if (DEBUG_NEW_GROUP)
09126:                    fCurrentScope = fScopeCount++;
09127:                else
09128:                    fCurrentScope = -1;
09129:
09130:                int index = -2;
09131:
09132:                boolean illegalChild = false;
09133:                String childName = (child != null) ? child.getLocalName() : "";
09134:
09135:                if (childName.equals(SchemaSymbols.ELT_ALL)) {
09136:                    index = traverseAll(child);
09137:                } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
09138:                    index = traverseChoice(child);
09139:                } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
09140:                    index = traverseSequence(child);
09141:                } else if (childName.length() != 0
09142:                        || (child != null && XUtil.getNextSiblingElement(child) != null)) {
09143:                    illegalChild = true;
09144:                    reportSchemaError(
09145:                            SchemaMessageProvider.GroupContentRestricted,
09146:                            new Object[] { "group", childName });
09147:                }
09148:
09149:                //Must have all or choice or sequence child.
09150:                if (child == null) {
09151:                    reportGenericSchemaError("Named group must contain an 'all', 'choice' or 'sequence' child");
09152:                } else if (XUtil.getNextSiblingElement(child) != null) {
09153:                    illegalChild = true;
09154:                    reportSchemaError(
09155:                            SchemaMessageProvider.GroupContentRestricted,
09156:                            new Object[] { "group", childName });
09157:                }
09158:                if (!illegalChild && child != null) {
09159:                    index = handleOccurrences(index, child, CHILD_OF_GROUP);
09160:                }
09161:
09162:                gInfo = new GroupInfo();
09163:                gInfo.contentSpecIndex = index;
09164:                gInfo.scope = fCurrentScope;
09165:                fCurrentScope = savedScope;
09166:                fCurrentGroupNameStack.pop();
09167:                fGroupNameRegistry.put(qualifiedGroupName, gInfo);
09168:                return gInfo;
09169:            }
09170:
09171:            private void findAndCreateElements(int csIndex, int scope) {
09172:
09173:                if (csIndex < 0 || fCurrentScope == TOP_LEVEL_SCOPE) {
09174:                    return;
09175:                }
09176:
09177:                fSchemaGrammar.getContentSpec(csIndex, tempContentSpec1);
09178:
09179:                int type = tempContentSpec1.type;
09180:                int left = tempContentSpec1.value;
09181:                int right = tempContentSpec1.otherValue;
09182:
09183:                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
09184:                    int eltNdx = fSchemaGrammar.getElementDeclIndex(right,
09185:                            left, scope);
09186:                    if (eltNdx < 0)
09187:                        return;
09188:
09189:                    ComplexTypeInfo typeInfo = fSchemaGrammar
09190:                            .getElementComplexTypeInfo(eltNdx);
09191:                    int scopeDefined = typeInfo != null ? typeInfo.scopeDefined
09192:                            : fCurrentScope;
09193:
09194:                    int newIdx = fSchemaGrammar.cloneElementDecl(eltNdx,
09195:                            fCurrentScope, scopeDefined);
09196:
09197:                    // if the element being cloned is in fElementRecurseComplex,
09198:                    // which means it's inside a recursive declaration, we need to put
09199:                    // the cloned element in the vector too, so that its declaration
09200:                    // will be finished after we get all the type information - sgao
09201:                    int count = fElementRecurseComplex.size();
09202:                    for (int i = 0; i < count; i++) {
09203:                        ElementInfo eobj = (ElementInfo) fElementRecurseComplex
09204:                                .elementAt(i);
09205:                        if (eobj.elementIndex == eltNdx) {
09206:                            fElementRecurseComplex.addElement(new ElementInfo(
09207:                                    newIdx, eobj.typeName));
09208:                            break;
09209:                        }
09210:                    }
09211:                } else if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE
09212:                        || type == XMLContentSpec.CONTENTSPECNODE_ALL
09213:                        || type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
09214:
09215:                    findAndCreateElements(left, scope);
09216:
09217:                    if (right != -2)
09218:                        findAndCreateElements(right, scope);
09219:                }
09220:
09221:                else if (type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
09222:                        || type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
09223:                        || type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
09224:
09225:                    findAndCreateElements(left, scope);
09226:                }
09227:                return;
09228:
09229:            }
09230:
09231:            private GroupInfo traverseGroupDeclFromAnotherSchema(
09232:                    String groupName, String uriStr) throws Exception {
09233:
09234:                GroupInfo gInfo = null;
09235:                Grammar grammar = fGrammarResolver.getGrammar(uriStr);
09236:                if (uriStr == null || grammar == null
09237:                        || !(grammar instanceof  SchemaGrammar)) {
09238:                    // REVISIT: Localize
09239:                    reportGenericSchemaError("!!Schema not found in #traverseGroupDeclFromAnotherSchema, "
09240:                            + "schema uri: "
09241:                            + uriStr
09242:                            + ", groupName: "
09243:                            + groupName);
09244:                    return null;
09245:                }
09246:                SchemaGrammar aGrammar = (SchemaGrammar) grammar;
09247:
09248:                Element groupDecl = (Element) aGrammar.topLevelGroupDecls
09249:                        .get((Object) groupName);
09250:                if (groupDecl == null) {
09251:                    // REVISIT: Localize
09252:                    reportGenericSchemaError("no group named \"" + groupName
09253:                            + "\" was defined in schema : " + uriStr);
09254:                    return null;
09255:                }
09256:
09257:                NamespacesScope saveNSMapping = fNamespacesScope;
09258:                int saveTargetNSUri = fTargetNSURI;
09259:                fTargetNSURI = fStringPool.addSymbol(aGrammar
09260:                        .getTargetNamespaceURI());
09261:                fNamespacesScope = aGrammar.getNamespacesScope();
09262:
09263:                Element child = checkContent(groupDecl, XUtil
09264:                        .getFirstChildElement(groupDecl), true);
09265:
09266:                String qualifiedGroupName = fTargetNSURIString + ","
09267:                        + groupName;
09268:                try {
09269:                    gInfo = (GroupInfo) fGroupNameRegistry
09270:                            .get(qualifiedGroupName);
09271:                    if (gInfo != null)
09272:                        return gInfo;
09273:                } catch (ClassCastException c) {
09274:                }
09275:
09276:                // ------------------------------------
09277:                // if we're here then we're traversing a top-level group that we've never seen before.
09278:
09279:                int index = -2;
09280:                int savedScope = fCurrentScope;
09281:                if (DEBUG_NEW_GROUP)
09282:                    fCurrentScope = fScopeCount++;
09283:
09284:                boolean illegalChild = false;
09285:                String childName = (child != null) ? child.getLocalName() : "";
09286:                if (childName.equals(SchemaSymbols.ELT_ALL)) {
09287:                    index = traverseAll(child);
09288:                } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
09289:                    index = traverseChoice(child);
09290:                } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
09291:                    index = traverseSequence(child);
09292:                } else if (childName.length() != 0
09293:                        || (child != null && XUtil.getNextSiblingElement(child) != null)) {
09294:                    illegalChild = true;
09295:                    reportSchemaError(
09296:                            SchemaMessageProvider.GroupContentRestricted,
09297:                            new Object[] { "group", childName });
09298:                }
09299:                if (!illegalChild && child != null) {
09300:                    index = handleOccurrences(index, child);
09301:                }
09302:
09303:                gInfo = new GroupInfo();
09304:                gInfo.contentSpecIndex = index;
09305:                gInfo.scope = fCurrentScope;
09306:                fCurrentScope = savedScope;
09307:                fGroupNameRegistry.put(qualifiedGroupName, gInfo);
09308:                fNamespacesScope = saveNSMapping;
09309:                fTargetNSURI = saveTargetNSUri;
09310:                return gInfo;
09311:
09312:            } // end of method traverseGroupDeclFromAnotherSchema
09313:
09314:            /**
09315:             *
09316:             * Traverse the Sequence declaration
09317:             *
09318:             * <sequence
09319:             *   id = ID
09320:             *   maxOccurs = string
09321:             *   minOccurs = nonNegativeInteger>
09322:             *   Content: (annotation? , (element | group | choice | sequence | any)*)
09323:             * </sequence>
09324:             *
09325:             **/
09326:            int traverseSequence(Element sequenceDecl) throws Exception {
09327:                // General Attribute Checking
09328:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
09329:                Hashtable attrValues = generalCheck(sequenceDecl, scope);
09330:
09331:                Element child = checkContent(sequenceDecl, XUtil
09332:                        .getFirstChildElement(sequenceDecl), true);
09333:
09334:                int csnType = XMLContentSpec.CONTENTSPECNODE_SEQ;
09335:
09336:                int left = -2;
09337:                int right = -2;
09338:                boolean hadContent = false;
09339:
09340:                for (; child != null; child = XUtil
09341:                        .getNextSiblingElement(child)) {
09342:                    int index = -2;
09343:
09344:                    boolean seeParticle = false;
09345:                    String childName = child.getLocalName();
09346:                    if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
09347:                        QName eltQName = traverseElementDecl(child);
09348:                        index = fSchemaGrammar.addContentSpecNode(
09349:                                XMLContentSpec.CONTENTSPECNODE_LEAF,
09350:                                eltQName.localpart, eltQName.uri, false);
09351:                        seeParticle = true;
09352:
09353:                    } else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
09354:                        GroupInfo grpInfo = traverseGroupDecl(child);
09355:                        index = (grpInfo != null) ? grpInfo.contentSpecIndex
09356:                                : -2;
09357:
09358:                        // A content type of all can only appear
09359:                        // as the content type of a complex type definition.
09360:                        if (hasAllContent(index)) {
09361:                            reportSchemaError(
09362:                                    SchemaMessageProvider.AllContentLimited,
09363:                                    new Object[] { "sequence" });
09364:                            continue;
09365:                        }
09366:
09367:                        seeParticle = true;
09368:
09369:                    } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
09370:                        index = traverseChoice(child);
09371:                        seeParticle = true;
09372:
09373:                    } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
09374:                        index = traverseSequence(child);
09375:                        seeParticle = true;
09376:
09377:                    } else if (childName.equals(SchemaSymbols.ELT_ANY)) {
09378:                        index = traverseAny(child);
09379:                        seeParticle = true;
09380:                    } else {
09381:                        reportSchemaError(
09382:                                SchemaMessageProvider.SeqChoiceContentRestricted,
09383:                                new Object[] { "sequence", childName });
09384:                        continue;
09385:                    }
09386:
09387:                    if (index != -2)
09388:                        hadContent = true;
09389:
09390:                    if (seeParticle) {
09391:                        index = handleOccurrences(index, child);
09392:                    }
09393:                    if (left == -2) {
09394:                        left = index;
09395:                    } else if (right == -2) {
09396:                        right = index;
09397:                    } else {
09398:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09399:                                right, false);
09400:                        right = index;
09401:                    }
09402:                }
09403:
09404:                if (hadContent) {
09405:                    if (right != -2
09406:                            || fSchemaGrammar.getDeferContentSpecExpansion())
09407:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09408:                                right, false);
09409:                }
09410:
09411:                return left;
09412:            }
09413:
09414:            /**
09415:             *
09416:             * Traverse the Choice declaration
09417:             *
09418:             * <choice
09419:             *   id = ID
09420:             *   maxOccurs = string
09421:             *   minOccurs = nonNegativeInteger>
09422:             *   Content: (annotation? , (element | group | choice | sequence | any)*)
09423:             * </choice>
09424:             *
09425:             **/
09426:            int traverseChoice(Element choiceDecl) throws Exception {
09427:                // General Attribute Checking
09428:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
09429:                Hashtable attrValues = generalCheck(choiceDecl, scope);
09430:
09431:                // REVISIT: traverseChoice, traverseSequence can be combined
09432:                Element child = checkContent(choiceDecl, XUtil
09433:                        .getFirstChildElement(choiceDecl), true);
09434:
09435:                int csnType = XMLContentSpec.CONTENTSPECNODE_CHOICE;
09436:
09437:                int left = -2;
09438:                int right = -2;
09439:                boolean hadContent = false;
09440:
09441:                for (; child != null; child = XUtil
09442:                        .getNextSiblingElement(child)) {
09443:                    int index = -2;
09444:
09445:                    boolean seeParticle = false;
09446:                    String childName = child.getLocalName();
09447:                    if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
09448:                        QName eltQName = traverseElementDecl(child);
09449:                        index = fSchemaGrammar.addContentSpecNode(
09450:                                XMLContentSpec.CONTENTSPECNODE_LEAF,
09451:                                eltQName.localpart, eltQName.uri, false);
09452:                        seeParticle = true;
09453:
09454:                    } else if (childName.equals(SchemaSymbols.ELT_GROUP)) {
09455:                        GroupInfo grpInfo = traverseGroupDecl(child);
09456:                        index = (grpInfo != null) ? grpInfo.contentSpecIndex
09457:                                : -2;
09458:
09459:                        // A model group whose {compositor} is "all" can only appear
09460:                        // as the {content type} of a complex type definition.
09461:                        if (hasAllContent(index)) {
09462:                            reportSchemaError(
09463:                                    SchemaMessageProvider.AllContentLimited,
09464:                                    new Object[] { "choice" });
09465:                            continue;
09466:                        }
09467:
09468:                        seeParticle = true;
09469:
09470:                    } else if (childName.equals(SchemaSymbols.ELT_CHOICE)) {
09471:                        index = traverseChoice(child);
09472:                        seeParticle = true;
09473:
09474:                    } else if (childName.equals(SchemaSymbols.ELT_SEQUENCE)) {
09475:                        index = traverseSequence(child);
09476:                        seeParticle = true;
09477:
09478:                    } else if (childName.equals(SchemaSymbols.ELT_ANY)) {
09479:                        index = traverseAny(child);
09480:                        seeParticle = true;
09481:                    } else {
09482:                        reportSchemaError(
09483:                                SchemaMessageProvider.SeqChoiceContentRestricted,
09484:                                new Object[] { "choice", childName });
09485:                        continue;
09486:                    }
09487:
09488:                    if (index != -2)
09489:                        hadContent = true;
09490:
09491:                    if (seeParticle) {
09492:                        index = handleOccurrences(index, child);
09493:                    }
09494:
09495:                    if (left == -2) {
09496:                        left = index;
09497:                    } else if (right == -2) {
09498:                        right = index;
09499:                    } else {
09500:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09501:                                right, false);
09502:                        right = index;
09503:                    }
09504:                }
09505:
09506:                if (hadContent) {
09507:                    if (right != -2
09508:                            || fSchemaGrammar.getDeferContentSpecExpansion())
09509:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09510:                                right, false);
09511:                }
09512:                return left;
09513:            }
09514:
09515:            /**
09516:             *
09517:             * Traverse the "All" declaration
09518:             *
09519:             * <all
09520:             *   id = ID
09521:             *   maxOccurs = 1 : 1
09522:             *   minOccurs = (0 | 1) : 1>
09523:             *   Content: (annotation? , element*)
09524:             * </all>
09525:             **/
09526:
09527:            int traverseAll(Element allDecl) throws Exception {
09528:                // General Attribute Checking
09529:                int scope = GeneralAttrCheck.ELE_CONTEXT_LOCAL;
09530:                Hashtable attrValues = generalCheck(allDecl, scope);
09531:
09532:                Element child = checkContent(allDecl, XUtil
09533:                        .getFirstChildElement(allDecl), true);
09534:
09535:                int csnType = XMLContentSpec.CONTENTSPECNODE_ALL;
09536:
09537:                int left = -2;
09538:                int right = -2;
09539:                boolean hadContent = false;
09540:
09541:                for (; child != null; child = XUtil
09542:                        .getNextSiblingElement(child)) {
09543:                    int index = -2;
09544:
09545:                    String childName = child.getLocalName();
09546:
09547:                    // Only elements are allowed in <all>
09548:                    if (childName.equals(SchemaSymbols.ELT_ELEMENT)) {
09549:                        QName eltQName = traverseElementDecl(child);
09550:                        index = fSchemaGrammar.addContentSpecNode(
09551:                                XMLContentSpec.CONTENTSPECNODE_LEAF,
09552:                                eltQName.localpart, eltQName.uri, false);
09553:
09554:                        index = handleOccurrences(index, child,
09555:                                PROCESSING_ALL_EL);
09556:                    } else {
09557:                        reportSchemaError(
09558:                                SchemaMessageProvider.AllContentRestricted,
09559:                                new Object[] { childName });
09560:                        continue;
09561:                    }
09562:
09563:                    hadContent = true;
09564:
09565:                    if (left == -2) {
09566:                        left = index;
09567:                    } else if (right == -2) {
09568:                        right = index;
09569:                    } else {
09570:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09571:                                right, false);
09572:                        right = index;
09573:                    }
09574:                }
09575:
09576:                if (hadContent) {
09577:                    if (right != -2
09578:                            || fSchemaGrammar.getDeferContentSpecExpansion())
09579:                        left = fSchemaGrammar.addContentSpecNode(csnType, left,
09580:                                right, false);
09581:                }
09582:
09583:                return left;
09584:            }
09585:
09586:            // Determines whether a content spec tree represents an "all" content model
09587:            private boolean hasAllContent(int contentSpecIndex) {
09588:                // If the content is not empty, is the top node ALL?
09589:                if (contentSpecIndex > -1) {
09590:                    XMLContentSpec content = new XMLContentSpec();
09591:                    fSchemaGrammar.getContentSpec(contentSpecIndex, content);
09592:
09593:                    // An ALL node could be optional, so we have to be prepared
09594:                    // to look one level below a ZERO_OR_ONE node for an ALL.
09595:                    if (content.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
09596:                        fSchemaGrammar.getContentSpec(content.value, content);
09597:                    }
09598:
09599:                    return (content.type == XMLContentSpec.CONTENTSPECNODE_ALL);
09600:                }
09601:
09602:                return false;
09603:            }
09604:
09605:            // check the prefix of each element: must be SchemaForSchema
09606:            // general constrain checking on attriubtes
09607:            private Hashtable generalCheck(Element element, int scope)
09608:                    throws Exception {
09609:                String uri = element.getNamespaceURI();
09610:                if (uri == null
09611:                        || !uri.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) {
09612:                    reportGenericSchemaError("The namespce name for '"
09613:                            + element.getLocalName() + "' must be "
09614:                            + SchemaSymbols.URI_SCHEMAFORSCHEMA);
09615:                }
09616:                return fGeneralAttrCheck.checkAttributes(element, scope);
09617:            }
09618:
09619:            // utilities from Tom Watson's SchemaParser class
09620:            // TO DO: Need to make this more conformant with Schema int type parsing
09621:
09622:            private int parseInt(String intString) throws Exception {
09623:                if (intString.equals("*")) {
09624:                    return SchemaSymbols.INFINITY;
09625:                } else {
09626:                    return Integer.parseInt(intString);
09627:                }
09628:            }
09629:
09630:            private int parseSimpleFinal(String finalString) throws Exception {
09631:                if (finalString.equals(SchemaSymbols.ATTVAL_POUNDALL)) {
09632:                    return SchemaSymbols.ENUMERATION
09633:                            + SchemaSymbols.RESTRICTION + SchemaSymbols.LIST;
09634:                } else {
09635:                    int enumerate = 0;
09636:                    int restrict = 0;
09637:                    int list = 0;
09638:
09639:                    StringTokenizer t = new StringTokenizer(finalString, " ");
09640:                    while (t.hasMoreTokens()) {
09641:                        String token = t.nextToken();
09642:
09643:                        if (token.equals(SchemaSymbols.ATTVAL_RESTRICTION)) {
09644:                            if (restrict == 0) {
09645:                                restrict = SchemaSymbols.RESTRICTION;
09646:                            } else {
09647:                                // REVISIT: Localize
09648:                                reportGenericSchemaError("restriction in set twice");
09649:                            }
09650:                        } else if (token.equals(SchemaSymbols.ELT_LIST)) {
09651:                            if (list == 0) {
09652:                                list = SchemaSymbols.LIST;
09653:                            } else {
09654:                                // REVISIT: Localize
09655:                                reportGenericSchemaError("list in set twice");
09656:                            }
09657:                        } else {
09658:                            // REVISIT: Localize
09659:                            reportGenericSchemaError("Invalid value ("
09660:                                    + finalString + ")");
09661:                        }
09662:                    }
09663:
09664:                    return enumerate + list;
09665:                }
09666:            }
09667:
09668:            private int parseDerivationSet(String finalString) throws Exception {
09669:                if (finalString.equals(SchemaSymbols.ATTVAL_POUNDALL)) {
09670:                    return SchemaSymbols.EXTENSION + SchemaSymbols.RESTRICTION;
09671:                } else {
09672:                    int extend = 0;
09673:                    int restrict = 0;
09674:
09675:                    StringTokenizer t = new StringTokenizer(finalString, " ");
09676:                    while (t.hasMoreTokens()) {
09677:                        String token = t.nextToken();
09678:
09679:                        if (token.equals(SchemaSymbols.ATTVAL_EXTENSION)) {
09680:                            if (extend == 0) {
09681:                                extend = SchemaSymbols.EXTENSION;
09682:                            } else {
09683:                                // REVISIT: Localize
09684:                                reportGenericSchemaError("extension already in set");
09685:                            }
09686:                        } else if (token
09687:                                .equals(SchemaSymbols.ATTVAL_RESTRICTION)) {
09688:                            if (restrict == 0) {
09689:                                restrict = SchemaSymbols.RESTRICTION;
09690:                            } else {
09691:                                // REVISIT: Localize
09692:                                reportGenericSchemaError("restriction already in set");
09693:                            }
09694:                        } else {
09695:                            // REVISIT: Localize
09696:                            reportGenericSchemaError("Invalid final value ("
09697:                                    + finalString + ")");
09698:                        }
09699:                    }
09700:
09701:                    return extend + restrict;
09702:                }
09703:            }
09704:
09705:            private int parseBlockSet(String blockString) throws Exception {
09706:                if (blockString == null)
09707:                    return fBlockDefault;
09708:                else if (blockString.equals(SchemaSymbols.ATTVAL_POUNDALL)) {
09709:                    return SchemaSymbols.SUBSTITUTION + SchemaSymbols.EXTENSION
09710:                            + SchemaSymbols.RESTRICTION;
09711:                } else {
09712:                    int extend = 0;
09713:                    int restrict = 0;
09714:                    int substitute = 0;
09715:
09716:                    StringTokenizer t = new StringTokenizer(blockString, " ");
09717:                    while (t.hasMoreTokens()) {
09718:                        String token = t.nextToken();
09719:
09720:                        if (token.equals(SchemaSymbols.ATTVAL_SUBSTITUTION)) {
09721:                            if (substitute == 0) {
09722:                                substitute = SchemaSymbols.SUBSTITUTION;
09723:                            } else {
09724:                                // REVISIT: Localize
09725:                                reportGenericSchemaError("The value 'substitution' already in the list");
09726:                            }
09727:                        } else if (token.equals(SchemaSymbols.ATTVAL_EXTENSION)) {
09728:                            if (extend == 0) {
09729:                                extend = SchemaSymbols.EXTENSION;
09730:                            } else {
09731:                                // REVISIT: Localize
09732:                                reportGenericSchemaError("The value 'extension' is already in the list");
09733:                            }
09734:                        } else if (token
09735:                                .equals(SchemaSymbols.ATTVAL_RESTRICTION)) {
09736:                            if (restrict == 0) {
09737:                                restrict = SchemaSymbols.RESTRICTION;
09738:                            } else {
09739:                                // REVISIT: Localize
09740:                                reportGenericSchemaError("The value 'restriction' is already in the list");
09741:                            }
09742:                        } else {
09743:                            // REVISIT: Localize
09744:                            reportGenericSchemaError("Invalid block value ("
09745:                                    + blockString + ")");
09746:                        }
09747:                    }
09748:
09749:                    int defaultVal = extend + restrict + substitute;
09750:                    return (defaultVal == 0 ? fBlockDefault : defaultVal);
09751:                }
09752:            }
09753:
09754:            private int parseFinalSet(String finalString) throws Exception {
09755:                if (finalString == null) {
09756:                    return fFinalDefault;
09757:                } else if (finalString.equals(SchemaSymbols.ATTVAL_POUNDALL)) {
09758:                    return SchemaSymbols.EXTENSION + SchemaSymbols.LIST
09759:                            + SchemaSymbols.RESTRICTION + SchemaSymbols.UNION;
09760:                } else {
09761:                    int extend = 0;
09762:                    int restrict = 0;
09763:                    int list = 0;
09764:                    int union = 0;
09765:
09766:                    StringTokenizer t = new StringTokenizer(finalString, " ");
09767:                    while (t.hasMoreTokens()) {
09768:                        String token = t.nextToken();
09769:
09770:                        if (token.equals(SchemaSymbols.ELT_UNION)) {
09771:                            if (union == 0) {
09772:                                union = SchemaSymbols.UNION;
09773:                            } else {
09774:                                // REVISIT: Localize
09775:                                reportGenericSchemaError("The value 'union' is already in the list");
09776:                            }
09777:                        } else if (token.equals(SchemaSymbols.ATTVAL_EXTENSION)) {
09778:                            if (extend == 0) {
09779:                                extend = SchemaSymbols.EXTENSION;
09780:                            } else {
09781:                                // REVISIT: Localize
09782:                                reportGenericSchemaError("The value 'extension' is already in the list");
09783:                            }
09784:                        } else if (token.equals(SchemaSymbols.ELT_LIST)) {
09785:                            if (list == 0) {
09786:                                list = SchemaSymbols.LIST;
09787:                            } else {
09788:                                // REVISIT: Localize
09789:                                reportGenericSchemaError("The value 'list' is already in the list");
09790:                            }
09791:                        } else if (token
09792:                                .equals(SchemaSymbols.ATTVAL_RESTRICTION)) {
09793:                            if (restrict == 0) {
09794:                                restrict = SchemaSymbols.RESTRICTION;
09795:                            } else {
09796:                                // REVISIT: Localize
09797:                                reportGenericSchemaError("The value 'restriction' is already in the list");
09798:                            }
09799:                        } else {
09800:                            // REVISIT: Localize
09801:                            reportGenericSchemaError("Invalid final value ("
09802:                                    + finalString + ")");
09803:                        }
09804:                    }
09805:
09806:                    int defaultVal = extend + restrict + list + union;
09807:                    return (defaultVal == 0 ? fFinalDefault : defaultVal);
09808:                }
09809:            }
09810:
09811:            private void reportGenericSchemaError(String error)
09812:                    throws Exception {
09813:                if (fErrorReporter == null) {
09814:                    System.err.println("__TraverseSchemaError__ : " + error);
09815:                } else {
09816:                    reportSchemaError(SchemaMessageProvider.GenericError,
09817:                            new Object[] { error });
09818:                }
09819:            }
09820:
09821:            private void reportSchemaError(int major, Object args[])
09822:                    throws Exception {
09823:                if (fErrorReporter == null) {
09824:                    System.out.println("__TraverseSchemaError__ : "
09825:                            + SchemaMessageProvider.fgMessageKeys[major]);
09826:                    for (int i = 0; i < args.length; i++) {
09827:                        System.out.println((String) args[i]);
09828:                    }
09829:                } else {
09830:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
09831:                            SchemaMessageProvider.SCHEMA_DOMAIN, major,
09832:                            SchemaMessageProvider.MSG_NONE, args,
09833:                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
09834:                }
09835:            }
09836:
09837:            /** Don't check the following code in because it creates a dependency on
09838:                the serializer, preventing to package the parser without the serializer
09839:            //Unit Test here
09840:            public static void main(String args[] ) {
09841:
09842:                if( args.length != 1 ) {
09843:                    System.out.println( "Error: Usage java TraverseSchema yourFile.xsd" );
09844:                    System.exit(0);
09845:                }
09846:
09847:                DOMParser parser = new IgnoreWhitespaceParser();
09848:                parser.setEntityResolver( (fEntityResolver != null)? (fEntityResolver):(new Resolver()) );
09849:                parser.setErrorHandler(  new ErrorHandler() );
09850:
09851:                try {
09852:                parser.setFeature("http://xml.org/sax/features/validation", false);
09853:                parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
09854:                }catch(  org.xml.sax.SAXNotRecognizedException e ) {
09855:                    e.printStackTrace();
09856:                }catch( org.xml.sax.SAXNotSupportedException e ) {
09857:                    e.printStackTrace();
09858:                }
09859:
09860:                try {
09861:                parser.parse( args[0]);
09862:                }catch( IOException e ) {
09863:                    e.printStackTrace();
09864:                }catch( SAXException e ) {
09865:                    e.printStackTrace();
09866:                }
09867:
09868:                Document     document   = parser.getDocument(); //Our Grammar
09869:
09870:                OutputFormat    format  = new OutputFormat( document );
09871:                java.io.StringWriter outWriter = new java.io.StringWriter();
09872:                XMLSerializer    serial = new XMLSerializer( outWriter,format);
09873:
09874:                TraverseSchema tst = null;
09875:                try {
09876:                    Element root   = document.getDocumentElement();// This is what we pass to TraverserSchema
09877:                    //serial.serialize( root );
09878:                    //System.out.println(outWriter.toString());
09879:
09880:                    tst = new TraverseSchema( root, new StringPool(), new SchemaGrammar(), (GrammarResolver) new GrammarResolverImpl() );
09881:                    }
09882:                    catch (Exception e) {
09883:                        e.printStackTrace(System.err);
09884:                    }
09885:
09886:                    parser.getDocument();
09887:            }
09888:             **/
09889:
09890:            static class Resolver implements  EntityResolver {
09891:                private static final String SYSTEM[] = {
09892:                        "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/structures.dtd",
09893:                        "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/datatypes.dtd",
09894:                        "http://www.w3.org/TR/2000/WD-xmlschema-1-20000407/versionInfo.ent", };
09895:                private static final String PATH[] = { "structures.dtd",
09896:                        "datatypes.dtd", "versionInfo.ent", };
09897:
09898:                public InputSource resolveEntity(String publicId,
09899:                        String systemId) throws IOException {
09900:
09901:                    // looking for the schema DTDs?
09902:                    for (int i = 0; i < SYSTEM.length; i++) {
09903:                        if (systemId.equals(SYSTEM[i])) {
09904:                            InputSource source = new InputSource(getClass()
09905:                                    .getResourceAsStream(PATH[i]));
09906:                            source.setPublicId(publicId);
09907:                            source.setSystemId(systemId);
09908:                            return source;
09909:                        }
09910:                    }
09911:
09912:                    // use default resolution
09913:                    return null;
09914:
09915:                } // resolveEntity(String,String):InputSource
09916:
09917:            } // class Resolver
09918:
09919:            static class ErrorHandler implements  org.xml.sax.ErrorHandler {
09920:
09921:                /** Warning. */
09922:                public void warning(SAXParseException ex) {
09923:                    System.err.println("[Warning] " + getLocationString(ex)
09924:                            + ": " + ex.getMessage());
09925:                }
09926:
09927:                /** Error. */
09928:                public void error(SAXParseException ex) throws SAXException {
09929:                    System.err.println("[Error] " + getLocationString(ex)
09930:                            + ": " + ex.getMessage());
09931:                }
09932:
09933:                /** Fatal error. */
09934:                public void fatalError(SAXParseException ex)
09935:                        throws SAXException {
09936:                    System.err.println("[Fatal Error] " + getLocationString(ex)
09937:                            + ": " + ex.getMessage());
09938:                    throw ex;
09939:                }
09940:
09941:                //
09942:                // Private methods
09943:                //
09944:
09945:                /** Returns a string of the location. */
09946:                private String getLocationString(SAXParseException ex) {
09947:                    StringBuffer str = new StringBuffer();
09948:
09949:                    String systemId_ = ex.getSystemId();
09950:                    if (systemId_ != null) {
09951:                        int index = systemId_.lastIndexOf('/');
09952:                        if (index != -1)
09953:                            systemId_ = systemId_.substring(index + 1);
09954:                        str.append(systemId_);
09955:                    }
09956:                    str.append(':');
09957:                    str.append(ex.getLineNumber());
09958:                    str.append(':');
09959:                    str.append(ex.getColumnNumber());
09960:
09961:                    return str.toString();
09962:
09963:                } // getLocationString(SAXParseException):String
09964:            }
09965:
09966:            static class IgnoreWhitespaceParser extends DOMParser {
09967:                public void ignorableWhitespace(char ch[], int start, int length) {
09968:                }
09969:
09970:                public void ignorableWhitespace(int dataIdx) {
09971:                }
09972:            } // class IgnoreWhitespaceParser
09973:
09974:            // When in a <redefine>, type definitions being used (and indeed
09975:            // refs to <group>'s and <attributeGroup>'s) may refer to info
09976:            // items either in the schema being redefined, in the <redefine>,
09977:            // or else in the schema doing the redefining.  Because of this
09978:            // latter we have to be prepared sometimes to look for our type
09979:            // definitions outside the schema stored in fSchemaRootElement.
09980:            // This simple class does this; it's just a linked list that
09981:            // lets us look at the <schema>'s on the queue; note also that this
09982:            // should provide us with a mechanism to handle nested <redefine>'s.
09983:            // It's also a handy way of saving schema info when importing/including; saves some code.
09984:            public class SchemaInfo {
09985:                private Element saveRoot;
09986:                private SchemaInfo nextRoot;
09987:                private SchemaInfo prevRoot;
09988:                private String savedSchemaURL = fCurrentSchemaURL;
09989:                private boolean saveElementDefaultQualified = fElementDefaultQualified;
09990:                private boolean saveAttributeDefaultQualified = fAttributeDefaultQualified;
09991:                private int saveBlockDefault = fBlockDefault;
09992:                private int saveFinalDefault = fFinalDefault;
09993:                private NamespacesScope saveNamespacesScope = fNamespacesScope;
09994:
09995:                public SchemaInfo(boolean saveElementDefaultQualified,
09996:                        boolean saveAttributeDefaultQualified,
09997:                        int saveBlockDefault, int saveFinalDefault,
09998:                        String savedSchemaURL, Element saveRoot,
09999:                        NamespacesScope saveNamespacesScope,
10000:                        SchemaInfo nextRoot, SchemaInfo prevRoot) {
10001:                    this .saveElementDefaultQualified = saveElementDefaultQualified;
10002:                    this .saveAttributeDefaultQualified = saveAttributeDefaultQualified;
10003:                    this .saveBlockDefault = saveBlockDefault;
10004:                    this .saveFinalDefault = saveFinalDefault;
10005:                    this .savedSchemaURL = savedSchemaURL;
10006:                    this .saveRoot = saveRoot;
10007:                    if (saveNamespacesScope != null)
10008:                        this .saveNamespacesScope = (NamespacesScope) saveNamespacesScope
10009:                                .clone();
10010:                    this .nextRoot = nextRoot;
10011:                    this .prevRoot = prevRoot;
10012:                }
10013:
10014:                public void setNext(SchemaInfo next) {
10015:                    nextRoot = next;
10016:                }
10017:
10018:                public SchemaInfo getNext() {
10019:                    return nextRoot;
10020:                }
10021:
10022:                public void setPrev(SchemaInfo prev) {
10023:                    prevRoot = prev;
10024:                }
10025:
10026:                public String getCurrentSchemaURL() {
10027:                    return savedSchemaURL;
10028:                }
10029:
10030:                public SchemaInfo getPrev() {
10031:                    return prevRoot;
10032:                }
10033:
10034:                public Element getRoot() {
10035:                    return saveRoot;
10036:                }
10037:
10038:                // NOTE:  this has side-effects!!!
10039:                public void restore() {
10040:                    fCurrentSchemaURL = savedSchemaURL;
10041:                    fElementDefaultQualified = saveElementDefaultQualified;
10042:                    fAttributeDefaultQualified = saveAttributeDefaultQualified;
10043:                    fBlockDefault = saveBlockDefault;
10044:                    fFinalDefault = saveFinalDefault;
10045:                    fNamespacesScope = (NamespacesScope) saveNamespacesScope
10046:                            .clone();
10047:                    fSchemaRootElement = saveRoot;
10048:                }
10049:            } // class SchemaInfo
10050:
10051:        } // class TraverseSchema
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.