public void walk()

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);
            }
        }
    }