bundles/org.apache.jasper.glassfish/src/org/apache/jasper/compiler/JspDocumentParser.java
public void startElement(
        String uri,
        String localName,
        String qName,
        Attributes attrs)
        throws SAXException {

        AttributesImpl taglibAttrs = null;
        AttributesImpl nonTaglibAttrs = null;
        AttributesImpl nonTaglibXmlnsAttrs = null;

        processChars();

        checkPrefixes(uri, qName, attrs);

        if (directivesOnly &&
            !(JSP_URI.equals(uri) &&
                    (localName.startsWith(DIRECTIVE_ACTION)
                    || localName.startsWith(ROOT_ACTION)))) {
            return;
        }

        // jsp:text must not have any subelements
        if (JSP_URI.equals(uri) && TEXT_ACTION.equals(current.getLocalName())) {
            throw new SAXParseException(
                Localizer.getMessage("jsp.error.text.has_subelement"),
                locator);
        }

        startMark = new Mark(ctxt, path, locator.getLineNumber(),
                             locator.getColumnNumber());

        if (attrs != null) {
            /*
             * Notice that due to a bug in the underlying SAX parser, the
             * attributes must be enumerated in descending order. 
             */
            boolean isTaglib = false;
            for (int i = attrs.getLength() - 1; i >= 0; i--) {
                isTaglib = false;
                String attrQName = attrs.getQName(i);
                if (!attrQName.startsWith("xmlns")) {
                    if (nonTaglibAttrs == null) {
                        nonTaglibAttrs = new AttributesImpl();
                    }
                    nonTaglibAttrs.addAttribute(
                        attrs.getURI(i),
                        attrs.getLocalName(i),
                        attrs.getQName(i),
                        attrs.getType(i),
                        attrs.getValue(i));
                } else {
                    if (attrQName.startsWith("xmlns:jsp")) {
                        isTaglib = true;
                    } else {
                        String attrUri = attrs.getValue(i);
                        // TaglibInfo for this uri already established in
                        // startPrefixMapping
                        isTaglib = pageInfo.hasTaglib(attrUri);
                    }
                    if (isTaglib) {
                        if (taglibAttrs == null) {
                            taglibAttrs = new AttributesImpl();
                        }
                        taglibAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    } else {
                        if (nonTaglibXmlnsAttrs == null) {
                            nonTaglibXmlnsAttrs = new AttributesImpl();
                        }
                        nonTaglibXmlnsAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    }
                }
            }
        }

        Node node = null;

        if (tagDependentPending && JSP_URI.equals(uri) &&
                     localName.equals(BODY_ACTION)) {
            tagDependentPending = false;
            tagDependentNesting++;
            current =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            return;
        }

        if (tagDependentPending && JSP_URI.equals(uri) &&
                     localName.equals(ATTRIBUTE_ACTION)) {
            current =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            return;
        }

        if (tagDependentPending) {
            tagDependentPending = false;
            tagDependentNesting++;
        }

        if (tagDependentNesting > 0) {
            node =
                new Node.UninterpretedTag(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
        } else if (JSP_URI.equals(uri)) {
            node =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
        } else {
            node =
                parseCustomAction(
                    qName,
                    localName,
                    uri,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            if (node == null) {
                node =
                    new Node.UninterpretedTag(
                        qName,
                        localName,
                        nonTaglibAttrs,
                        nonTaglibXmlnsAttrs,
                        taglibAttrs,
                        startMark,
                        current);
            } else {
                // custom action
                String bodyType = getBodyType((Node.CustomTag) node);

                if (scriptlessBodyNode == null
                        && bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) {
                    scriptlessBodyNode = node;
                }
                else if (TagInfo.BODY_CONTENT_TAG_DEPENDENT.equalsIgnoreCase(bodyType)) {
                    tagDependentPending = true;
                }
            }
        }

        current = node;
    }
public void startElement(
        String uri,
        String localName,
        String qName,
        Attributes attrs)
        throws SAXException {

        AttributesImpl taglibAttrs = null;
        AttributesImpl nonTaglibAttrs = null;
        AttributesImpl nonTaglibXmlnsAttrs = null;

        processChars();

        checkPrefixes(uri, qName, attrs);

        if (directivesOnly &&
            !(JSP_URI.equals(uri) &&
                    (localName.startsWith(DIRECTIVE_ACTION)
                    || localName.startsWith(ROOT_ACTION)))) {
            return;
        }

        // jsp:text must not have any subelements
        if (JSP_URI.equals(uri) && TEXT_ACTION.equals(current.getLocalName())) {
            throw new SAXParseException(
                Localizer.getMessage("jsp.error.text.has_subelement"),
                locator);
        }

        startMark = new Mark(ctxt, path, locator.getLineNumber(),
                             locator.getColumnNumber());

        if (attrs != null) {
            /*
             * Notice that due to a bug in the underlying SAX parser, the
             * attributes must be enumerated in descending order. 
             */
            boolean isTaglib = false;
            for (int i = attrs.getLength() - 1; i >= 0; i--) {
                isTaglib = false;
                String attrQName = attrs.getQName(i);
                if (!attrQName.startsWith("xmlns")) {
                    if (nonTaglibAttrs == null) {
                        nonTaglibAttrs = new AttributesImpl();
                    }
                    nonTaglibAttrs.addAttribute(
                        attrs.getURI(i),
                        attrs.getLocalName(i),
                        attrs.getQName(i),
                        attrs.getType(i),
                        attrs.getValue(i));
                } else {
                    if (attrQName.startsWith("xmlns:jsp")) {
                        isTaglib = true;
                    } else {
                        String attrUri = attrs.getValue(i);
                        // TaglibInfo for this uri already established in
                        // startPrefixMapping
                        isTaglib = pageInfo.hasTaglib(attrUri);
                    }
                    if (isTaglib) {
                        if (taglibAttrs == null) {
                            taglibAttrs = new AttributesImpl();
                        }
                        taglibAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    } else {
                        if (nonTaglibXmlnsAttrs == null) {
                            nonTaglibXmlnsAttrs = new AttributesImpl();
                        }
                        nonTaglibXmlnsAttrs.addAttribute(
                            attrs.getURI(i),
                            attrs.getLocalName(i),
                            attrs.getQName(i),
                            attrs.getType(i),
                            attrs.getValue(i));
                    }
                }
            }
        }

        Node node = null;

        if (tagDependentPending && JSP_URI.equals(uri) &&
                     localName.equals(BODY_ACTION)) {
            tagDependentPending = false;
            tagDependentNesting++;
            current =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            return;
        }

        if (tagDependentPending && JSP_URI.equals(uri) &&
                     localName.equals(ATTRIBUTE_ACTION)) {
            current =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            return;
        }

        if (tagDependentPending) {
            tagDependentPending = false;
            tagDependentNesting++;
        }

        if (tagDependentNesting > 0) {
            node =
                new Node.UninterpretedTag(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
        } else if (JSP_URI.equals(uri)) {
            node =
                parseStandardAction(
                    qName,
                    localName,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
        } else {
            node =
                parseCustomAction(
                    qName,
                    localName,
                    uri,
                    nonTaglibAttrs,
                    nonTaglibXmlnsAttrs,
                    taglibAttrs,
                    startMark,
                    current);
            if (node == null) {
                node =
                    new Node.UninterpretedTag(
                        qName,
                        localName,
                        nonTaglibAttrs,
                        nonTaglibXmlnsAttrs,
                        taglibAttrs,
                        startMark,
                        current);
            } else {
                // custom action
                String bodyType = getBodyType((Node.CustomTag) node);

                if (scriptlessBodyNode == null
                        && bodyType.equalsIgnoreCase(TagInfo.BODY_CONTENT_SCRIPTLESS)) {
                    scriptlessBodyNode = node;
                }
                else if (TagInfo.BODY_CONTENT_TAG_DEPENDENT.equalsIgnoreCase(bodyType)) {
                    tagDependentPending = true;
                }
            }
        }

        current = node;
    }
/*
Receives notification of the start of an element.

This method assigns the given tag attributes to one of 3 buckets:

- "xmlns" attributes that represent (standard or custom) tag libraries.
- "xmlns" attributes that do not represent tag libraries.
- all remaining attributes.

For each "xmlns" attribute that represents a custom tag library, the
corresponding TagLibraryInfo object is added to the set of custom
tag libraries.