in src/org/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.java [682:956]
private void traverseComplexContent(Element complexContentElement,
boolean mixedOnType, XSDocumentInfo schemaDoc,
SchemaGrammar grammar)
throws ComplexTypeRecoverableError {
Object[] complexContentAttrValues = fAttrChecker.checkAttributes(complexContentElement, false,
schemaDoc);
// -----------------------------------------------------------------------
// Determine if this is mixed content
// -----------------------------------------------------------------------
boolean mixedContent = mixedOnType;
Boolean mixedAtt = (Boolean) complexContentAttrValues[XSAttributeChecker.ATTIDX_MIXED];
if (mixedAtt != null) {
mixedContent = mixedAtt.booleanValue();
}
// -----------------------------------------------------------------------
// Since the type must have complex content, set the simple type validators
// to null
// -----------------------------------------------------------------------
fXSSimpleType = null;
Element complexContent = DOMUtil.getFirstChildElement(complexContentElement);
if (complexContent != null && DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
addAnnotation(traverseAnnotationDecl(complexContent, complexContentAttrValues, false, schemaDoc));
complexContent = DOMUtil.getNextSiblingElement(complexContent);
}
else {
String text = DOMUtil.getSyntheticAnnotation(complexContentElement);
if (text != null) {
addAnnotation(traverseSyntheticAnnotation(complexContentElement, text, complexContentAttrValues, false, schemaDoc));
}
}
// If there are no children, return
if (complexContent==null) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.2",
new Object[]{fName,SchemaSymbols.ELT_COMPLEXCONTENT},
complexContentElement);
}
// -----------------------------------------------------------------------
// The content should be either "restriction" or "extension"
// -----------------------------------------------------------------------
String complexContentName = DOMUtil.getLocalName(complexContent);
if (complexContentName.equals(SchemaSymbols.ELT_RESTRICTION))
fDerivedBy = XSConstants.DERIVATION_RESTRICTION;
else if (complexContentName.equals(SchemaSymbols.ELT_EXTENSION))
fDerivedBy = XSConstants.DERIVATION_EXTENSION;
else {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
new Object[]{fName, complexContentName}, complexContent);
}
Element elemTmp = DOMUtil.getNextSiblingElement(complexContent);
if (elemTmp != null) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
String siblingName = DOMUtil.getLocalName(elemTmp);
throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
new Object[]{fName, siblingName}, elemTmp);
}
Object[] derivationTypeAttrValues = fAttrChecker.checkAttributes(complexContent, false,
schemaDoc);
QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE];
// -----------------------------------------------------------------------
// Need a base type. Check that it's a complex type
// -----------------------------------------------------------------------
if (baseTypeName==null) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("s4s-att-must-appear",
new Object[]{complexContentName, "base"}, complexContent);
}
XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc,
XSDHandler.TYPEDECL_TYPE,
baseTypeName,
complexContent);
if (type==null) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError();
}
if (! (type instanceof XSComplexTypeDecl)) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("src-ct.1",
new Object[]{fName, type.getName()}, complexContent);
}
XSComplexTypeDecl baseType = (XSComplexTypeDecl)type;
fBaseType = baseType;
// -----------------------------------------------------------------------
// Check that the base permits the derivation
// -----------------------------------------------------------------------
if ((baseType.getFinal() & fDerivedBy)!=0) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
String errorKey = (fDerivedBy==XSConstants.DERIVATION_EXTENSION) ?
"cos-ct-extends.1.1" : "derivation-ok-restriction.1";
throw new ComplexTypeRecoverableError(errorKey,
new Object[]{fName, fBaseType.getName()}, complexContent);
}
// -----------------------------------------------------------------------
// Skip over any potential annotations
// -----------------------------------------------------------------------
complexContent = DOMUtil.getFirstChildElement(complexContent);
if (complexContent != null) {
// traverse annotation if any
if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) {
addAnnotation(traverseAnnotationDecl(complexContent, derivationTypeAttrValues, false, schemaDoc));
complexContent = DOMUtil.getNextSiblingElement(complexContent);
}
else {
String text = DOMUtil.getSyntheticAnnotation(complexContent);
if (text != null) {
addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc));
}
}
if (complexContent !=null &&
DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)){
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1",
new Object[]{fName,SchemaSymbols.ELT_ANNOTATION}, complexContent);
}
}
else {
String text = DOMUtil.getSyntheticAnnotation(complexContent);
if (text != null) {
addAnnotation(traverseSyntheticAnnotation(complexContent, text, derivationTypeAttrValues, false, schemaDoc));
}
}
// -----------------------------------------------------------------------
// Process the content. Note: should I try to catch any complexType errors
// here in order to return the attr array?
// -----------------------------------------------------------------------
try {
processComplexContent(complexContent, mixedContent, true, schemaDoc,
grammar);
} catch (ComplexTypeRecoverableError e) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw e;
}
// -----------------------------------------------------------------------
// Compose the final content and attribute uses
// -----------------------------------------------------------------------
XSParticleDecl baseContent = (XSParticleDecl)baseType.getParticle();
if (fDerivedBy==XSConstants.DERIVATION_RESTRICTION) {
// This is an RESTRICTION
// N.B. derivation-ok-restriction.5.3 is checked under schema
// full checking. That's because we need to wait until locals are
// traversed so that occurrence information is correct.
if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("derivation-ok-restriction.5.4.1.2",
new Object[]{fName, baseType.getName()},
complexContent);
}
try {
mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, false, complexContent);
} catch (ComplexTypeRecoverableError e) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw e;
}
// Remove prohibited uses. Must be done after merge for RESTRICTION.
fAttrGrp.removeProhibitedAttrs();
if (baseType != SchemaGrammar.fAnyType) {
Object[] errArgs = fAttrGrp.validRestrictionOf(fName, baseType.getAttrGrp());
if (errArgs != null) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1],
errArgs, complexContent);
}
}
}
else {
// This is an EXTENSION
// Create the particle
if (fParticle == null) {
fContentType = baseType.getContentType();
fXSSimpleType = (XSSimpleType)baseType.getSimpleType();
fParticle = baseContent;
}
else if (baseType.getContentType() == XSComplexTypeDecl.CONTENTTYPE_EMPTY) {
}
else {
//
// Check if the contentType of the base is consistent with the new type
// cos-ct-extends.1.4.3.2
if (fContentType == XSComplexTypeDecl.CONTENTTYPE_ELEMENT &&
baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_ELEMENT) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.a",
new Object[]{fName}, complexContent);
}
else if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED &&
baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.b",
new Object[]{fName}, complexContent);
}
// if the content of either type is an "all" model group, error.
if (fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP &&
((XSModelGroupImpl)fParticle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL ||
((XSParticleDecl)baseType.getParticle()).fType == XSParticleDecl.PARTICLE_MODELGROUP &&
((XSModelGroupImpl)(((XSParticleDecl)baseType.getParticle())).fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw new ComplexTypeRecoverableError("cos-all-limited.1.2",
new Object[]{}, complexContent);
}
// the "sequence" model group to contain both particles
XSModelGroupImpl group = new XSModelGroupImpl();
group.fCompositor = XSModelGroupImpl.MODELGROUP_SEQUENCE;
group.fParticleCount = 2;
group.fParticles = new XSParticleDecl[2];
group.fParticles[0] = (XSParticleDecl)baseType.getParticle();
group.fParticles[1] = fParticle;
group.fAnnotations = XSObjectListImpl.EMPTY_LIST;
// the particle to contain the above sequence
XSParticleDecl particle = new XSParticleDecl();
particle.fType = XSParticleDecl.PARTICLE_MODELGROUP;
particle.fValue = group;
particle.fAnnotations = XSObjectListImpl.EMPTY_LIST;
fParticle = particle;
}
// Remove prohibited uses. Must be done before merge for EXTENSION.
fAttrGrp.removeProhibitedAttrs();
try {
mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, true, complexContent);
} catch (ComplexTypeRecoverableError e) {
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
throw e;
}
}
// and *finally* we can legitimately return the attributes!
fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc);
fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc);
} // end of traverseComplexContent