* @param vctx validation context
*/
public void applyAndCountUsage(ValidationContext vctx) {
// handle type substitutions for this component
OpenAttrBase component = getComponent();
boolean delete = false;
switch (component.type())
{
case SchemaBase.ATTRIBUTE_TYPE:
{
if (isIgnored()) {
delete = true;
} else {
AttributeElement attr = ((AttributeElement)component);
if (m_overrideType != null) {
attr.setType(m_overrideType);
}
QName type = attr.getType();
if (type == null) {
AttributeElement ref = attr.getReference();
if (ref != null) {
delete = !checkReference(ref);
} else if (!attr.isInlineType()) {
attr.setType(SchemaTypes.ANY_SIMPLE_TYPE.getQName());
}
} else {
QName repl = replaceAndReference(type, vctx);
if (repl == null) {
// TODO optionally make sure the attribute is optional?
delete = true;
} else if (repl != type) {
attr.setType(repl);
}
}
}
break;
}
case SchemaBase.ATTRIBUTEGROUP_TYPE:
{
if (component instanceof AttributeGroupRefElement) {
delete = !checkReference(((AttributeGroupRefElement)component).getReference());
}
break;
}
case SchemaBase.ELEMENT_TYPE:
{
ElementElement elem = ((ElementElement)component);
if (isIgnored()) {
// reference or definition determines handling
QName ref = elem.getRef();
if (ref == null) {
// definition, just delete all content
for (int i = 0; i < elem.getChildCount(); i++) {
elem.detachChild(i);
}
elem.compactChildren();
} else {
// reference may be to other namespace, so convert to qualified name string
StringBuffer buff = new StringBuffer();
buff.append('{');
if (ref.getUri() != null) {
buff.append(ref.getUri());
}
buff.append('}');
buff.append(ref.getName());
elem.setName(buff.toString());
elem.setRef(null);
}
elem.setType(SchemaTypes.ANY_TYPE.getQName());
} else {
if (m_overrideType != null) {
elem.setType(m_overrideType);
}
QName type = elem.getType();
if (type == null) {
delete = !checkReference(elem.getReference());
} else {
QName repl = replaceAndReference(type, vctx);
if (repl == null) {
// TODO optionally make sure the element is optional?
delete = true;
} else if (repl != type) {
elem.setType(repl);
}
}
}
break;
}
case SchemaBase.EXTENSION_TYPE:
case SchemaBase.RESTRICTION_TYPE:
{
CommonTypeDerivation deriv = (CommonTypeDerivation)component;
QName type = deriv.getBase();
if (type != null) {
QName repl = replaceAndReference(type, vctx);
if (repl == null) {
delete = true;
} else if (repl != type) {
deriv.setBase(repl);
}
}
break;
}
case SchemaBase.GROUP_TYPE:
{
if (component instanceof GroupRefElement) {
delete = !checkReference(((GroupRefElement)component).getReference());
}
break;
}
case SchemaBase.LIST_TYPE:
{
ListElement list = ((ListElement)component);
/* // not currently supported - is it needed?
if (m_overrideType != null) {
list.setItemType(m_overrideType);
} */
QName type = list.getItemType();
if (type != null) {
QName repl = replaceAndReference(type, vctx);
if (repl == null) {
delete = true;
} else if (repl != type) {
list.setItemType(repl);
}
}
break;
}
case SchemaBase.UNION_TYPE:
{
UnionElement union = ((UnionElement)component);
QName[] types = union.getMemberTypes();
if (types != null) {
ArrayList repls = new ArrayList();
boolean changed = false;
for (int i = 0; i < types.length; i++) {
QName type = types[i];
QName repl = replaceAndReference(type, vctx);
changed = changed || repl != type;
if (repl != null) {
repls.add(repl);
}
}
if (changed) {
if (repls.size() > 0) {
union.setMemberTypes((QName[])repls.toArray(new QName[repls.size()]));
} else {
union.setMemberTypes(null);
}
}
}
break;
}
}
if (delete) {
// raise deletion to containing removable component
SchemaBase parent = component;
SchemaBase remove = null;
loop: while (parent != null) {
switch (parent.type())
{
case SchemaBase.ATTRIBUTE_TYPE:
case SchemaBase.ATTRIBUTEGROUP_TYPE:
case SchemaBase.ELEMENT_TYPE:
case SchemaBase.GROUP_TYPE:
remove = parent;
break loop;
case SchemaBase.COMPLEXTYPE_TYPE:
case SchemaBase.SIMPLETYPE_TYPE:
remove = parent;
parent = parent.getParent();
break;
default:
if (remove == null) {
parent = parent.getParent();
break;
} else {
break loop;
}
}
}
if (remove == null) {
throw new IllegalStateException("Internal error: no removable ancestor found for component "
+ SchemaUtils.describeComponent(component));
} else {
((ComponentExtension)remove.getExtension()).setRemoved(true);
}
} else {
// process all child component extensions
boolean modified = false;
for (int i = 0; i < component.getChildCount(); i++) {
SchemaBase child = component.getChild(i);
ComponentExtension exten = (ComponentExtension)child.getExtension();
if (!exten.isRemoved()) {
exten.applyAndCountUsage(vctx);
}
if (exten.isRemoved()) {
removeChild(i);
modified = true;
}
}
if (modified) {
component.compactChildren();
}
}
}