2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
18
package org.apache.xerces.impl.xs;
20
import org.apache.xerces.impl.dv.XSSimpleType;
21
import org.apache.xerces.xs.*;
22
import org.apache.xerces.impl.xs.models.XSCMValidator;
23
import org.apache.xerces.impl.xs.models.CMBuilder;
24
import org.apache.xerces.impl.xs.util.XSObjectListImpl;
25
import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
26
import org.w3c.dom.TypeInfo;
29
* The XML representation for a complexType
30
* schema component is a <complexType> element information item
34
* @author Elena Litani, IBM
35
* @author Sandy Gao, IBM
36
* @version $Id: XSComplexTypeDecl.java,v 1.2 2009/12/10 03:18:27 matthewoliver Exp $
38
public class XSComplexTypeDecl implements XSComplexTypeDefinition, TypeInfo {
40
// name of the complexType
43
// target namespace of the complexType
44
String fTargetNamespace = null;
46
// base type of the complexType
47
XSTypeDefinition fBaseType = null;
49
// derivation method of the complexType
50
short fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
52
// final set of the complexType
53
short fFinal = XSConstants.DERIVATION_NONE;
55
// block set (prohibited substitution) of the complexType
56
short fBlock = XSConstants.DERIVATION_NONE;
58
// flags: whether is abstract; whether contains ID type;
59
// whether it's an anonymous tpye
62
// the attribute group that holds the attribute uses and attribute wildcard
63
XSAttributeGroupDecl fAttrGrp = null;
65
// the content type of the complexType
66
short fContentType = CONTENTTYPE_EMPTY;
68
// if the content type is simple, then the corresponding simpleType
69
XSSimpleType fXSSimpleType = null;
71
// if the content type is element or mixed, the particle
72
XSParticleDecl fParticle = null;
74
// if there is a particle, the content model corresponding to that particle
75
XSCMValidator fCMValidator = null;
77
// the content model that's sufficient for computing UPA
78
XSCMValidator fUPACMValidator = null;
80
// list of annotations affiliated with this type
81
XSObjectListImpl fAnnotations = null;
83
// DOM Level 3 TypeInfo Derivation Method constants
84
static final int DERIVATION_ANY = 0;
85
static final int DERIVATION_RESTRICTION = 1;
86
static final int DERIVATION_EXTENSION = 2;
87
static final int DERIVATION_UNION = 4;
88
static final int DERIVATION_LIST = 8;
90
public XSComplexTypeDecl() {
91
// do-nothing constructor for now.
94
public void setValues(String name, String targetNamespace,
95
XSTypeDefinition baseType, short derivedBy, short schemaFinal,
96
short block, short contentType,
97
boolean isAbstract, XSAttributeGroupDecl attrGrp,
98
XSSimpleType simpleType, XSParticleDecl particle,
99
XSObjectListImpl annotations) {
100
fTargetNamespace = targetNamespace;
101
fBaseType = baseType;
102
fDerivedBy = derivedBy;
103
fFinal = schemaFinal;
105
fContentType = contentType;
107
fMiscFlags |= CT_IS_ABSTRACT;
109
fXSSimpleType = simpleType;
110
fParticle = particle;
111
fAnnotations = annotations;
114
public void setName(String name) {
118
public short getTypeCategory() {
122
public String getTypeName() {
126
public short getFinalSet(){
130
public String getTargetNamespace(){
131
return fTargetNamespace;
134
// flags for the misc flag
135
private static final short CT_IS_ABSTRACT = 1;
136
private static final short CT_HAS_TYPE_ID = 2;
137
private static final short CT_IS_ANONYMOUS = 4;
139
// methods to get/set misc flag
141
public boolean containsTypeID () {
142
return((fMiscFlags & CT_HAS_TYPE_ID) != 0);
145
public void setIsAbstractType() {
146
fMiscFlags |= CT_IS_ABSTRACT;
148
public void setContainsTypeID() {
149
fMiscFlags |= CT_HAS_TYPE_ID;
151
public void setIsAnonymous() {
152
fMiscFlags |= CT_IS_ANONYMOUS;
155
public XSCMValidator getContentModel(CMBuilder cmBuilder) {
156
return getContentModel(cmBuilder, false);
159
public synchronized XSCMValidator getContentModel(CMBuilder cmBuilder, boolean forUPA) {
160
if (fCMValidator == null) {
162
if (fUPACMValidator == null) {
163
fUPACMValidator = cmBuilder.getContentModel(this, true);
165
if (fUPACMValidator != null && !fUPACMValidator.isCompactedForUPA()) {
166
fCMValidator = fUPACMValidator;
169
return fUPACMValidator;
172
fCMValidator = cmBuilder.getContentModel(this, false);
179
// some utility methods:
181
// return the attribute group for this complex type
182
public XSAttributeGroupDecl getAttrGrp() {
186
public String toString() {
187
StringBuffer str = new StringBuffer();
189
return str.toString();
192
void appendTypeInfo(StringBuffer str) {
193
String contentType[] = {"EMPTY", "SIMPLE", "ELEMENT", "MIXED"};
194
String derivedBy[] = {"EMPTY", "EXTENSION", "RESTRICTION"};
196
str.append("Complex type name='").append(fTargetNamespace).append(",").append(getTypeName()).append("', ");
197
if (fBaseType != null) {
198
str.append(" base type name='").append(fBaseType.getName()).append("', ");
200
str.append(" content type='").append(contentType[fContentType]).append("', ");
201
str.append(" isAbstract='").append(getAbstract()).append("', ");
202
str.append(" hasTypeId='").append(containsTypeID()).append("', ");
203
str.append(" final='").append(fFinal).append("', ");
204
str.append(" block='").append(fBlock).append("', ");
205
if (fParticle != null) {
206
str.append(" particle='").append(fParticle.toString()).append("', ");
208
str.append(" derivedBy='").append(derivedBy[fDerivedBy]).append("'. ");
212
public boolean derivedFromType(XSTypeDefinition ancestor, short derivationMethod) {
213
// ancestor is null, retur false
214
if (ancestor == null)
216
// ancestor is anyType, return true
217
if (ancestor == SchemaGrammar.fAnyType)
219
// recursively get base, and compare it with ancestor
220
XSTypeDefinition type = this;
221
while (type != ancestor && // compare with ancestor
222
type != SchemaGrammar.fAnySimpleType && // reached anySimpleType
223
type != SchemaGrammar.fAnyType) { // reached anyType
224
type = type.getBaseType();
227
return type == ancestor;
230
public boolean derivedFrom(String ancestorNS, String ancestorName, short derivationMethod) {
231
// ancestor is null, retur false
232
if (ancestorName == null)
234
// ancestor is anyType, return true
235
if (ancestorNS != null &&
236
ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) &&
237
ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
241
// recursively get base, and compare it with ancestor
242
XSTypeDefinition type = this;
243
while (!(ancestorName.equals(type.getName()) &&
244
((ancestorNS == null && type.getNamespace() == null) ||
245
(ancestorNS != null && ancestorNS.equals(type.getNamespace())))) && // compare with ancestor
246
type != SchemaGrammar.fAnySimpleType && // reached anySimpleType
247
type != SchemaGrammar.fAnyType) { // reached anyType
248
type = (XSTypeDefinition)type.getBaseType();
251
return type != SchemaGrammar.fAnySimpleType &&
252
type != SchemaGrammar.fAnyType;
256
* Checks if a type is derived from another given the the name, namespace
257
* and derivation method. See:
258
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
261
* The namspace of the ancestor type declaration
262
* @param ancestorName
263
* The name of the ancestor type declaration
264
* @param derivationMethod
265
* The derivation method
267
* @return boolean True if the ancestor type is derived from the reference
268
* type by the specifiied derivation method.
270
public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName,
271
int derivationMethod) {
272
// ancestor is null, retur false
273
if (ancestorName == null)
276
// ancestor is anyType, return true
277
if (ancestorNS != null
278
&& ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
279
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)
280
&& (derivationMethod == DERIVATION_RESTRICTION
281
&& derivationMethod == DERIVATION_EXTENSION)) {
286
if ((derivationMethod & DERIVATION_RESTRICTION) != 0) {
287
if (isDerivedByRestriction(ancestorNS, ancestorName,
288
derivationMethod, this)) {
294
if ((derivationMethod & DERIVATION_EXTENSION) != 0) {
295
if (isDerivedByExtension(ancestorNS, ancestorName,
296
derivationMethod, this)) {
302
if ((((derivationMethod & DERIVATION_LIST) != 0) || ((derivationMethod & DERIVATION_UNION) != 0))
303
&& ((derivationMethod & DERIVATION_RESTRICTION) == 0)
304
&& ((derivationMethod & DERIVATION_EXTENSION) == 0)) {
306
if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
307
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
308
ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
311
if(!(fName.equals(SchemaSymbols.ATTVAL_ANYTYPE)
312
&& fTargetNamespace.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))){
313
if (fBaseType != null && fBaseType instanceof XSSimpleTypeDecl) {
315
return ((XSSimpleTypeDecl) fBaseType).isDOMDerivedFrom(ancestorNS,
316
ancestorName, derivationMethod);
317
} else if (fBaseType != null
318
&& fBaseType instanceof XSComplexTypeDecl) {
319
return ((XSComplexTypeDecl) fBaseType).isDOMDerivedFrom(
320
ancestorNS, ancestorName, derivationMethod);
325
// If the value of the parameter is 0 i.e. no bit (corresponding to
326
// restriction, list, extension or union) is set to 1 for the
327
// derivationMethod parameter.
328
if (((derivationMethod & DERIVATION_EXTENSION) == 0)
329
&& (((derivationMethod & DERIVATION_RESTRICTION) == 0)
330
&& ((derivationMethod & DERIVATION_LIST) == 0)
331
&& ((derivationMethod & DERIVATION_UNION) == 0))) {
332
return isDerivedByAny(ancestorNS, ancestorName, derivationMethod, this);
339
* Checks if a type is derived from another by any combination of
340
* restriction, list ir union. See:
341
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
344
* The namspace of the ancestor type declaration
345
* @param ancestorName
346
* The name of the ancestor type declaration
347
* @param derivationMethod
348
* A short indication the method of derivation
350
* The reference type definition
352
* @return boolean True if the type is derived by any method for the
355
private boolean isDerivedByAny(String ancestorNS, String ancestorName,
356
int derivationMethod, XSTypeDefinition type) {
357
XSTypeDefinition oldType = null;
358
boolean derivedFrom = false;
359
while (type != null && type != oldType) {
361
// If the ancestor type is reached or is the same as this type.
362
if ((ancestorName.equals(type.getName()))
363
&& ((ancestorNS == null && type.getNamespace() == null)
364
|| (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
369
// Check if this type is derived from the base by restriction or
371
if (isDerivedByRestriction(ancestorNS, ancestorName,
372
derivationMethod, type)) {
374
} else if (!isDerivedByExtension(ancestorNS, ancestorName,
375
derivationMethod, type)) {
379
type = type.getBaseType();
386
* Checks if a type is derived from another by restriction. See:
387
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
390
* The namspace of the ancestor type declaration
391
* @param ancestorName
392
* The name of the ancestor type declaration
393
* @param derivationMethod
394
* A short indication the method of derivation *
396
* The reference type definition
398
* @return boolean True if the type is derived by restriciton for the
401
private boolean isDerivedByRestriction(String ancestorNS,
402
String ancestorName, int derivationMethod, XSTypeDefinition type) {
404
XSTypeDefinition oldType = null;
405
while (type != null && type != oldType) {
407
// ancestor is anySimpleType, return false
408
if (ancestorNS != null
409
&& ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
410
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYSIMPLETYPE)) {
414
// if the name and namespace of this type is the same as the
415
// ancestor return true
416
if ((ancestorName.equals(type.getName()))
417
&& (ancestorNS != null && ancestorNS.equals(type.getNamespace()))
418
|| ((type.getNamespace() == null && ancestorNS == null))) {
423
// If the base type is a complexType with simpleContent
424
if (type instanceof XSSimpleTypeDecl) {
425
if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
426
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
427
ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
429
return ((XSSimpleTypeDecl) type).isDOMDerivedFrom(ancestorNS,
430
ancestorName, derivationMethod);
432
// If the base type is a complex type
433
// Every derivation step till the base type should be
434
// restriction. If not return false
435
if (((XSComplexTypeDecl) type).getDerivationMethod() != XSConstants.DERIVATION_RESTRICTION) {
440
type = type.getBaseType();
448
* Checks if a type is derived from another by extension. See:
449
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom
452
* The namspace of the ancestor type declaration
453
* @param ancestorName
454
* The name of the ancestor type declaration
455
* @param derivationMethod
456
* A short indication the method of derivation
458
* The reference type definition
460
* @return boolean True if the type is derived by extension for the
463
private boolean isDerivedByExtension(String ancestorNS,
464
String ancestorName, int derivationMethod, XSTypeDefinition type) {
466
boolean extension = false;
467
XSTypeDefinition oldType = null;
468
while (type != null && type != oldType) {
469
// If ancestor is anySimpleType return false.
470
if (ancestorNS != null
471
&& ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
472
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYSIMPLETYPE)
473
&& SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(type.getNamespace())
474
&& SchemaSymbols.ATTVAL_ANYTYPE.equals(type.getName())) {
478
if ((ancestorName.equals(type.getName()))
479
&& ((ancestorNS == null && type.getNamespace() == null)
480
|| (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) {
481
// returns true if atleast one derivation step was extension
485
// If the base type is a complexType with simpleContent
486
if (type instanceof XSSimpleTypeDecl) {
487
if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)
488
&& ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) {
489
ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE;
492
// derivationMethod extension will always return false for a
494
// we treat it like a restriction
495
if ((derivationMethod & DERIVATION_EXTENSION) != 0) {
497
& ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
498
ancestorNS, ancestorName,
499
(derivationMethod & DERIVATION_RESTRICTION));
502
& ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
503
ancestorNS, ancestorName, derivationMethod);
507
// If the base type is a complex type
508
// At least one derivation step upto the ancestor type should be
510
if (((XSComplexTypeDecl) type).getDerivationMethod() == XSConstants.DERIVATION_EXTENSION) {
511
extension = extension | true;
515
type = type.getBaseType();
525
fTargetNamespace = null;
527
fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
528
fFinal = XSConstants.DERIVATION_NONE;
529
fBlock = XSConstants.DERIVATION_NONE;
533
// reset attribute group
535
fContentType = CONTENTTYPE_EMPTY;
536
fXSSimpleType = null;
539
fUPACMValidator = null;
540
if(fAnnotations != null) {
541
// help out the garbage collector
542
fAnnotations.clear();
548
* Get the type of the object, i.e ELEMENT_DECLARATION.
550
public short getType() {
551
return XSConstants.TYPE_DEFINITION;
555
* The <code>name</code> of this <code>XSObject</code> depending on the
556
* <code>XSObject</code> type.
558
public String getName() {
559
return getAnonymous() ? null : fName;
563
* A boolean that specifies if the type definition is anonymous.
564
* Convenience attribute. This is a field is not part of
565
* XML Schema component model.
567
public boolean getAnonymous() {
568
return((fMiscFlags & CT_IS_ANONYMOUS) != 0);
572
* The namespace URI of this node, or <code>null</code> if it is
573
* unspecified. defines how a namespace URI is attached to schema
576
public String getNamespace() {
577
return fTargetNamespace;
581
* {base type definition} Either a simple type definition or a complex
584
public XSTypeDefinition getBaseType() {
589
* {derivation method} Either extension or restriction. The valid constant
590
* value for this <code>XSConstants</code> EXTENTION, RESTRICTION.
592
public short getDerivationMethod() {
597
* {final} For complex type definition it is a subset of {extension,
598
* restriction}. For simple type definition it is a subset of
599
* {extension, list, restriction, union}.
600
* @param derivation Extension, restriction, list, union constants
601
* (defined in <code>XSConstants</code>).
602
* @return True if derivation is in the final set, otherwise false.
604
public boolean isFinal(short derivation) {
605
return (fFinal & derivation) != 0;
609
* {final} For complex type definition it is a subset of {extension, restriction}.
611
* @return A bit flag that represents:
612
* {extension, restriction) or none for complexTypes;
613
* {extension, list, restriction, union} or none for simpleTypes;
615
public short getFinal() {
620
* {abstract} A boolean. Complex types for which {abstract} is true must
621
* not be used as the {type definition} for the validation of element
624
public boolean getAbstract() {
625
return((fMiscFlags & CT_IS_ABSTRACT) != 0);
629
* {attribute uses} A set of attribute uses.
631
public XSObjectList getAttributeUses() {
632
return fAttrGrp.getAttributeUses();
636
* {attribute wildcard} Optional. A wildcard.
638
public XSWildcard getAttributeWildcard() {
639
return fAttrGrp.getAttributeWildcard();
643
* {content type} One of empty, a simple type definition (see
644
* <code>simpleType</code>, or mixed, element-only (see
645
* <code>cmParticle</code>).
647
public short getContentType() {
652
* A simple type definition corresponding to simple content model,
653
* otherwise <code>null</code>
655
public XSSimpleTypeDefinition getSimpleType() {
656
return fXSSimpleType;
660
* A particle for mixed or element-only content model, otherwise
663
public XSParticle getParticle() {
668
* {prohibited substitutions} A subset of {extension, restriction}.
669
* @param prohibited extention or restriction constants (defined in
670
* <code>XSConstants</code>).
671
* @return True if prohibited is a prohibited substitution, otherwise
674
public boolean isProhibitedSubstitution(short prohibited) {
675
return (fBlock & prohibited) != 0;
679
* {prohibited substitutions}
681
* @return A bit flag corresponding to prohibited substitutions
683
public short getProhibitedSubstitutions() {
688
* Optional. Annotation.
690
public XSObjectList getAnnotations() {
691
return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST;
695
* @see org.apache.xerces.xs.XSObject#getNamespaceItem()
697
public XSNamespaceItem getNamespaceItem() {
698
// REVISIT: implement
703
* @see org.apache.xerces.xs.XSComplexTypeDefinition#getAttributeUse(java.lang.String, java.lang.String)
705
public XSAttributeUse getAttributeUse(String namespace, String name) {
706
return fAttrGrp.getAttributeUse(namespace, name);
709
public String getTypeNamespace() {
710
return getNamespace();
713
public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) {
714
return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod);
717
} // class XSComplexTypeDecl