1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Nov 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xerces.internal.impl.xs;
  23 
  24 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  25 import com.sun.org.apache.xerces.internal.xs.*;
  26 import com.sun.org.apache.xerces.internal.impl.xs.models.XSCMValidator;
  27 import com.sun.org.apache.xerces.internal.impl.xs.models.CMBuilder;
  28 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  29 import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
  30 import org.w3c.dom.TypeInfo;
  31 
  32 /**
  33  * The XML representation for a complexType
  34  * schema component is a <complexType> element information item
  35  *
  36  * @xerces.internal
  37  *
  38  * @author Elena Litani, IBM
  39  * @author Sandy Gao, IBM
  40  */
  41 public class XSComplexTypeDecl implements XSComplexTypeDefinition, TypeInfo {
  42 
  43     // name of the complexType
  44     String fName = null;
  45 
  46     // target namespace of the complexType
  47     String fTargetNamespace = null;
  48 
  49     // base type of the complexType
  50     XSTypeDefinition fBaseType = null;
  51 
  52     // derivation method of the complexType
  53     short fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
  54 
  55     // final set of the complexType
  56     short fFinal = XSConstants.DERIVATION_NONE;
  57 
  58     // block set (prohibited substitution) of the complexType
  59     short fBlock = XSConstants.DERIVATION_NONE;
  60 
  61     // flags: whether is abstract; whether contains ID type;
  62     //        whether it's an anonymous tpye
  63     short fMiscFlags = 0;
  64 
  65     // the attribute group that holds the attribute uses and attribute wildcard
  66     XSAttributeGroupDecl fAttrGrp = null;
  67 
  68     // the content type of the complexType
  69     short fContentType = CONTENTTYPE_EMPTY;
  70 
  71     // if the content type is simple, then the corresponding simpleType
  72     XSSimpleType fXSSimpleType = null;
  73 
  74     // if the content type is element or mixed, the particle
  75     XSParticleDecl fParticle = null;
  76 
  77     // if there is a particle, the content model corresponding to that particle
  78     volatile XSCMValidator fCMValidator = null;
  79 
  80     // the content model that's sufficient for computing UPA
  81     volatile XSCMValidator fUPACMValidator = null;
  82 
  83     // list of annotations affiliated with this type
  84     XSObjectListImpl fAnnotations = null;
  85 
  86     // The namespace schema information item corresponding to the target namespace
  87     // of the complex type definition, if it is globally declared; or null otherwise.
  88     private XSNamespaceItem fNamespaceItem = null;
  89 
  90     // DOM Level 3 TypeInfo Derivation Method constants
  91     static final int DERIVATION_ANY = 0;
  92     static final int DERIVATION_RESTRICTION = 1;
  93     static final int DERIVATION_EXTENSION = 2;
  94     static final int DERIVATION_UNION = 4;
  95     static final int DERIVATION_LIST = 8;
  96 
  97     public XSComplexTypeDecl() {
  98         // do-nothing constructor for now.
  99     }
 100 
 101     public void setValues(String name, String targetNamespace,
 102             XSTypeDefinition baseType, short derivedBy, short schemaFinal,
 103             short block, short contentType,
 104             boolean isAbstract, XSAttributeGroupDecl attrGrp,
 105             XSSimpleType simpleType, XSParticleDecl particle,
 106             XSObjectListImpl annotations) {
 107         fTargetNamespace = targetNamespace;
 108         fBaseType = baseType;
 109         fDerivedBy = derivedBy;
 110         fFinal = schemaFinal;
 111         fBlock = block;
 112         fContentType = contentType;
 113         if(isAbstract)
 114             fMiscFlags |= CT_IS_ABSTRACT;
 115         fAttrGrp = attrGrp;
 116         fXSSimpleType = simpleType;
 117         fParticle = particle;
 118         fAnnotations = annotations;
 119    }
 120 
 121    public void setName(String name) {
 122         fName = name;
 123    }
 124 
 125     public short getTypeCategory() {
 126         return COMPLEX_TYPE;
 127     }
 128 
 129     public String getTypeName() {
 130         return fName;
 131     }
 132 
 133     public short getFinalSet(){
 134         return fFinal;
 135     }
 136 
 137     public String getTargetNamespace(){
 138         return fTargetNamespace;
 139     }
 140 
 141     // flags for the misc flag
 142     private static final short CT_IS_ABSTRACT = 1;
 143     private static final short CT_HAS_TYPE_ID = 2;
 144     private static final short CT_IS_ANONYMOUS = 4;
 145 
 146     // methods to get/set misc flag
 147 
 148     public boolean containsTypeID () {
 149         return((fMiscFlags & CT_HAS_TYPE_ID) != 0);
 150     }
 151 
 152     public void setIsAbstractType() {
 153         fMiscFlags |= CT_IS_ABSTRACT;
 154     }
 155     public void setContainsTypeID() {
 156         fMiscFlags |= CT_HAS_TYPE_ID;
 157     }
 158     public void setIsAnonymous() {
 159         fMiscFlags |= CT_IS_ANONYMOUS;
 160     }
 161 
 162     public XSCMValidator getContentModel(CMBuilder cmBuilder) {
 163         // for complex type with empty or simple content,
 164         // there is no content model validator
 165         if (fContentType == XSComplexTypeDecl.CONTENTTYPE_SIMPLE ||
 166             fContentType == XSComplexTypeDecl.CONTENTTYPE_EMPTY) {
 167             return null;
 168         }
 169         if (fCMValidator == null) {
 170             fCMValidator = getContentModel(cmBuilder, false);
 171         }
 172         return fCMValidator;
 173     }
 174 
 175     public synchronized XSCMValidator getContentModel(CMBuilder cmBuilder, boolean forUPA) {
 176         if (fCMValidator == null) {
 177             if (forUPA) {
 178                 if (fUPACMValidator == null) {
 179                     fUPACMValidator = cmBuilder.getContentModel(this, true);
 180 
 181                     if (fUPACMValidator != null && !fUPACMValidator.isCompactedForUPA()) {
 182                         fCMValidator = fUPACMValidator;
 183                     }
 184                 }
 185                 return fUPACMValidator;
 186             }
 187             else {
 188                 fCMValidator = cmBuilder.getContentModel(this, false);
 189             }
 190         }
 191         return fCMValidator;
 192     }
 193 
 194     // some utility methods:
 195 
 196     // return the attribute group for this complex type
 197     public XSAttributeGroupDecl getAttrGrp() {
 198         return fAttrGrp;
 199     }
 200 
 201     public String toString() {
 202         StringBuilder str = new StringBuilder(192);
 203         appendTypeInfo(str);
 204         return str.toString();
 205     }
 206 
 207     void appendTypeInfo(StringBuilder str) {
 208         String contentType[] = {"EMPTY", "SIMPLE", "ELEMENT", "MIXED"};
 209         String derivedBy[] = {"EMPTY", "EXTENSION", "RESTRICTION"};
 210 
 211         str.append("Complex type name='").append(fTargetNamespace).append(',').append(getTypeName()).append("', ");
 212         if (fBaseType != null) {
 213             str.append(" base type name='").append(fBaseType.getName()).append("', ");
 214         }
 215         str.append(" content type='").append(contentType[fContentType]).append("', ");
 216         str.append(" isAbstract='").append(getAbstract()).append("', ");
 217         str.append(" hasTypeId='").append(containsTypeID()).append("', ");
 218         str.append(" final='").append(fFinal).append("', ");
 219         str.append(" block='").append(fBlock).append("', ");
 220         if (fParticle != null) {
 221             str.append(" particle='").append(fParticle.toString()).append("', ");
 222         }
 223         str.append(" derivedBy='").append(derivedBy[fDerivedBy]).append("'. ");
 224 
 225     }
 226 
 227     public boolean derivedFromType(XSTypeDefinition ancestor, short derivationMethod) {
 228         // ancestor is null, retur false
 229         if (ancestor == null)
 230             return false;
 231         // ancestor is anyType, return true
 232         if (ancestor == SchemaGrammar.fAnyType)
 233             return true;
 234         // recursively get base, and compare it with ancestor
 235         XSTypeDefinition type = this;
 236         while (type != ancestor &&                     // compare with ancestor
 237                type != SchemaGrammar.fAnySimpleType &&  // reached anySimpleType
 238                type != SchemaGrammar.fAnyType) {        // reached anyType
 239             type = type.getBaseType();
 240         }
 241 
 242         return type == ancestor;
 243     }
 244 
 245     public boolean derivedFrom(String ancestorNS, String ancestorName, short derivationMethod) {
 246         // ancestor is null, retur false
 247         if (ancestorName == null)
 248             return false;
 249         // ancestor is anyType, return true
 250         if (ancestorNS != null &&
 251             ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
 252             ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
 253             return true;
 254         }
 255 
 256         // recursively get base, and compare it with ancestor
 257         XSTypeDefinition type = this;
 258         while (!(ancestorName.equals(type.getName()) &&
 259                  ((ancestorNS == null && type.getNamespace() == null) ||
 260                   (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) &&   // compare with ancestor
 261                type != SchemaGrammar.fAnySimpleType &&  // reached anySimpleType
 262                type != SchemaGrammar.fAnyType) {        // reached anyType
 263             type = type.getBaseType();
 264         }
 265 
 266         return type != SchemaGrammar.fAnySimpleType &&
 267         type != SchemaGrammar.fAnyType;
 268     }
 269 
 270     /**
 271      * Checks if a type is derived from another given the the name, namespace
 272      * and derivation method. See:
 273      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 274      *
 275      * @param ancestorNS
 276      *            The namspace of the ancestor type declaration
 277      * @param ancestorName
 278      *            The name of the ancestor type declaration
 279      * @param derivationMethod
 280      *            The derivation method
 281      *
 282      * @return boolean True if the ancestor type is derived from the reference
 283      *         type by the specifiied derivation method.
 284      */
 285     public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName,
 286             int derivationMethod) {
 287         // ancestor is null, retur false
 288         if (ancestorName == null)
 289             return false;
 290 
 291         // ancestor is anyType, return true
 292         if (ancestorNS != null
 293                 && ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 294                 && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)
 295                 && (derivationMethod == DERIVATION_RESTRICTION
 296                 && derivationMethod == DERIVATION_EXTENSION)) {
 297             return true;
 298         }
 299 
 300         // restriction
 301         if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
 302             if (isDerivedByRestriction(ancestorNS, ancestorName,
 303                     derivationMethod, this)) {
 304                 return true;
 305             }
 306         }
 307 
 308         // extension
 309         if ((derivationMethod & DERIVATION_EXTENSION) != 0) {
 310             if (isDerivedByExtension(ancestorNS, ancestorName,
 311                     derivationMethod, this)) {
 312                 return true;
 313             }
 314         }
 315 
 316         // list or union
 317         if ((((derivationMethod & DERIVATION_LIST) != 0) || ((derivationMethod & DERIVATION_UNION) != 0))
 318                 && ((derivationMethod & DERIVATION_RESTRICTION) == 0)
 319                 && ((derivationMethod & DERIVATION_EXTENSION) == 0)) {
 320 
 321             if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 322                     && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
 323                 ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
 324             }
 325 
 326             if(!(fName.equals(SchemaSymbols.ATTVAL_ANYTYPE)
 327                             && fTargetNamespace.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))){
 328                 if (fBaseType != null && fBaseType instanceof XSSimpleTypeDecl) {
 329 
 330                     return ((XSSimpleTypeDecl) fBaseType).isDOMDerivedFrom(ancestorNS,
 331                             ancestorName, derivationMethod);
 332                 } else if (fBaseType != null
 333                         && fBaseType instanceof XSComplexTypeDecl) {
 334                     return ((XSComplexTypeDecl) fBaseType).isDOMDerivedFrom(
 335                             ancestorNS, ancestorName, derivationMethod);
 336                 }
 337             }
 338         }
 339 
 340         // If the value of the parameter is 0 i.e. no bit (corresponding to
 341         // restriction, list, extension or union) is set to 1 for the
 342         // derivationMethod parameter.
 343         if (((derivationMethod  & DERIVATION_EXTENSION) == 0)
 344                 && (((derivationMethod & DERIVATION_RESTRICTION) == 0)
 345                         && ((derivationMethod & DERIVATION_LIST) == 0)
 346                         && ((derivationMethod & DERIVATION_UNION) == 0))) {
 347             return isDerivedByAny(ancestorNS, ancestorName, derivationMethod, this);
 348         }
 349 
 350         return false;
 351     }
 352 
 353     /**
 354      * Checks if a type is derived from another by any combination of
 355      * restriction, list ir union. See:
 356      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 357      *
 358      * @param ancestorNS
 359      *            The namspace of the ancestor type declaration
 360      * @param ancestorName
 361      *            The name of the ancestor type declaration
 362      * @param derivationMethod
 363      *            A short indication the method of derivation
 364      * @param type
 365      *            The reference type definition
 366      *
 367      * @return boolean True if the type is derived by any method for the
 368      *         reference type
 369      */
 370     private boolean isDerivedByAny(String ancestorNS, String ancestorName,
 371             int derivationMethod, XSTypeDefinition type) {
 372         XSTypeDefinition oldType = null;
 373         boolean derivedFrom = false;
 374         while (type != null && type != oldType) {
 375 
 376             // If the ancestor type is reached or is the same as this type.
 377             if ((ancestorName.equals(type.getName()))
 378                     && ((ancestorNS == null && type.getNamespace() == null)
 379                         || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
 380                 derivedFrom = true;
 381                 break;
 382             }
 383 
 384             // Check if this type is derived from the base by restriction or
 385             // extension
 386             if (isDerivedByRestriction(ancestorNS, ancestorName,
 387                     derivationMethod, type)) {
 388                 return true;
 389             } else if (!isDerivedByExtension(ancestorNS, ancestorName,
 390                     derivationMethod, type)) {
 391                 return true;
 392             }
 393             oldType = type;
 394             type = type.getBaseType();
 395         }
 396 
 397         return derivedFrom;
 398     }
 399 
 400     /**
 401      * Checks if a type is derived from another by restriction. See:
 402      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 403      *
 404      * @param ancestorNS
 405      *            The namspace of the ancestor type declaration
 406      * @param ancestorName
 407      *            The name of the ancestor type declaration
 408      * @param derivationMethod
 409      *            A short indication the method of derivation *
 410      * @param type
 411      *            The reference type definition
 412      *
 413      * @return boolean True if the type is derived by restriciton for the
 414      *         reference type
 415      */
 416     private boolean isDerivedByRestriction(String ancestorNS,
 417             String ancestorName, int derivationMethod, XSTypeDefinition type) {
 418 
 419         XSTypeDefinition oldType = null;
 420         while (type != null && type != oldType) {
 421 
 422             // ancestor is anySimpleType, return false
 423             if (ancestorNS != null
 424                     && ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 425                     && ancestorName.equals(SchemaSymbols.ATTVAL_ANYSIMPLETYPE)) {
 426                 return false;
 427             }
 428 
 429             // if the name and namespace of this type is the same as the
 430             // ancestor return true
 431             if ((ancestorName.equals(type.getName()))
 432                     && (ancestorNS != null && ancestorNS.equals(type.getNamespace()))
 433                             || ((type.getNamespace() == null && ancestorNS == null))) {
 434 
 435                 return true;
 436             }
 437 
 438             // If the base type is a complexType with simpleContent
 439             if (type instanceof XSSimpleTypeDecl) {
 440                 if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 441                         && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
 442                     ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
 443                 }
 444                 return ((XSSimpleTypeDecl) type).isDOMDerivedFrom(ancestorNS,
 445                         ancestorName, derivationMethod);
 446             } else {
 447                 // If the base type is a complex type
 448                 // Every derivation step till the base type should be
 449                 // restriction. If not return false
 450                 if (((XSComplexTypeDecl) type).getDerivationMethod() != XSConstants.DERIVATION_RESTRICTION) {
 451                     return false;
 452                 }
 453             }
 454             oldType = type;
 455             type = type.getBaseType();
 456 
 457         }
 458 
 459         return false;
 460     }
 461 
 462     /**
 463      * Checks if a type is derived from another by extension. See:
 464      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
 465      *
 466      * @param ancestorNS
 467      *            The namspace of the ancestor type declaration
 468      * @param ancestorName
 469      *            The name of the ancestor type declaration
 470      * @param derivationMethod
 471      *            A short indication the method of derivation
 472      * @param type
 473      *            The reference type definition
 474      *
 475      * @return boolean True if the type is derived by extension for the
 476      *         reference type
 477      */
 478     private boolean isDerivedByExtension(String ancestorNS,
 479             String ancestorName, int derivationMethod, XSTypeDefinition type) {
 480 
 481         boolean extension = false;
 482         XSTypeDefinition oldType = null;
 483         while (type != null && type != oldType) {
 484             // If ancestor is anySimpleType return false.
 485             if (ancestorNS != null
 486                     && ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 487                     && ancestorName.equals(SchemaSymbols.ATTVAL_ANYSIMPLETYPE)
 488                     && SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(type.getNamespace())
 489                             && SchemaSymbols.ATTVAL_ANYTYPE.equals(type.getName())) {
 490                 break;
 491             }
 492 
 493             if ((ancestorName.equals(type.getName()))
 494                     && ((ancestorNS == null && type.getNamespace() == null)
 495                         || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
 496                 // returns true if atleast one derivation step was extension
 497                 return extension;
 498             }
 499 
 500             // If the base type is a complexType with simpleContent
 501             if (type instanceof XSSimpleTypeDecl) {
 502                 if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
 503                         && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
 504                     ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
 505                 }
 506 
 507                 // derivationMethod extension will always return false for a
 508                 // simpleType,
 509                 // we treat it like a restriction
 510                 if ((derivationMethod & DERIVATION_EXTENSION) != 0) {
 511                     return extension
 512                     & ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
 513                             ancestorNS, ancestorName,
 514                             (derivationMethod & DERIVATION_RESTRICTION));
 515                 } else {
 516                     return extension
 517                     & ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
 518                             ancestorNS, ancestorName, derivationMethod);
 519                 }
 520 
 521             } else {
 522                 // If the base type is a complex type
 523                 // At least one derivation step upto the ancestor type should be
 524                 // extension.
 525                 if (((XSComplexTypeDecl) type).getDerivationMethod() == XSConstants.DERIVATION_EXTENSION) {
 526                     extension = extension | true;
 527                 }
 528             }
 529             oldType = type;
 530             type = type.getBaseType();
 531         }
 532 
 533         return false;
 534     }
 535 
 536 
 537 
 538     public void reset(){
 539         fName = null;
 540         fTargetNamespace = null;
 541         fBaseType = null;
 542         fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
 543         fFinal = XSConstants.DERIVATION_NONE;
 544         fBlock = XSConstants.DERIVATION_NONE;
 545 
 546         fMiscFlags = 0;
 547 
 548         // reset attribute group
 549         fAttrGrp.reset();
 550         fContentType = CONTENTTYPE_EMPTY;
 551         fXSSimpleType = null;
 552         fParticle = null;
 553         fCMValidator = null;
 554         fUPACMValidator = null;
 555         if(fAnnotations != null) {
 556             // help out the garbage collector
 557             fAnnotations.clearXSObjectList();
 558         }
 559         fAnnotations = null;
 560     }
 561 
 562     /**
 563      * Get the type of the object, i.e ELEMENT_DECLARATION.
 564      */
 565     public short getType() {
 566         return XSConstants.TYPE_DEFINITION;
 567     }
 568 
 569     /**
 570      * The <code>name</code> of this <code>XSObject</code> depending on the
 571      * <code>XSObject</code> type.
 572      */
 573     public String getName() {
 574         return getAnonymous() ? null : fName;
 575     }
 576 
 577     /**
 578      * A boolean that specifies if the type definition is anonymous.
 579      * Convenience attribute. This is a field is not part of
 580      * XML Schema component model.
 581      */
 582     public boolean getAnonymous() {
 583         return((fMiscFlags & CT_IS_ANONYMOUS) != 0);
 584     }
 585 
 586     /**
 587      * The namespace URI of this node, or <code>null</code> if it is
 588      * unspecified.  defines how a namespace URI is attached to schema
 589      * components.
 590      */
 591     public String getNamespace() {
 592         return fTargetNamespace;
 593     }
 594 
 595     /**
 596      * {base type definition} Either a simple type definition or a complex
 597      * type definition.
 598      */
 599     public XSTypeDefinition getBaseType() {
 600         return fBaseType;
 601     }
 602 
 603     /**
 604      * {derivation method} Either extension or restriction. The valid constant
 605      * value for this <code>XSConstants</code> EXTENTION, RESTRICTION.
 606      */
 607     public short getDerivationMethod() {
 608         return fDerivedBy;
 609     }
 610 
 611     /**
 612      * {final} For complex type definition it is a subset of {extension,
 613      * restriction}. For simple type definition it is a subset of
 614      * {extension, list, restriction, union}.
 615      * @param derivation  Extension, restriction, list, union constants
 616      *   (defined in <code>XSConstants</code>).
 617      * @return True if derivation is in the final set, otherwise false.
 618      */
 619     public boolean isFinal(short derivation) {
 620         return (fFinal & derivation) != 0;
 621     }
 622 
 623     /**
 624      * {final} For complex type definition it is a subset of {extension, restriction}.
 625      *
 626      * @return A bit flag that represents:
 627      *         {extension, restriction) or none for complexTypes;
 628      *         {extension, list, restriction, union} or none for simpleTypes;
 629      */
 630     public short getFinal() {
 631         return fFinal;
 632     }
 633 
 634     /**
 635      * {abstract} A boolean. Complex types for which {abstract} is true must
 636      * not be used as the {type definition} for the validation of element
 637      * information items.
 638      */
 639     public boolean getAbstract() {
 640         return((fMiscFlags & CT_IS_ABSTRACT) != 0);
 641     }
 642 
 643     /**
 644      *  {attribute uses} A set of attribute uses.
 645      */
 646     public XSObjectList getAttributeUses() {
 647         return fAttrGrp.getAttributeUses();
 648     }
 649 
 650     /**
 651      * {attribute wildcard} Optional. A wildcard.
 652      */
 653     public XSWildcard getAttributeWildcard() {
 654         return fAttrGrp.getAttributeWildcard();
 655     }
 656 
 657     /**
 658      * {content type} One of empty, a simple type definition (see
 659      * <code>simpleType</code>, or mixed, element-only (see
 660      * <code>cmParticle</code>).
 661      */
 662     public short getContentType() {
 663         return fContentType;
 664     }
 665 
 666     /**
 667      * A simple type definition corresponding to simple content model,
 668      * otherwise <code>null</code>
 669      */
 670     public XSSimpleTypeDefinition getSimpleType() {
 671         return fXSSimpleType;
 672     }
 673 
 674     /**
 675      * A particle for mixed or element-only content model, otherwise
 676      * <code>null</code>
 677      */
 678     public XSParticle getParticle() {
 679         return fParticle;
 680     }
 681 
 682     /**
 683      * {prohibited substitutions} A subset of {extension, restriction}.
 684      * @param prohibited  extention or restriction constants (defined in
 685      *   <code>XSConstants</code>).
 686      * @return True if prohibited is a prohibited substitution, otherwise
 687      *   false.
 688      */
 689     public boolean isProhibitedSubstitution(short prohibited) {
 690         return (fBlock & prohibited) != 0;
 691     }
 692 
 693     /**
 694      * {prohibited substitutions}
 695      *
 696      * @return A bit flag corresponding to prohibited substitutions
 697      */
 698     public short getProhibitedSubstitutions() {
 699         return fBlock;
 700     }
 701 
 702     /**
 703      * Optional. Annotation.
 704      */
 705     public XSObjectList getAnnotations() {
 706         return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
 707     }
 708 
 709     /**
 710      * @see org.apache.xerces.xs.XSObject#getNamespaceItem()
 711      */
 712     public XSNamespaceItem getNamespaceItem() {
 713         return fNamespaceItem;
 714     }
 715 
 716     void setNamespaceItem(XSNamespaceItem namespaceItem) {
 717         fNamespaceItem = namespaceItem;
 718     }
 719 
 720     /* (non-Javadoc)
 721      * @see org.apache.xerces.xs.XSComplexTypeDefinition#getAttributeUse(java.lang.String, java.lang.String)
 722      */
 723     public XSAttributeUse getAttributeUse(String namespace, String name) {
 724          return fAttrGrp.getAttributeUse(namespace, name);
 725     }
 726 
 727     public String getTypeNamespace() {
 728         return getNamespace();
 729     }
 730 
 731     public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) {
 732         return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
 733     }
 734 
 735 } // class XSComplexTypeDecl