in xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaWalker.java [187:323]
public void walk(XmlSchemaElement element) {
element = getElement(element, false);
final XmlSchemaElement substGroupElem = element;
/*
* If this element is the root of a substitution group, notify the
* visitors.
*/
List<XmlSchemaElement> substitutes = null;
if (elemsBySubstGroup.containsKey(getElementQName(element))) {
substitutes = elemsBySubstGroup.get(element.getQName());
for (XmlSchemaVisitor visitor : visitors) {
visitor.onEnterSubstitutionGroup(substGroupElem);
}
// Force a copy to change the min & max occurs.
element = getElement(element, true);
element.setMinOccurs(XmlSchemaParticle.DEFAULT_MIN_OCCURS);
element.setMaxOccurs(XmlSchemaParticle.DEFAULT_MAX_OCCURS);
}
XmlSchemaType schemaType = element.getSchemaType();
if (schemaType == null) {
final QName typeQName = element.getSchemaTypeName();
if (typeQName != null) {
schemaType = schemasByNamespace.getTypeByName(typeQName);
}
}
if (schemaType != null) {
XmlSchemaScope scope = null;
if ((schemaType.getQName() != null) && scopeCache.containsKey(schemaType.getQName())) {
scope = scopeCache.get(schemaType.getQName());
} else {
scope = new XmlSchemaScope(schemaType, schemasByNamespace, scopeCache, userRecognizedTypes);
if (schemaType.getQName() != null) {
scopeCache.put(schemaType.getQName(), scope);
}
}
// 1. Fetch all attributes as a List<XmlSchemaAttribute>.
final Collection<XmlSchemaAttrInfo> attrs = scope.getAttributesInScope();
final XmlSchemaTypeInfo typeInfo = scope.getTypeInfo();
// 2. for each visitor, call visitor.startElement(element, type);
final boolean previouslyVisited = (!element.isAnonymous() && visitedElements.contains(element
.getQName()));
for (XmlSchemaVisitor visitor : visitors) {
visitor.onEnterElement(element, typeInfo, previouslyVisited);
}
if (!element.isAnonymous() && !previouslyVisited) {
visitedElements.add(element.getQName());
}
// If we already visited this element, skip the attributes and
// child.
if (!previouslyVisited) {
// 3. Walk the attributes in the element, retrieving type
// information.
if (attrs != null) {
for (XmlSchemaAttrInfo attr : attrs) {
XmlSchemaType attrType = attr.getAttribute().getSchemaType();
if (attrType != null) {
XmlSchemaScope attrScope;
if ((attrType.getQName() != null) && scopeCache.containsKey(attrType.getQName())) {
attrScope = scopeCache.get(attrType.getQName());
} else {
attrScope = new XmlSchemaScope(attrType,
schemasByNamespace, scopeCache,
userRecognizedTypes);
if (attrType.getName() != null) {
scopeCache.put(attrType.getQName(), attrScope);
}
}
final XmlSchemaTypeInfo attrTypeInfo = attrScope.getTypeInfo();
attr.setType(attrTypeInfo);
}
for (XmlSchemaVisitor visitor : visitors) {
visitor.onVisitAttribute(element, attr);
}
}
}
// 4. Visit the anyAttribute, if any.
if (scope.getAnyAttribute() != null) {
for (XmlSchemaVisitor visitor : visitors) {
visitor.onVisitAnyAttribute(element, scope.getAnyAttribute());
}
}
/*
* 5. Notify that we visited all of the attributes (even if
* there weren't any).
*/
for (XmlSchemaVisitor visitor : visitors) {
visitor.onEndAttributes(element, typeInfo);
}
// 6. Walk the child groups and elements (if any), depth-first.
final XmlSchemaParticle child = scope.getParticle();
if (child != null) {
walk(child);
}
}
/*
* 7. On the way back up, call visitor.endElement(element, type,
* attributes);
*/
for (XmlSchemaVisitor visitor : visitors) {
visitor.onExitElement(element, typeInfo, previouslyVisited);
}
} else if (!element.isAbstract()) {
throw new IllegalStateException("Element " + element.getQName()
+ " is not abstract and has no type.");
}
// 8. Now handle substitute elements, if any.
if (substitutes != null) {
for (XmlSchemaElement substitute : substitutes) {
walk(substitute);
}
for (XmlSchemaVisitor visitor : visitors) {
visitor.onExitSubstitutionGroup(substGroupElem);
}
}
}