Source Code Cross Referenced for XSConstraints.java in  » XML » xerces-2_9_1 » org » apache » xerces » impl » xs » 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 » XML » xerces 2_9_1 » org.apache.xerces.impl.xs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.xerces.impl.xs;
0019:
0020:        import org.apache.xerces.impl.dv.XSSimpleType;
0021:        import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
0022:        import org.apache.xerces.impl.dv.ValidatedInfo;
0023:        import org.apache.xerces.impl.XMLErrorReporter;
0024:        import org.apache.xerces.impl.xs.models.CMBuilder;
0025:        import org.apache.xerces.impl.xs.models.XSCMValidator;
0026:        import org.apache.xerces.impl.xs.util.SimpleLocator;
0027:        import org.apache.xerces.xs.XSConstants;
0028:        import org.apache.xerces.xs.XSObjectList;
0029:        import org.apache.xerces.xs.XSTypeDefinition;
0030:        import org.apache.xerces.impl.dv.ValidationContext;
0031:        import org.apache.xerces.util.SymbolHash;
0032:
0033:        import java.util.Collections;
0034:        import java.util.Comparator;
0035:        import java.util.Vector;
0036:
0037:        /**
0038:         * Constraints shared by traversers and validator
0039:         * 
0040:         * @xerces.internal
0041:         *
0042:         * @author Sandy Gao, IBM
0043:         *
0044:         * @version $Id: XSConstraints.java 573322 2007-09-06 16:48:47Z peterjm $
0045:         */
0046:        public class XSConstraints {
0047:
0048:            // IHR: Visited on 2006-11-17
0049:            // Added a boolean return value to particleValidRestriction (it was a void function)
0050:            // to help the checkRecurseLax to know when expansion has happened and no order is required
0051:            // (IHR@xbrl.org) (Ignacio@Hernandez-Ros.com)
0052:
0053:            static final int OCCURRENCE_UNKNOWN = SchemaSymbols.OCCURRENCE_UNBOUNDED - 1;
0054:            static final XSSimpleType STRING_TYPE = (XSSimpleType) SchemaGrammar.SG_SchemaNS
0055:                    .getGlobalTypeDecl(SchemaSymbols.ATTVAL_STRING);
0056:
0057:            private static final Comparator ELEMENT_PARTICLE_COMPARATOR = new Comparator() {
0058:
0059:                public int compare(Object o1, Object o2) {
0060:                    XSParticleDecl pDecl1 = (XSParticleDecl) o1;
0061:                    XSParticleDecl pDecl2 = (XSParticleDecl) o2;
0062:                    XSElementDecl decl1 = (XSElementDecl) pDecl1.fValue;
0063:                    XSElementDecl decl2 = (XSElementDecl) pDecl2.fValue;
0064:
0065:                    String namespace1 = decl1.getNamespace();
0066:                    String namespace2 = decl2.getNamespace();
0067:                    String name1 = decl1.getName();
0068:                    String name2 = decl2.getName();
0069:
0070:                    boolean sameNamespace = (namespace1 == namespace2);
0071:                    int namespaceComparison = 0;
0072:
0073:                    if (!sameNamespace) {
0074:                        if (namespace1 != null) {
0075:                            if (namespace2 != null) {
0076:                                namespaceComparison = namespace1
0077:                                        .compareTo(namespace2);
0078:                            } else {
0079:                                namespaceComparison = 1;
0080:                            }
0081:                        } else {
0082:                            namespaceComparison = -1;
0083:                        }
0084:                    }
0085:                    //This assumes that the names are never null.
0086:                    return namespaceComparison != 0 ? namespaceComparison
0087:                            : name1.compareTo(name2);
0088:                }
0089:            };
0090:
0091:            /**
0092:             * check whether derived is valid derived from base, given a subset
0093:             * of {restriction, extension}.B
0094:             */
0095:            public static boolean checkTypeDerivationOk(
0096:                    XSTypeDefinition derived, XSTypeDefinition base, short block) {
0097:                // if derived is anyType, then it's valid only if base is anyType too
0098:                if (derived == SchemaGrammar.fAnyType)
0099:                    return derived == base;
0100:                // if derived is anySimpleType, then it's valid only if the base
0101:                // is ur-type
0102:                if (derived == SchemaGrammar.fAnySimpleType) {
0103:                    return (base == SchemaGrammar.fAnyType || base == SchemaGrammar.fAnySimpleType);
0104:                }
0105:
0106:                // if derived is simple type
0107:                if (derived.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
0108:                    // if base is complex type
0109:                    if (base.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
0110:                        // if base is anyType, change base to anySimpleType,
0111:                        // otherwise, not valid
0112:                        if (base == SchemaGrammar.fAnyType)
0113:                            base = SchemaGrammar.fAnySimpleType;
0114:                        else
0115:                            return false;
0116:                    }
0117:                    return checkSimpleDerivation((XSSimpleType) derived,
0118:                            (XSSimpleType) base, block);
0119:                } else {
0120:                    return checkComplexDerivation((XSComplexTypeDecl) derived,
0121:                            base, block);
0122:                }
0123:            }
0124:
0125:            /**
0126:             * check whether simple type derived is valid derived from base,
0127:             * given a subset of {restriction, extension}.
0128:             */
0129:            public static boolean checkSimpleDerivationOk(XSSimpleType derived,
0130:                    XSTypeDefinition base, short block) {
0131:                // if derived is anySimpleType, then it's valid only if the base
0132:                // is ur-type
0133:                if (derived == SchemaGrammar.fAnySimpleType) {
0134:                    return (base == SchemaGrammar.fAnyType || base == SchemaGrammar.fAnySimpleType);
0135:                }
0136:
0137:                // if base is complex type
0138:                if (base.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
0139:                    // if base is anyType, change base to anySimpleType,
0140:                    // otherwise, not valid
0141:                    if (base == SchemaGrammar.fAnyType)
0142:                        base = SchemaGrammar.fAnySimpleType;
0143:                    else
0144:                        return false;
0145:                }
0146:                return checkSimpleDerivation((XSSimpleType) derived,
0147:                        (XSSimpleType) base, block);
0148:            }
0149:
0150:            /**
0151:             * check whether complex type derived is valid derived from base,
0152:             * given a subset of {restriction, extension}.
0153:             */
0154:            public static boolean checkComplexDerivationOk(
0155:                    XSComplexTypeDecl derived, XSTypeDefinition base,
0156:                    short block) {
0157:                // if derived is anyType, then it's valid only if base is anyType too
0158:                if (derived == SchemaGrammar.fAnyType)
0159:                    return derived == base;
0160:                return checkComplexDerivation((XSComplexTypeDecl) derived,
0161:                        base, block);
0162:            }
0163:
0164:            /**
0165:             * Note: this will be a private method, and it assumes that derived is not
0166:             *       anySimpleType, and base is not anyType. Another method will be
0167:             *       introduced for public use, which will call this method.
0168:             */
0169:            private static boolean checkSimpleDerivation(XSSimpleType derived,
0170:                    XSSimpleType base, short block) {
0171:                // 1 They are the same type definition.
0172:                if (derived == base)
0173:                    return true;
0174:
0175:                // 2 All of the following must be true:
0176:                // 2.1 restriction is not in the subset, or in the {final} of its own {base type definition};
0177:                if ((block & XSConstants.DERIVATION_RESTRICTION) != 0
0178:                        || (derived.getBaseType().getFinal() & XSConstants.DERIVATION_RESTRICTION) != 0) {
0179:                    return false;
0180:                }
0181:
0182:                // 2.2 One of the following must be true:
0183:                // 2.2.1 D's base type definition is B.
0184:                XSSimpleType directBase = (XSSimpleType) derived.getBaseType();
0185:                if (directBase == base)
0186:                    return true;
0187:
0188:                // 2.2.2 D's base type definition is not the simple ur-type definition and is validly derived from B given the subset, as defined by this constraint.
0189:                if (directBase != SchemaGrammar.fAnySimpleType
0190:                        && checkSimpleDerivation(directBase, base, block)) {
0191:                    return true;
0192:                }
0193:
0194:                // 2.2.3 D's {variety} is list or union and B is the simple ur-type definition.
0195:                if ((derived.getVariety() == XSSimpleType.VARIETY_LIST || derived
0196:                        .getVariety() == XSSimpleType.VARIETY_UNION)
0197:                        && base == SchemaGrammar.fAnySimpleType) {
0198:                    return true;
0199:                }
0200:
0201:                // 2.2.4 B's {variety} is union and D is validly derived from a type definition in B's {member type definitions} given the subset, as defined by this constraint.
0202:                if (base.getVariety() == XSSimpleType.VARIETY_UNION) {
0203:                    XSObjectList subUnionMemberDV = base.getMemberTypes();
0204:                    int subUnionSize = subUnionMemberDV.getLength();
0205:                    for (int i = 0; i < subUnionSize; i++) {
0206:                        base = (XSSimpleType) subUnionMemberDV.item(i);
0207:                        if (checkSimpleDerivation(derived, base, block))
0208:                            return true;
0209:                    }
0210:                }
0211:
0212:                return false;
0213:            }
0214:
0215:            /**
0216:             * Note: this will be a private method, and it assumes that derived is not
0217:             *       anyType. Another method will be introduced for public use,
0218:             *       which will call this method.
0219:             */
0220:            private static boolean checkComplexDerivation(
0221:                    XSComplexTypeDecl derived, XSTypeDefinition base,
0222:                    short block) {
0223:                // 2.1 B and D must be the same type definition.
0224:                if (derived == base)
0225:                    return true;
0226:
0227:                // 1 If B and D are not the same type definition, then the {derivation method} of D must not be in the subset.
0228:                if ((derived.fDerivedBy & block) != 0)
0229:                    return false;
0230:
0231:                // 2 One of the following must be true:
0232:                XSTypeDefinition directBase = derived.fBaseType;
0233:                // 2.2 B must be D's {base type definition}.
0234:                if (directBase == base)
0235:                    return true;
0236:
0237:                // 2.3 All of the following must be true:
0238:                // 2.3.1 D's {base type definition} must not be the ur-type definition.
0239:                if (directBase == SchemaGrammar.fAnyType
0240:                        || directBase == SchemaGrammar.fAnySimpleType) {
0241:                    return false;
0242:                }
0243:
0244:                // 2.3.2 The appropriate case among the following must be true:
0245:                // 2.3.2.1 If D's {base type definition} is complex, then it must be validly derived from B given the subset as defined by this constraint.
0246:                if (directBase.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE)
0247:                    return checkComplexDerivation(
0248:                            (XSComplexTypeDecl) directBase, base, block);
0249:
0250:                // 2.3.2.2 If D's {base type definition} is simple, then it must be validly derived from B given the subset as defined in Type Derivation OK (Simple) (3.14.6).
0251:                if (directBase.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
0252:                    // if base is complex type
0253:                    if (base.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
0254:                        // if base is anyType, change base to anySimpleType,
0255:                        // otherwise, not valid
0256:                        if (base == SchemaGrammar.fAnyType)
0257:                            base = SchemaGrammar.fAnySimpleType;
0258:                        else
0259:                            return false;
0260:                    }
0261:                    return checkSimpleDerivation((XSSimpleType) directBase,
0262:                            (XSSimpleType) base, block);
0263:                }
0264:
0265:                return false;
0266:            }
0267:
0268:            /**
0269:             * check whether a value is a valid default for some type
0270:             * returns the compiled form of the value
0271:             * The parameter value could be either a String or a ValidatedInfo object
0272:             */
0273:            public static Object ElementDefaultValidImmediate(
0274:                    XSTypeDefinition type, String value,
0275:                    ValidationContext context, ValidatedInfo vinfo) {
0276:
0277:                XSSimpleType dv = null;
0278:
0279:                // e-props-correct
0280:                // For a string to be a valid default with respect to a type definition the appropriate case among the following must be true:
0281:                // 1 If the type definition is a simple type definition, then the string must be valid with respect to that definition as defined by String Valid (3.14.4).
0282:                if (type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
0283:                    dv = (XSSimpleType) type;
0284:                }
0285:
0286:                // 2 If the type definition is a complex type definition, then all of the following must be true:
0287:                else {
0288:                    // 2.1 its {content type} must be a simple type definition or mixed.
0289:                    XSComplexTypeDecl ctype = (XSComplexTypeDecl) type;
0290:                    // 2.2 The appropriate case among the following must be true:
0291:                    // 2.2.1 If the {content type} is a simple type definition, then the string must be valid with respect to that simple type definition as defined by String Valid (3.14.4).
0292:                    if (ctype.fContentType == XSComplexTypeDecl.CONTENTTYPE_SIMPLE) {
0293:                        dv = ctype.fXSSimpleType;
0294:                    }
0295:                    // 2.2.2 If the {content type} is mixed, then the {content type}'s particle must be emptiable as defined by Particle Emptiable (3.9.6).
0296:                    else if (ctype.fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED) {
0297:                        if (!((XSParticleDecl) ctype.getParticle()).emptiable())
0298:                            return null;
0299:                    } else {
0300:                        return null;
0301:                    }
0302:                }
0303:
0304:                // get the simple type declaration, and validate
0305:                Object actualValue = null;
0306:                if (dv == null) {
0307:                    // complex type with mixed. to make sure that we store correct
0308:                    // information in vinfo and return the correct value, we use
0309:                    // "string" type for validation
0310:                    dv = STRING_TYPE;
0311:                }
0312:                try {
0313:                    // validate the original lexical rep, and set the actual value
0314:                    actualValue = dv.validate(value, context, vinfo);
0315:                    // validate the canonical lexical rep
0316:                    if (vinfo != null)
0317:                        actualValue = dv.validate(vinfo.stringValue(), context,
0318:                                vinfo);
0319:                } catch (InvalidDatatypeValueException ide) {
0320:                    return null;
0321:                }
0322:
0323:                return actualValue;
0324:            }
0325:
0326:            static void reportSchemaError(XMLErrorReporter errorReporter,
0327:                    SimpleLocator loc, String key, Object[] args) {
0328:                if (loc != null) {
0329:                    errorReporter.reportError(loc,
0330:                            XSMessageFormatter.SCHEMA_DOMAIN, key, args,
0331:                            XMLErrorReporter.SEVERITY_ERROR);
0332:                } else {
0333:                    errorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
0334:                            key, args, XMLErrorReporter.SEVERITY_ERROR);
0335:                }
0336:            }
0337:
0338:            /**
0339:             * used to check the 3 constraints against each complex type
0340:             * (should be each model group):
0341:             * Unique Particle Attribution, Particle Derivation (Restriction),
0342:             * Element Declrations Consistent.
0343:             */
0344:            public static void fullSchemaChecking(
0345:                    XSGrammarBucket grammarBucket,
0346:                    SubstitutionGroupHandler SGHandler, CMBuilder cmBuilder,
0347:                    XMLErrorReporter errorReporter) {
0348:                // get all grammars, and put all substitution group information
0349:                // in the substitution group handler
0350:                SchemaGrammar[] grammars = grammarBucket.getGrammars();
0351:                for (int i = grammars.length - 1; i >= 0; i--) {
0352:                    SGHandler.addSubstitutionGroup(grammars[i]
0353:                            .getSubstitutionGroups());
0354:                }
0355:
0356:                XSParticleDecl fakeDerived = new XSParticleDecl();
0357:                XSParticleDecl fakeBase = new XSParticleDecl();
0358:                fakeDerived.fType = XSParticleDecl.PARTICLE_MODELGROUP;
0359:                fakeBase.fType = XSParticleDecl.PARTICLE_MODELGROUP;
0360:                // before worrying about complexTypes, let's get
0361:                // groups redefined by restriction out of the way.
0362:                for (int g = grammars.length - 1; g >= 0; g--) {
0363:                    XSGroupDecl[] redefinedGroups = grammars[g]
0364:                            .getRedefinedGroupDecls();
0365:                    SimpleLocator[] rgLocators = grammars[g].getRGLocators();
0366:                    for (int i = 0; i < redefinedGroups.length;) {
0367:                        XSGroupDecl derivedGrp = redefinedGroups[i++];
0368:                        XSModelGroupImpl derivedMG = derivedGrp.fModelGroup;
0369:                        XSGroupDecl baseGrp = redefinedGroups[i++];
0370:                        XSModelGroupImpl baseMG = baseGrp.fModelGroup;
0371:                        if (baseMG == null) {
0372:                            if (derivedMG != null) { // can't be a restriction!
0373:                                reportSchemaError(errorReporter,
0374:                                        rgLocators[i / 2 - 1],
0375:                                        "src-redefine.6.2.2", new Object[] {
0376:                                                derivedGrp.fName,
0377:                                                "rcase-Recurse.2" });
0378:                            }
0379:                        } else {
0380:                            fakeDerived.fValue = derivedMG;
0381:                            fakeBase.fValue = baseMG;
0382:                            try {
0383:                                particleValidRestriction(fakeDerived,
0384:                                        SGHandler, fakeBase, SGHandler);
0385:                            } catch (XMLSchemaException e) {
0386:                                String key = e.getKey();
0387:                                reportSchemaError(errorReporter,
0388:                                        rgLocators[i / 2 - 1], key, e.getArgs());
0389:                                reportSchemaError(errorReporter,
0390:                                        rgLocators[i / 2 - 1],
0391:                                        "src-redefine.6.2.2", new Object[] {
0392:                                                derivedGrp.fName, key });
0393:                            }
0394:                        }
0395:                    }
0396:                }
0397:
0398:                // for each complex type, check the 3 constraints.
0399:                // types need to be checked
0400:                XSComplexTypeDecl[] types;
0401:                SimpleLocator[] ctLocators;
0402:                // to hold the errors
0403:                // REVISIT: do we want to report all errors? or just one?
0404:                //XMLSchemaError1D errors = new XMLSchemaError1D();
0405:                // whether need to check this type again;
0406:                // whether only do UPA checking
0407:                boolean further, fullChecked;
0408:                // if do all checkings, how many need to be checked again.
0409:                int keepType;
0410:                // i: grammar; j: type; k: error
0411:                // for all grammars
0412:                SymbolHash elemTable = new SymbolHash();
0413:                for (int i = grammars.length - 1, j; i >= 0; i--) {
0414:                    // get whether to skip EDC, and types need to be checked
0415:                    keepType = 0;
0416:                    fullChecked = grammars[i].fFullChecked;
0417:                    types = grammars[i].getUncheckedComplexTypeDecls();
0418:                    ctLocators = grammars[i].getUncheckedCTLocators();
0419:                    // for each type
0420:                    for (j = 0; j < types.length; j++) {
0421:                        // if we've already full-checked this grammar, then
0422:                        // skip the EDC constraint
0423:                        if (!fullChecked) {
0424:                            // 1. Element Decl Consistent
0425:                            if (types[j].fParticle != null) {
0426:                                elemTable.clear();
0427:                                try {
0428:                                    checkElementDeclsConsistent(types[j],
0429:                                            types[j].fParticle, elemTable,
0430:                                            SGHandler);
0431:                                } catch (XMLSchemaException e) {
0432:                                    reportSchemaError(errorReporter,
0433:                                            ctLocators[j], e.getKey(), e
0434:                                                    .getArgs());
0435:                                }
0436:                            }
0437:                        }
0438:
0439:                        // 2. Particle Derivation
0440:
0441:                        if (types[j].fBaseType != null
0442:                                && types[j].fBaseType != SchemaGrammar.fAnyType
0443:                                && types[j].fDerivedBy == XSConstants.DERIVATION_RESTRICTION
0444:                                && (types[j].fBaseType instanceof  XSComplexTypeDecl)) {
0445:
0446:                            XSParticleDecl derivedParticle = types[j].fParticle;
0447:                            XSParticleDecl baseParticle = ((XSComplexTypeDecl) (types[j].fBaseType)).fParticle;
0448:                            if (derivedParticle == null) {
0449:                                if (baseParticle != null
0450:                                        && !baseParticle.emptiable()) {
0451:                                    reportSchemaError(errorReporter,
0452:                                            ctLocators[j],
0453:                                            "derivation-ok-restriction.5.3.2",
0454:                                            new Object[] {
0455:                                                    types[j].fName,
0456:                                                    types[j].fBaseType
0457:                                                            .getName() });
0458:                                }
0459:                            } else if (baseParticle != null) {
0460:                                try {
0461:                                    particleValidRestriction(
0462:                                            types[j].fParticle,
0463:                                            SGHandler,
0464:                                            ((XSComplexTypeDecl) (types[j].fBaseType)).fParticle,
0465:                                            SGHandler);
0466:                                } catch (XMLSchemaException e) {
0467:                                    reportSchemaError(errorReporter,
0468:                                            ctLocators[j], e.getKey(), e
0469:                                                    .getArgs());
0470:                                    reportSchemaError(errorReporter,
0471:                                            ctLocators[j],
0472:                                            "derivation-ok-restriction.5.4.2",
0473:                                            new Object[] { types[j].fName });
0474:                                }
0475:                            } else {
0476:                                reportSchemaError(errorReporter, ctLocators[j],
0477:                                        "derivation-ok-restriction.5.4.2",
0478:                                        new Object[] { types[j].fName });
0479:                            }
0480:                        }
0481:                        // 3. UPA
0482:                        // get the content model and check UPA
0483:                        XSCMValidator cm = types[j].getContentModel(cmBuilder,
0484:                                true);
0485:                        further = false;
0486:                        if (cm != null) {
0487:                            try {
0488:                                further = cm
0489:                                        .checkUniqueParticleAttribution(SGHandler);
0490:                            } catch (XMLSchemaException e) {
0491:                                reportSchemaError(errorReporter, ctLocators[j],
0492:                                        e.getKey(), e.getArgs());
0493:                            }
0494:                        }
0495:                        // now report all errors
0496:                        // REVISIT: do we want to report all errors? or just one?
0497:                        /*for (k = errors.getErrorCodeNum()-1; k >= 0; k--) {
0498:                            reportSchemaError(errorReporter, ctLocators[j],
0499:                                              errors.getErrorCode(k),
0500:                                              errors.getArgs(k));
0501:                        }*/
0502:
0503:                        // if we are doing all checkings, and this one needs further
0504:                        // checking, store it in the type array.
0505:                        if (!fullChecked && further)
0506:                            types[keepType++] = types[j];
0507:
0508:                        // clear errors for the next type.
0509:                        // REVISIT: do we want to report all errors? or just one?
0510:                        //errors.clear();
0511:                    }
0512:                    // we've done with the types in this grammar. if we are checking
0513:                    // all constraints, need to trim type array to a proper size:
0514:                    // only contain those need further checking.
0515:                    // and mark this grammar that it only needs UPA checking.
0516:                    if (!fullChecked) {
0517:                        grammars[i].setUncheckedTypeNum(keepType);
0518:                        grammars[i].fFullChecked = true;
0519:                    }
0520:                }
0521:            }
0522:
0523:            /*
0524:               Check that a given particle is a valid restriction of a base particle.
0525:             */
0526:
0527:            public static void checkElementDeclsConsistent(
0528:                    XSComplexTypeDecl type, XSParticleDecl particle,
0529:                    SymbolHash elemDeclHash, SubstitutionGroupHandler sgHandler)
0530:                    throws XMLSchemaException {
0531:
0532:                // check for elements in the tree with the same name and namespace
0533:
0534:                int pType = particle.fType;
0535:
0536:                if (pType == XSParticleDecl.PARTICLE_WILDCARD)
0537:                    return;
0538:
0539:                if (pType == XSParticleDecl.PARTICLE_ELEMENT) {
0540:                    XSElementDecl elem = (XSElementDecl) (particle.fValue);
0541:                    findElemInTable(type, elem, elemDeclHash);
0542:
0543:                    if (elem.fScope == XSConstants.SCOPE_GLOBAL) {
0544:                        // Check for subsitution groups.
0545:                        XSElementDecl[] subGroup = sgHandler
0546:                                .getSubstitutionGroup(elem);
0547:                        for (int i = 0; i < subGroup.length; i++) {
0548:                            findElemInTable(type, subGroup[i], elemDeclHash);
0549:                        }
0550:                    }
0551:                    return;
0552:                }
0553:
0554:                XSModelGroupImpl group = (XSModelGroupImpl) particle.fValue;
0555:                for (int i = 0; i < group.fParticleCount; i++)
0556:                    checkElementDeclsConsistent(type, group.fParticles[i],
0557:                            elemDeclHash, sgHandler);
0558:            }
0559:
0560:            public static void findElemInTable(XSComplexTypeDecl type,
0561:                    XSElementDecl elem, SymbolHash elemDeclHash)
0562:                    throws XMLSchemaException {
0563:
0564:                // How can we avoid this concat?  LM.
0565:                String name = elem.fName + "," + elem.fTargetNamespace;
0566:
0567:                XSElementDecl existingElem = null;
0568:                if ((existingElem = (XSElementDecl) (elemDeclHash.get(name))) == null) {
0569:                    // just add it in
0570:                    elemDeclHash.put(name, elem);
0571:                } else {
0572:                    // If this is the same check element, we're O.K.
0573:                    if (elem == existingElem)
0574:                        return;
0575:
0576:                    if (elem.fType != existingElem.fType) {
0577:                        // Types are not the same
0578:                        throw new XMLSchemaException("cos-element-consistent",
0579:                                new Object[] { type.fName, elem.fName });
0580:
0581:                    }
0582:                }
0583:            }
0584:
0585:            // Check that a given particle is a valid restriction of a base particle.
0586:            // 
0587:            // IHR: 2006/11/17
0588:            // Returns a boolean indicating if there has been expansion of substitution group
0589:            // in the bParticle.
0590:            // With this information the checkRecurseLax function knows when is
0591:            // to keep the order and when to ignore it.
0592:            private static boolean particleValidRestriction(
0593:                    XSParticleDecl dParticle,
0594:                    SubstitutionGroupHandler dSGHandler,
0595:                    XSParticleDecl bParticle,
0596:                    SubstitutionGroupHandler bSGHandler)
0597:                    throws XMLSchemaException {
0598:                return particleValidRestriction(dParticle, dSGHandler,
0599:                        bParticle, bSGHandler, true);
0600:            }
0601:
0602:            private static boolean particleValidRestriction(
0603:                    XSParticleDecl dParticle,
0604:                    SubstitutionGroupHandler dSGHandler,
0605:                    XSParticleDecl bParticle,
0606:                    SubstitutionGroupHandler bSGHandler,
0607:                    boolean checkWCOccurrence) throws XMLSchemaException {
0608:
0609:                Vector dChildren = null;
0610:                Vector bChildren = null;
0611:                int dMinEffectiveTotalRange = OCCURRENCE_UNKNOWN;
0612:                int dMaxEffectiveTotalRange = OCCURRENCE_UNKNOWN;
0613:
0614:                // By default there has been no expansion
0615:                boolean bExpansionHappened = false;
0616:
0617:                // Check for empty particles.   If either base or derived particle is empty,
0618:                // (and the other isn't) it's an error.
0619:                if (dParticle.isEmpty() && !bParticle.emptiable()) {
0620:                    throw new XMLSchemaException("cos-particle-restrict.a",
0621:                            null);
0622:                } else if (!dParticle.isEmpty() && bParticle.isEmpty()) {
0623:                    throw new XMLSchemaException("cos-particle-restrict.b",
0624:                            null);
0625:                }
0626:
0627:                //
0628:                // Do setup prior to invoking the Particle (Restriction) cases.
0629:                // This involves:
0630:                //   - removing pointless occurrences for groups, and retrieving a vector of
0631:                //     non-pointless children
0632:                //   - turning top-level elements with substitution groups into CHOICE groups.
0633:                //
0634:
0635:                short dType = dParticle.fType;
0636:                //
0637:                // Handle pointless groups for the derived particle
0638:                //
0639:                if (dType == XSParticleDecl.PARTICLE_MODELGROUP) {
0640:                    dType = ((XSModelGroupImpl) dParticle.fValue).fCompositor;
0641:
0642:                    // Find a group, starting with this particle, with more than 1 child.   There
0643:                    // may be none, and the particle of interest trivially becomes an element or
0644:                    // wildcard.
0645:                    XSParticleDecl dtmp = getNonUnaryGroup(dParticle);
0646:                    if (dtmp != dParticle) {
0647:                        // Particle has been replaced.   Retrieve new type info.
0648:                        dParticle = dtmp;
0649:                        dType = dParticle.fType;
0650:                        if (dType == XSParticleDecl.PARTICLE_MODELGROUP)
0651:                            dType = ((XSModelGroupImpl) dParticle.fValue).fCompositor;
0652:                    }
0653:
0654:                    // Fill in a vector with the children of the particle, removing any
0655:                    // pointless model groups in the process.
0656:                    dChildren = removePointlessChildren(dParticle);
0657:                }
0658:
0659:                int dMinOccurs = dParticle.fMinOccurs;
0660:                int dMaxOccurs = dParticle.fMaxOccurs;
0661:
0662:                //
0663:                // For elements which are the heads of substitution groups, treat as CHOICE
0664:                //
0665:                if (dSGHandler != null
0666:                        && dType == XSParticleDecl.PARTICLE_ELEMENT) {
0667:                    XSElementDecl dElement = (XSElementDecl) dParticle.fValue;
0668:
0669:                    if (dElement.fScope == XSConstants.SCOPE_GLOBAL) {
0670:                        // Check for subsitution groups.   Treat any element that has a
0671:                        // subsitution group as a choice.   Fill in the children vector with the
0672:                        // members of the substitution group
0673:                        XSElementDecl[] subGroup = dSGHandler
0674:                                .getSubstitutionGroup(dElement);
0675:                        if (subGroup.length > 0) {
0676:                            // Now, set the type to be CHOICE.  The "group" will have the same
0677:                            // occurrence information as the original particle.
0678:                            dType = XSModelGroupImpl.MODELGROUP_CHOICE;
0679:                            dMinEffectiveTotalRange = dMinOccurs;
0680:                            dMaxEffectiveTotalRange = dMaxOccurs;
0681:
0682:                            // Fill in the vector of children
0683:                            dChildren = new Vector(subGroup.length + 1);
0684:                            for (int i = 0; i < subGroup.length; i++) {
0685:                                addElementToParticleVector(dChildren,
0686:                                        subGroup[i]);
0687:                            }
0688:                            addElementToParticleVector(dChildren, dElement);
0689:                            Collections.sort(dChildren,
0690:                                    ELEMENT_PARTICLE_COMPARATOR);
0691:
0692:                            // Set the handler to null, to indicate that we've finished handling
0693:                            // substitution groups for this particle.
0694:                            dSGHandler = null;
0695:                        }
0696:                    }
0697:                }
0698:
0699:                short bType = bParticle.fType;
0700:                //
0701:                // Handle pointless groups for the base particle
0702:                //
0703:                if (bType == XSParticleDecl.PARTICLE_MODELGROUP) {
0704:                    bType = ((XSModelGroupImpl) bParticle.fValue).fCompositor;
0705:
0706:                    // Find a group, starting with this particle, with more than 1 child.   There
0707:                    // may be none, and the particle of interest trivially becomes an element or
0708:                    // wildcard.
0709:                    XSParticleDecl btmp = getNonUnaryGroup(bParticle);
0710:                    if (btmp != bParticle) {
0711:                        // Particle has been replaced.   Retrieve new type info.
0712:                        bParticle = btmp;
0713:                        bType = bParticle.fType;
0714:                        if (bType == XSParticleDecl.PARTICLE_MODELGROUP)
0715:                            bType = ((XSModelGroupImpl) bParticle.fValue).fCompositor;
0716:                    }
0717:
0718:                    // Fill in a vector with the children of the particle, removing any
0719:                    // pointless model groups in the process.
0720:                    bChildren = removePointlessChildren(bParticle);
0721:                }
0722:
0723:                int bMinOccurs = bParticle.fMinOccurs;
0724:                int bMaxOccurs = bParticle.fMaxOccurs;
0725:
0726:                if (bSGHandler != null
0727:                        && bType == XSParticleDecl.PARTICLE_ELEMENT) {
0728:                    XSElementDecl bElement = (XSElementDecl) bParticle.fValue;
0729:
0730:                    if (bElement.fScope == XSConstants.SCOPE_GLOBAL) {
0731:                        // Check for subsitution groups.   Treat any element that has a
0732:                        // subsitution group as a choice.   Fill in the children vector with the
0733:                        // members of the substitution group
0734:                        XSElementDecl[] bsubGroup = bSGHandler
0735:                                .getSubstitutionGroup(bElement);
0736:                        if (bsubGroup.length > 0) {
0737:                            // Now, set the type to be CHOICE
0738:                            bType = XSModelGroupImpl.MODELGROUP_CHOICE;
0739:
0740:                            bChildren = new Vector(bsubGroup.length + 1);
0741:                            for (int i = 0; i < bsubGroup.length; i++) {
0742:                                addElementToParticleVector(bChildren,
0743:                                        bsubGroup[i]);
0744:                            }
0745:                            addElementToParticleVector(bChildren, bElement);
0746:                            Collections.sort(bChildren,
0747:                                    ELEMENT_PARTICLE_COMPARATOR);
0748:                            // Set the handler to null, to indicate that we've finished handling
0749:                            // substitution groups for this particle.
0750:                            bSGHandler = null;
0751:
0752:                            // if we are here expansion of bParticle happened
0753:                            bExpansionHappened = true;
0754:                        }
0755:                    }
0756:                }
0757:
0758:                //
0759:                // O.K. - Figure out which particle derivation rule applies and call it
0760:                //
0761:                switch (dType) {
0762:                case XSParticleDecl.PARTICLE_ELEMENT: {
0763:                    switch (bType) {
0764:
0765:                    // Elt:Elt NameAndTypeOK
0766:                    case XSParticleDecl.PARTICLE_ELEMENT: {
0767:                        checkNameAndTypeOK((XSElementDecl) dParticle.fValue,
0768:                                dMinOccurs, dMaxOccurs,
0769:                                (XSElementDecl) bParticle.fValue, bMinOccurs,
0770:                                bMaxOccurs);
0771:                        return bExpansionHappened;
0772:                    }
0773:
0774:                        // Elt:Any NSCompat
0775:                    case XSParticleDecl.PARTICLE_WILDCARD: {
0776:                        checkNSCompat((XSElementDecl) dParticle.fValue,
0777:                                dMinOccurs, dMaxOccurs,
0778:                                (XSWildcardDecl) bParticle.fValue, bMinOccurs,
0779:                                bMaxOccurs, checkWCOccurrence);
0780:                        return bExpansionHappened;
0781:                    }
0782:
0783:                        // Elt:All RecurseAsIfGroup
0784:                    case XSModelGroupImpl.MODELGROUP_CHOICE: {
0785:                        // Treat the element as if it were in a group of the same type
0786:                        // as the base Particle
0787:                        dChildren = new Vector();
0788:                        dChildren.addElement(dParticle);
0789:
0790:                        checkRecurseLax(dChildren, 1, 1, dSGHandler, bChildren,
0791:                                bMinOccurs, bMaxOccurs, bSGHandler);
0792:                        return bExpansionHappened;
0793:                    }
0794:                    case XSModelGroupImpl.MODELGROUP_SEQUENCE:
0795:                    case XSModelGroupImpl.MODELGROUP_ALL: {
0796:                        // Treat the element as if it were in a group of the same type
0797:                        // as the base Particle
0798:                        dChildren = new Vector();
0799:                        dChildren.addElement(dParticle);
0800:
0801:                        checkRecurse(dChildren, 1, 1, dSGHandler, bChildren,
0802:                                bMinOccurs, bMaxOccurs, bSGHandler);
0803:                        return bExpansionHappened;
0804:                    }
0805:
0806:                    default: {
0807:                        throw new XMLSchemaException("Internal-Error",
0808:                                new Object[] { "in particleValidRestriction" });
0809:                    }
0810:                    }
0811:                }
0812:
0813:                case XSParticleDecl.PARTICLE_WILDCARD: {
0814:                    switch (bType) {
0815:
0816:                    // Any:Any NSSubset
0817:                    case XSParticleDecl.PARTICLE_WILDCARD: {
0818:                        checkNSSubset((XSWildcardDecl) dParticle.fValue,
0819:                                dMinOccurs, dMaxOccurs,
0820:                                (XSWildcardDecl) bParticle.fValue, bMinOccurs,
0821:                                bMaxOccurs);
0822:                        return bExpansionHappened;
0823:                    }
0824:
0825:                    case XSModelGroupImpl.MODELGROUP_CHOICE:
0826:                    case XSModelGroupImpl.MODELGROUP_SEQUENCE:
0827:                    case XSModelGroupImpl.MODELGROUP_ALL:
0828:                    case XSParticleDecl.PARTICLE_ELEMENT: {
0829:                        throw new XMLSchemaException("cos-particle-restrict.2",
0830:                                new Object[] { "any:choice,sequence,all,elt" });
0831:                    }
0832:
0833:                    default: {
0834:                        throw new XMLSchemaException("Internal-Error",
0835:                                new Object[] { "in particleValidRestriction" });
0836:                    }
0837:                    }
0838:                }
0839:
0840:                case XSModelGroupImpl.MODELGROUP_ALL: {
0841:                    switch (bType) {
0842:
0843:                    // All:Any NSRecurseCheckCardinality
0844:                    case XSParticleDecl.PARTICLE_WILDCARD: {
0845:                        if (dMinEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0846:                            dMinEffectiveTotalRange = dParticle
0847:                                    .minEffectiveTotalRange();
0848:                        if (dMaxEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0849:                            dMaxEffectiveTotalRange = dParticle
0850:                                    .maxEffectiveTotalRange();
0851:
0852:                        checkNSRecurseCheckCardinality(dChildren,
0853:                                dMinEffectiveTotalRange,
0854:                                dMaxEffectiveTotalRange, dSGHandler, bParticle,
0855:                                bMinOccurs, bMaxOccurs, checkWCOccurrence);
0856:
0857:                        return bExpansionHappened;
0858:                    }
0859:
0860:                    case XSModelGroupImpl.MODELGROUP_ALL: {
0861:                        checkRecurse(dChildren, dMinOccurs, dMaxOccurs,
0862:                                dSGHandler, bChildren, bMinOccurs, bMaxOccurs,
0863:                                bSGHandler);
0864:                        return bExpansionHappened;
0865:                    }
0866:
0867:                    case XSModelGroupImpl.MODELGROUP_CHOICE:
0868:                    case XSModelGroupImpl.MODELGROUP_SEQUENCE:
0869:                    case XSParticleDecl.PARTICLE_ELEMENT: {
0870:                        throw new XMLSchemaException("cos-particle-restrict.2",
0871:                                new Object[] { "all:choice,sequence,elt" });
0872:                    }
0873:
0874:                    default: {
0875:                        throw new XMLSchemaException("Internal-Error",
0876:                                new Object[] { "in particleValidRestriction" });
0877:                    }
0878:                    }
0879:                }
0880:
0881:                case XSModelGroupImpl.MODELGROUP_CHOICE: {
0882:                    switch (bType) {
0883:
0884:                    // Choice:Any NSRecurseCheckCardinality
0885:                    case XSParticleDecl.PARTICLE_WILDCARD: {
0886:                        if (dMinEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0887:                            dMinEffectiveTotalRange = dParticle
0888:                                    .minEffectiveTotalRange();
0889:                        if (dMaxEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0890:                            dMaxEffectiveTotalRange = dParticle
0891:                                    .maxEffectiveTotalRange();
0892:
0893:                        checkNSRecurseCheckCardinality(dChildren,
0894:                                dMinEffectiveTotalRange,
0895:                                dMaxEffectiveTotalRange, dSGHandler, bParticle,
0896:                                bMinOccurs, bMaxOccurs, checkWCOccurrence);
0897:                        return bExpansionHappened;
0898:                    }
0899:
0900:                    case XSModelGroupImpl.MODELGROUP_CHOICE: {
0901:                        checkRecurseLax(dChildren, dMinOccurs, dMaxOccurs,
0902:                                dSGHandler, bChildren, bMinOccurs, bMaxOccurs,
0903:                                bSGHandler);
0904:                        return bExpansionHappened;
0905:                    }
0906:
0907:                    case XSModelGroupImpl.MODELGROUP_ALL:
0908:                    case XSModelGroupImpl.MODELGROUP_SEQUENCE:
0909:                    case XSParticleDecl.PARTICLE_ELEMENT: {
0910:                        throw new XMLSchemaException("cos-particle-restrict.2",
0911:                                new Object[] { "choice:all,sequence,elt" });
0912:                    }
0913:
0914:                    default: {
0915:                        throw new XMLSchemaException("Internal-Error",
0916:                                new Object[] { "in particleValidRestriction" });
0917:                    }
0918:                    }
0919:                }
0920:
0921:                case XSModelGroupImpl.MODELGROUP_SEQUENCE: {
0922:                    switch (bType) {
0923:
0924:                    // Choice:Any NSRecurseCheckCardinality
0925:                    case XSParticleDecl.PARTICLE_WILDCARD: {
0926:                        if (dMinEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0927:                            dMinEffectiveTotalRange = dParticle
0928:                                    .minEffectiveTotalRange();
0929:                        if (dMaxEffectiveTotalRange == OCCURRENCE_UNKNOWN)
0930:                            dMaxEffectiveTotalRange = dParticle
0931:                                    .maxEffectiveTotalRange();
0932:
0933:                        checkNSRecurseCheckCardinality(dChildren,
0934:                                dMinEffectiveTotalRange,
0935:                                dMaxEffectiveTotalRange, dSGHandler, bParticle,
0936:                                bMinOccurs, bMaxOccurs, checkWCOccurrence);
0937:                        return bExpansionHappened;
0938:                    }
0939:
0940:                    case XSModelGroupImpl.MODELGROUP_ALL: {
0941:                        checkRecurseUnordered(dChildren, dMinOccurs,
0942:                                dMaxOccurs, dSGHandler, bChildren, bMinOccurs,
0943:                                bMaxOccurs, bSGHandler);
0944:                        return bExpansionHappened;
0945:                    }
0946:
0947:                    case XSModelGroupImpl.MODELGROUP_SEQUENCE: {
0948:                        checkRecurse(dChildren, dMinOccurs, dMaxOccurs,
0949:                                dSGHandler, bChildren, bMinOccurs, bMaxOccurs,
0950:                                bSGHandler);
0951:                        return bExpansionHappened;
0952:                    }
0953:
0954:                    case XSModelGroupImpl.MODELGROUP_CHOICE: {
0955:                        int min1 = dMinOccurs * dChildren.size();
0956:                        int max1 = (dMaxOccurs == SchemaSymbols.OCCURRENCE_UNBOUNDED) ? dMaxOccurs
0957:                                : dMaxOccurs * dChildren.size();
0958:                        checkMapAndSum(dChildren, min1, max1, dSGHandler,
0959:                                bChildren, bMinOccurs, bMaxOccurs, bSGHandler);
0960:                        return bExpansionHappened;
0961:                    }
0962:
0963:                    case XSParticleDecl.PARTICLE_ELEMENT: {
0964:                        throw new XMLSchemaException("cos-particle-restrict.2",
0965:                                new Object[] { "seq:elt" });
0966:                    }
0967:
0968:                    default: {
0969:                        throw new XMLSchemaException("Internal-Error",
0970:                                new Object[] { "in particleValidRestriction" });
0971:                    }
0972:                    }
0973:                }
0974:
0975:                }
0976:
0977:                return bExpansionHappened;
0978:            }
0979:
0980:            private static void addElementToParticleVector(Vector v,
0981:                    XSElementDecl d) {
0982:
0983:                XSParticleDecl p = new XSParticleDecl();
0984:                p.fValue = d;
0985:                p.fType = XSParticleDecl.PARTICLE_ELEMENT;
0986:                v.addElement(p);
0987:
0988:            }
0989:
0990:            private static XSParticleDecl getNonUnaryGroup(XSParticleDecl p) {
0991:
0992:                if (p.fType == XSParticleDecl.PARTICLE_ELEMENT
0993:                        || p.fType == XSParticleDecl.PARTICLE_WILDCARD)
0994:                    return p;
0995:
0996:                if (p.fMinOccurs == 1 && p.fMaxOccurs == 1 && p.fValue != null
0997:                        && ((XSModelGroupImpl) p.fValue).fParticleCount == 1)
0998:                    return getNonUnaryGroup(((XSModelGroupImpl) p.fValue).fParticles[0]);
0999:                else
1000:                    return p;
1001:            }
1002:
1003:            private static Vector removePointlessChildren(XSParticleDecl p) {
1004:
1005:                if (p.fType == XSParticleDecl.PARTICLE_ELEMENT
1006:                        || p.fType == XSParticleDecl.PARTICLE_WILDCARD)
1007:                    return null;
1008:
1009:                Vector children = new Vector();
1010:
1011:                XSModelGroupImpl group = (XSModelGroupImpl) p.fValue;
1012:                for (int i = 0; i < group.fParticleCount; i++)
1013:                    gatherChildren(group.fCompositor, group.fParticles[i],
1014:                            children);
1015:
1016:                return children;
1017:            }
1018:
1019:            private static void gatherChildren(int parentType,
1020:                    XSParticleDecl p, Vector children) {
1021:
1022:                int min = p.fMinOccurs;
1023:                int max = p.fMaxOccurs;
1024:                int type = p.fType;
1025:                if (type == XSParticleDecl.PARTICLE_MODELGROUP)
1026:                    type = ((XSModelGroupImpl) p.fValue).fCompositor;
1027:
1028:                if (type == XSParticleDecl.PARTICLE_ELEMENT
1029:                        || type == XSParticleDecl.PARTICLE_WILDCARD) {
1030:                    children.addElement(p);
1031:                    return;
1032:                }
1033:
1034:                if (!(min == 1 && max == 1)) {
1035:                    children.addElement(p);
1036:                } else if (parentType == type) {
1037:                    XSModelGroupImpl group = (XSModelGroupImpl) p.fValue;
1038:                    for (int i = 0; i < group.fParticleCount; i++)
1039:                        gatherChildren(type, group.fParticles[i], children);
1040:                } else if (!p.isEmpty()) {
1041:                    children.addElement(p);
1042:                }
1043:
1044:            }
1045:
1046:            private static void checkNameAndTypeOK(XSElementDecl dElement,
1047:                    int dMin, int dMax, XSElementDecl bElement, int bMin,
1048:                    int bMax) throws XMLSchemaException {
1049:
1050:                //
1051:                // Check that the names are the same
1052:                //
1053:                if (dElement.fName != bElement.fName
1054:                        || dElement.fTargetNamespace != bElement.fTargetNamespace) {
1055:                    throw new XMLSchemaException("rcase-NameAndTypeOK.1",
1056:                            new Object[] { dElement.fName,
1057:                                    dElement.fTargetNamespace, bElement.fName,
1058:                                    bElement.fTargetNamespace });
1059:                }
1060:
1061:                //
1062:                // Check nillable
1063:                //
1064:                if (!bElement.getNillable() && dElement.getNillable()) {
1065:                    throw new XMLSchemaException("rcase-NameAndTypeOK.2",
1066:                            new Object[] { dElement.fName });
1067:                }
1068:
1069:                //
1070:                // Check occurrence range
1071:                //
1072:                if (!checkOccurrenceRange(dMin, dMax, bMin, bMax)) {
1073:                    throw new XMLSchemaException(
1074:                            "rcase-NameAndTypeOK.3",
1075:                            new Object[] {
1076:                                    dElement.fName,
1077:                                    Integer.toString(dMin),
1078:                                    dMax == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1079:                                            : Integer.toString(dMax),
1080:                                    Integer.toString(bMin),
1081:                                    bMax == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1082:                                            : Integer.toString(bMax) });
1083:                }
1084:
1085:                //
1086:                // Check for consistent fixed values
1087:                //
1088:                if (bElement.getConstraintType() == XSConstants.VC_FIXED) {
1089:                    // derived one has to have a fixed value
1090:                    if (dElement.getConstraintType() != XSConstants.VC_FIXED) {
1091:                        throw new XMLSchemaException("rcase-NameAndTypeOK.4.a",
1092:                                new Object[] { dElement.fName,
1093:                                        bElement.fDefault.stringValue() });
1094:                    }
1095:
1096:                    // get simple type
1097:                    boolean isSimple = false;
1098:                    if (dElement.fType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE
1099:                            || ((XSComplexTypeDecl) dElement.fType).fContentType == XSComplexTypeDecl.CONTENTTYPE_SIMPLE) {
1100:                        isSimple = true;
1101:                    }
1102:
1103:                    // if there is no simple type, then compare based on string
1104:                    if (!isSimple
1105:                            && !bElement.fDefault.normalizedValue
1106:                                    .equals(dElement.fDefault.normalizedValue)
1107:                            || isSimple
1108:                            && !bElement.fDefault.actualValue
1109:                                    .equals(dElement.fDefault.actualValue)) {
1110:                        throw new XMLSchemaException("rcase-NameAndTypeOK.4.b",
1111:                                new Object[] { dElement.fName,
1112:                                        dElement.fDefault.stringValue(),
1113:                                        bElement.fDefault.stringValue() });
1114:                    }
1115:                }
1116:
1117:                //
1118:                // Check identity constraints
1119:                //
1120:                checkIDConstraintRestriction(dElement, bElement);
1121:
1122:                //
1123:                // Check for disallowed substitutions
1124:                //
1125:                int blockSet1 = dElement.fBlock;
1126:                int blockSet2 = bElement.fBlock;
1127:                if (((blockSet1 & blockSet2) != blockSet2)
1128:                        || (blockSet1 == XSConstants.DERIVATION_NONE && blockSet2 != XSConstants.DERIVATION_NONE))
1129:                    throw new XMLSchemaException("rcase-NameAndTypeOK.6",
1130:                            new Object[] { dElement.fName });
1131:
1132:                //
1133:                // Check that the derived element's type is derived from the base's.
1134:                //
1135:                if (!checkTypeDerivationOk(
1136:                        dElement.fType,
1137:                        bElement.fType,
1138:                        (short) (XSConstants.DERIVATION_EXTENSION
1139:                                | XSConstants.DERIVATION_LIST | XSConstants.DERIVATION_UNION))) {
1140:                    throw new XMLSchemaException("rcase-NameAndTypeOK.7",
1141:                            new Object[] { dElement.fName,
1142:                                    dElement.fType.getName(),
1143:                                    bElement.fType.getName() });
1144:                }
1145:
1146:            }
1147:
1148:            private static void checkIDConstraintRestriction(
1149:                    XSElementDecl derivedElemDecl, XSElementDecl baseElemDecl)
1150:                    throws XMLSchemaException {
1151:                // TODO
1152:            } // checkIDConstraintRestriction
1153:
1154:            private static boolean checkOccurrenceRange(int min1, int max1,
1155:                    int min2, int max2) {
1156:
1157:                if ((min1 >= min2)
1158:                        && ((max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED) || (max1 != SchemaSymbols.OCCURRENCE_UNBOUNDED && max1 <= max2)))
1159:                    return true;
1160:                else
1161:                    return false;
1162:            }
1163:
1164:            private static void checkNSCompat(XSElementDecl elem, int min1,
1165:                    int max1, XSWildcardDecl wildcard, int min2, int max2,
1166:                    boolean checkWCOccurrence) throws XMLSchemaException {
1167:
1168:                // check Occurrence ranges
1169:                if (checkWCOccurrence
1170:                        && !checkOccurrenceRange(min1, max1, min2, max2)) {
1171:                    throw new XMLSchemaException(
1172:                            "rcase-NSCompat.2",
1173:                            new Object[] {
1174:                                    elem.fName,
1175:                                    Integer.toString(min1),
1176:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1177:                                            : Integer.toString(max1),
1178:                                    Integer.toString(min2),
1179:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1180:                                            : Integer.toString(max2) });
1181:                }
1182:
1183:                // check wildcard allows namespace of element
1184:                if (!wildcard.allowNamespace(elem.fTargetNamespace)) {
1185:                    throw new XMLSchemaException("rcase-NSCompat.1",
1186:                            new Object[] { elem.fName, elem.fTargetNamespace });
1187:                }
1188:
1189:            }
1190:
1191:            private static void checkNSSubset(XSWildcardDecl dWildcard,
1192:                    int min1, int max1, XSWildcardDecl bWildcard, int min2,
1193:                    int max2) throws XMLSchemaException {
1194:
1195:                // check Occurrence ranges
1196:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
1197:                    throw new XMLSchemaException(
1198:                            "rcase-NSSubset.2",
1199:                            new Object[] {
1200:                                    Integer.toString(min1),
1201:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1202:                                            : Integer.toString(max1),
1203:                                    Integer.toString(min2),
1204:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1205:                                            : Integer.toString(max2) });
1206:                }
1207:
1208:                // check wildcard subset
1209:                if (!dWildcard.isSubsetOf(bWildcard)) {
1210:                    throw new XMLSchemaException("rcase-NSSubset.1", null);
1211:                }
1212:
1213:                if (dWildcard.weakerProcessContents(bWildcard)) {
1214:                    throw new XMLSchemaException("rcase-NSSubset.3",
1215:                            new Object[] {
1216:                                    dWildcard.getProcessContentsAsString(),
1217:                                    bWildcard.getProcessContentsAsString() });
1218:                }
1219:
1220:            }
1221:
1222:            private static void checkNSRecurseCheckCardinality(Vector children,
1223:                    int min1, int max1, SubstitutionGroupHandler dSGHandler,
1224:                    XSParticleDecl wildcard, int min2, int max2,
1225:                    boolean checkWCOccurrence) throws XMLSchemaException {
1226:
1227:                // check Occurrence ranges
1228:                if (checkWCOccurrence
1229:                        && !checkOccurrenceRange(min1, max1, min2, max2)) {
1230:                    throw new XMLSchemaException(
1231:                            "rcase-NSRecurseCheckCardinality.2",
1232:                            new Object[] {
1233:                                    Integer.toString(min1),
1234:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1235:                                            : Integer.toString(max1),
1236:                                    Integer.toString(min2),
1237:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1238:                                            : Integer.toString(max2) });
1239:                }
1240:
1241:                // Check that each member of the group is a valid restriction of the wildcard
1242:                int count = children.size();
1243:                try {
1244:                    for (int i = 0; i < count; i++) {
1245:                        XSParticleDecl particle1 = (XSParticleDecl) children
1246:                                .elementAt(i);
1247:                        particleValidRestriction(particle1, dSGHandler,
1248:                                wildcard, null, false);
1249:
1250:                    }
1251:                }
1252:                // REVISIT: should we really just ignore original cause of this error?
1253:                //          how can we report it?
1254:                catch (XMLSchemaException e) {
1255:                    throw new XMLSchemaException(
1256:                            "rcase-NSRecurseCheckCardinality.1", null);
1257:                }
1258:
1259:            }
1260:
1261:            private static void checkRecurse(Vector dChildren, int min1,
1262:                    int max1, SubstitutionGroupHandler dSGHandler,
1263:                    Vector bChildren, int min2, int max2,
1264:                    SubstitutionGroupHandler bSGHandler)
1265:                    throws XMLSchemaException {
1266:
1267:                // check Occurrence ranges
1268:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
1269:                    throw new XMLSchemaException(
1270:                            "rcase-Recurse.1",
1271:                            new Object[] {
1272:                                    Integer.toString(min1),
1273:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1274:                                            : Integer.toString(max1),
1275:                                    Integer.toString(min2),
1276:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1277:                                            : Integer.toString(max2) });
1278:                }
1279:
1280:                int count1 = dChildren.size();
1281:                int count2 = bChildren.size();
1282:
1283:                int current = 0;
1284:                label: for (int i = 0; i < count1; i++) {
1285:
1286:                    XSParticleDecl particle1 = (XSParticleDecl) dChildren
1287:                            .elementAt(i);
1288:                    for (int j = current; j < count2; j++) {
1289:                        XSParticleDecl particle2 = (XSParticleDecl) bChildren
1290:                                .elementAt(j);
1291:                        current += 1;
1292:                        try {
1293:                            particleValidRestriction(particle1, dSGHandler,
1294:                                    particle2, bSGHandler);
1295:                            continue label;
1296:                        } catch (XMLSchemaException e) {
1297:                            if (!particle2.emptiable())
1298:                                throw new XMLSchemaException("rcase-Recurse.2",
1299:                                        null);
1300:                        }
1301:                    }
1302:                    throw new XMLSchemaException("rcase-Recurse.2", null);
1303:                }
1304:
1305:                // Now, see if there are some elements in the base we didn't match up
1306:                for (int j = current; j < count2; j++) {
1307:                    XSParticleDecl particle2 = (XSParticleDecl) bChildren
1308:                            .elementAt(j);
1309:                    if (!particle2.emptiable()) {
1310:                        throw new XMLSchemaException("rcase-Recurse.2", null);
1311:                    }
1312:                }
1313:
1314:            }
1315:
1316:            private static void checkRecurseUnordered(Vector dChildren,
1317:                    int min1, int max1, SubstitutionGroupHandler dSGHandler,
1318:                    Vector bChildren, int min2, int max2,
1319:                    SubstitutionGroupHandler bSGHandler)
1320:                    throws XMLSchemaException {
1321:
1322:                // check Occurrence ranges
1323:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
1324:                    throw new XMLSchemaException(
1325:                            "rcase-RecurseUnordered.1",
1326:                            new Object[] {
1327:                                    Integer.toString(min1),
1328:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1329:                                            : Integer.toString(max1),
1330:                                    Integer.toString(min2),
1331:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1332:                                            : Integer.toString(max2) });
1333:                }
1334:
1335:                int count1 = dChildren.size();
1336:                int count2 = bChildren.size();
1337:
1338:                boolean foundIt[] = new boolean[count2];
1339:
1340:                label: for (int i = 0; i < count1; i++) {
1341:                    XSParticleDecl particle1 = (XSParticleDecl) dChildren
1342:                            .elementAt(i);
1343:
1344:                    for (int j = 0; j < count2; j++) {
1345:                        XSParticleDecl particle2 = (XSParticleDecl) bChildren
1346:                                .elementAt(j);
1347:                        try {
1348:                            particleValidRestriction(particle1, dSGHandler,
1349:                                    particle2, bSGHandler);
1350:                            if (foundIt[j])
1351:                                throw new XMLSchemaException(
1352:                                        "rcase-RecurseUnordered.2", null);
1353:                            else
1354:                                foundIt[j] = true;
1355:
1356:                            continue label;
1357:                        } catch (XMLSchemaException e) {
1358:                        }
1359:                    }
1360:                    // didn't find a match.  Detect an error
1361:                    throw new XMLSchemaException("rcase-RecurseUnordered.2",
1362:                            null);
1363:                }
1364:
1365:                // Now, see if there are some elements in the base we didn't match up
1366:                for (int j = 0; j < count2; j++) {
1367:                    XSParticleDecl particle2 = (XSParticleDecl) bChildren
1368:                            .elementAt(j);
1369:                    if (!foundIt[j] && !particle2.emptiable()) {
1370:                        throw new XMLSchemaException(
1371:                                "rcase-RecurseUnordered.2", null);
1372:                    }
1373:                }
1374:
1375:            }
1376:
1377:            private static void checkRecurseLax(Vector dChildren, int min1,
1378:                    int max1, SubstitutionGroupHandler dSGHandler,
1379:                    Vector bChildren, int min2, int max2,
1380:                    SubstitutionGroupHandler bSGHandler)
1381:                    throws XMLSchemaException {
1382:
1383:                // check Occurrence ranges
1384:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
1385:                    throw new XMLSchemaException(
1386:                            "rcase-RecurseLax.1",
1387:                            new Object[] {
1388:                                    Integer.toString(min1),
1389:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1390:                                            : Integer.toString(max1),
1391:                                    Integer.toString(min2),
1392:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1393:                                            : Integer.toString(max2) });
1394:                }
1395:
1396:                int count1 = dChildren.size();
1397:                int count2 = bChildren.size();
1398:
1399:                int current = 0;
1400:                label: for (int i = 0; i < count1; i++) {
1401:
1402:                    XSParticleDecl particle1 = (XSParticleDecl) dChildren
1403:                            .elementAt(i);
1404:                    for (int j = current; j < count2; j++) {
1405:                        XSParticleDecl particle2 = (XSParticleDecl) bChildren
1406:                                .elementAt(j);
1407:                        current += 1;
1408:                        try {
1409:                            // IHR: go back one element on b list because the next element may match
1410:                            // this as well.
1411:                            if (particleValidRestriction(particle1, dSGHandler,
1412:                                    particle2, bSGHandler))
1413:                                current--;
1414:                            continue label;
1415:                        } catch (XMLSchemaException e) {
1416:                        }
1417:                    }
1418:                    // didn't find a match.  Detect an error
1419:                    throw new XMLSchemaException("rcase-RecurseLax.2", null);
1420:
1421:                }
1422:
1423:            }
1424:
1425:            private static void checkMapAndSum(Vector dChildren, int min1,
1426:                    int max1, SubstitutionGroupHandler dSGHandler,
1427:                    Vector bChildren, int min2, int max2,
1428:                    SubstitutionGroupHandler bSGHandler)
1429:                    throws XMLSchemaException {
1430:
1431:                // See if the sequence group is a valid restriction of the choice
1432:
1433:                // Here is an example of a valid restriction:
1434:                //   <choice minOccurs="2">
1435:                //       <a/>
1436:                //       <b/>
1437:                //       <c/>
1438:                //   </choice>
1439:                //
1440:                //   <sequence>
1441:                //        <b/>
1442:                //        <a/>
1443:                //   </sequence>
1444:
1445:                // check Occurrence ranges
1446:                if (!checkOccurrenceRange(min1, max1, min2, max2)) {
1447:                    throw new XMLSchemaException(
1448:                            "rcase-MapAndSum.2",
1449:                            new Object[] {
1450:                                    Integer.toString(min1),
1451:                                    max1 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1452:                                            : Integer.toString(max1),
1453:                                    Integer.toString(min2),
1454:                                    max2 == SchemaSymbols.OCCURRENCE_UNBOUNDED ? "unbounded"
1455:                                            : Integer.toString(max2) });
1456:                }
1457:
1458:                int count1 = dChildren.size();
1459:                int count2 = bChildren.size();
1460:
1461:                label: for (int i = 0; i < count1; i++) {
1462:
1463:                    XSParticleDecl particle1 = (XSParticleDecl) dChildren
1464:                            .elementAt(i);
1465:                    for (int j = 0; j < count2; j++) {
1466:                        XSParticleDecl particle2 = (XSParticleDecl) bChildren
1467:                                .elementAt(j);
1468:                        try {
1469:                            particleValidRestriction(particle1, dSGHandler,
1470:                                    particle2, bSGHandler);
1471:                            continue label;
1472:                        } catch (XMLSchemaException e) {
1473:                        }
1474:                    }
1475:                    // didn't find a match.  Detect an error
1476:                    throw new XMLSchemaException("rcase-MapAndSum.1", null);
1477:                }
1478:            }
1479:
1480:            // to check whether two element overlap, as defined in constraint UPA
1481:            public static boolean overlapUPA(XSElementDecl element1,
1482:                    XSElementDecl element2, SubstitutionGroupHandler sgHandler) {
1483:                // if the two element have the same name and namespace,
1484:                if (element1.fName == element2.fName
1485:                        && element1.fTargetNamespace == element2.fTargetNamespace) {
1486:                    return true;
1487:                }
1488:
1489:                // or if there is an element decl in element1's substitution group,
1490:                // who has the same name/namespace with element2
1491:                XSElementDecl[] subGroup = sgHandler
1492:                        .getSubstitutionGroup(element1);
1493:                for (int i = subGroup.length - 1; i >= 0; i--) {
1494:                    if (subGroup[i].fName == element2.fName
1495:                            && subGroup[i].fTargetNamespace == element2.fTargetNamespace) {
1496:                        return true;
1497:                    }
1498:                }
1499:
1500:                // or if there is an element decl in element2's substitution group,
1501:                // who has the same name/namespace with element1
1502:                subGroup = sgHandler.getSubstitutionGroup(element2);
1503:                for (int i = subGroup.length - 1; i >= 0; i--) {
1504:                    if (subGroup[i].fName == element1.fName
1505:                            && subGroup[i].fTargetNamespace == element1.fTargetNamespace) {
1506:                        return true;
1507:                    }
1508:                }
1509:
1510:                return false;
1511:            }
1512:
1513:            // to check whether an element overlaps with a wildcard,
1514:            // as defined in constraint UPA
1515:            public static boolean overlapUPA(XSElementDecl element,
1516:                    XSWildcardDecl wildcard, SubstitutionGroupHandler sgHandler) {
1517:                // if the wildcard allows the element
1518:                if (wildcard.allowNamespace(element.fTargetNamespace))
1519:                    return true;
1520:
1521:                // or if the wildcard allows any element in the substitution group
1522:                XSElementDecl[] subGroup = sgHandler
1523:                        .getSubstitutionGroup(element);
1524:                for (int i = subGroup.length - 1; i >= 0; i--) {
1525:                    if (wildcard.allowNamespace(subGroup[i].fTargetNamespace))
1526:                        return true;
1527:                }
1528:
1529:                return false;
1530:            }
1531:
1532:            public static boolean overlapUPA(XSWildcardDecl wildcard1,
1533:                    XSWildcardDecl wildcard2) {
1534:                // if the intersection of the two wildcard is not empty list
1535:                XSWildcardDecl intersect = wildcard1.performIntersectionWith(
1536:                        wildcard2, wildcard1.fProcessContents);
1537:                if (intersect == null
1538:                        || intersect.fType != XSWildcardDecl.NSCONSTRAINT_LIST
1539:                        || intersect.fNamespaceList.length != 0) {
1540:                    return true;
1541:                }
1542:
1543:                return false;
1544:            }
1545:
1546:            // call one of the above methods according to the type of decls
1547:            public static boolean overlapUPA(Object decl1, Object decl2,
1548:                    SubstitutionGroupHandler sgHandler) {
1549:                if (decl1 instanceof  XSElementDecl) {
1550:                    if (decl2 instanceof  XSElementDecl) {
1551:                        return overlapUPA((XSElementDecl) decl1,
1552:                                (XSElementDecl) decl2, sgHandler);
1553:                    } else {
1554:                        return overlapUPA((XSElementDecl) decl1,
1555:                                (XSWildcardDecl) decl2, sgHandler);
1556:                    }
1557:                } else {
1558:                    if (decl2 instanceof  XSElementDecl) {
1559:                        return overlapUPA((XSElementDecl) decl2,
1560:                                (XSWildcardDecl) decl1, sgHandler);
1561:                    } else {
1562:                        return overlapUPA((XSWildcardDecl) decl1,
1563:                                (XSWildcardDecl) decl2);
1564:                    }
1565:                }
1566:            }
1567:
1568:        } // class XSContraints
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.