protected void startNode()

in core/cocoon-pipeline/cocoon-pipeline-impl/src/main/java/org/apache/cocoon/xml/dom/DOMStreamer.java [262:476]


        protected void startNode(Node node) throws SAXException {

            switch (node.getNodeType()) {
                case Node.COMMENT_NODE:
                    {
                        if (lexicalHandler != null) {
                            final String data = ((Comment) node).getData();
                            if ( data != null ) {
                                lexicalHandler.comment(data.toCharArray(), 0, data.length());
                            }
                        }
                    }
                    break;
                case Node.DOCUMENT_FRAGMENT_NODE:
                    // ??;
                case Node.DOCUMENT_NODE:
                    break;
                case Node.ELEMENT_NODE:
                    NamedNodeMap atts = node.getAttributes();
                    int nAttrs = atts.getLength();

                    // create a list of localy declared namespace prefixes
                    currentElementInfo = new NamespaceNormalizingDOMStreamer.ElementInfo(currentElementInfo);
                    for (int i = 0; i < nAttrs; i++) {
                        Node attr = atts.item(i);
                        String attrName = attr.getNodeName();

                        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:")) {
                            int index;
                            String prefix = (index = attrName.indexOf(":")) < 0
                                    ? "" : attrName.substring(index + 1);

                            currentElementInfo.put(prefix, attr.getNodeValue());
                        }
                    }

                    String namespaceURI = node.getNamespaceURI();
                    String prefix = node.getPrefix();
                    String localName = node.getLocalName();

                    if (localName == null) {
                        // this is an element created with createElement instead of createElementNS
                        String[] prefixAndLocalName = getPrefixAndLocalName(node.getNodeName());
                        prefix = prefixAndLocalName[0];
                        localName = prefixAndLocalName[1];
                        // note: if prefix is null, there can still be a default namespace...
                        namespaceURI = getNamespaceForPrefix(prefix, (Element)node);
                    }

                    if (namespaceURI != null) {
                        // no prefix means: make this the default namespace
                        if (prefix == null) {
                            prefix = "";
                        }
                        // check that is declared
                        String uri = currentElementInfo.findNamespaceURI(prefix);
                        if (StringUtils.equals(uri, namespaceURI)) {
                            // System.out.println("namespace is declared");
                            // prefix is declared correctly, do nothing
                            //} else if (uri != null) {
                            // System.out.println("prefix is declared with other namespace, overwriting it");
                            // prefix exists but is bound to another namespace, overwrite it
                            // currentElementInfo.put(prefix, namespaceURI);
                        } else {
                            // System.out.println("prefix is not yet declared, declaring it now");
                            currentElementInfo.put(prefix, namespaceURI);
                        }
                    } else {
                        // element has no namespace
                        // check if there is a default namespace, if so undeclare it
                        String uri = currentElementInfo.findNamespaceURI("");
                        if (StringUtils.isNotEmpty(uri)) {
                            // System.out.println("undeclaring default namespace");
                            currentElementInfo.put("", "");
                        }
                    }

                    // SAX uses empty string to denote no namespace, while DOM uses null.
                    if (namespaceURI == null)
                        namespaceURI = "";

                    String qName;
                    if (StringUtils.isNotEmpty(prefix)) {
                        qName = prefix + ":" + localName;
                    } else {
                        qName = localName;
                    }

                    // make the attributes
                    AttributesImpl newAttrs = new AttributesImpl();
                    for (int i = 0; i < nAttrs; i++) {
                        Node attr = atts.item(i);
                        String attrName = attr.getNodeName();
                        String assignedAttrPrefix = null;

                        // only do non-namespace attributes
                        if (!(attrName.equals("xmlns") || attrName.startsWith("xmlns:"))) {
                            String attrPrefix;
                            String attrLocalName;
                            String attrNsURI;

                            if (attr.getLocalName() == null) {
                                // this is an attribute created with setAttribute instead of setAttributeNS
                                String[] prefixAndLocalName = getPrefixAndLocalName(attrName);
                                attrPrefix = prefixAndLocalName[0];
                                // the statement below causes the attribute to keep its prefix even if it is not
                                // bound to a namespace (to support pre-namespace XML).
                                assignedAttrPrefix = attrPrefix;
                                attrLocalName = prefixAndLocalName[1];
                                // note: if prefix is null, the attribute has no namespace (namespace defaulting
                                // does not apply to attributes)
                                if (attrPrefix != null)
                                    attrNsURI = getNamespaceForPrefix(attrPrefix, (Element)node);
                                else
                                    attrNsURI = null;
                            } else {
                                attrLocalName = attr.getLocalName();
                                attrPrefix = attr.getPrefix();
                                attrNsURI = attr.getNamespaceURI();
                            }

                            if (attrNsURI != null) {
                                String declaredUri = currentElementInfo.findNamespaceURI(attrPrefix);
                                // if the prefix is null, or the prefix has not been declared, or conflicts with an in-scope binding
                                if (declaredUri == null || !declaredUri.equals(attrNsURI)) {
                                    String availablePrefix = currentElementInfo.findPrefix(attrNsURI);
                                    if (availablePrefix != null && !availablePrefix.equals(""))
                                        assignedAttrPrefix = availablePrefix;
                                    else {
                                        if (attrPrefix != null && declaredUri == null) {
                                            // prefix is not null and is not yet declared: declare it
                                            assignedAttrPrefix = attrPrefix;
                                            currentElementInfo.put(assignedAttrPrefix, attrNsURI);
                                        } else {
                                            // attribute has no prefix (which is not allowed for namespaced attributes) or
                                            // the prefix is already bound to something else: generate a new prefix
                                            newPrefixCounter++;
                                            assignedAttrPrefix = "NS" + newPrefixCounter;
                                            currentElementInfo.put(assignedAttrPrefix, attrNsURI);
                                        }
                                    }
                                } else {
                                    assignedAttrPrefix = attrPrefix;
                                }
                            }

                            String assignedAttrNsURI = attrNsURI != null ? attrNsURI : "";
                            String attrQName;
                            if (assignedAttrPrefix != null) {
                                attrQName = assignedAttrPrefix + ":" + attrLocalName;
                            } else {
                                attrQName = attrLocalName;
                            }
                            newAttrs.addAttribute(assignedAttrNsURI, attrLocalName, attrQName, "CDATA", attr.getNodeValue());
                        }
                    }

                    // add local namespace declaration and fire startPrefixMapping events
                    if (currentElementInfo.namespaceDeclarations != null && currentElementInfo.namespaceDeclarations.size() > 0) {
                        Iterator localNsDeclIt = currentElementInfo.namespaceDeclarations.entrySet().iterator();
                        while (localNsDeclIt.hasNext()) {
                            Map.Entry entry = (Map.Entry) localNsDeclIt.next();
                            String pr = (String) entry.getKey();
                            String ns = (String) entry.getValue();
                            // the following lines enable the creation of explicit xmlns attributes
                            //String pr1 = pr.equals("") ? "xmlns" : pr;
                            //String qn = pr.equals("") ? "xmlns" : "xmlns:" + pr;
                            //newAttrs.addAttribute("", pr1, qn, "CDATA", ns);
                            // System.out.println("starting prefix mapping  for prefix " + pr + " for " + ns);
                            contentHandler.startPrefixMapping(pr, ns);
                        }
                    }

                    contentHandler.startElement(namespaceURI, localName, qName, newAttrs);

                    currentElementInfo.localName = localName;
                    currentElementInfo.namespaceURI = namespaceURI;
                    currentElementInfo.qName = qName;
                    break;
                case Node.PROCESSING_INSTRUCTION_NODE:
                    {
                        ProcessingInstruction pi = (ProcessingInstruction) node;
                        contentHandler.processingInstruction(pi.getNodeName(), pi.getData());
                    }
                    break;
                case Node.CDATA_SECTION_NODE:
                    {
                        if (lexicalHandler != null)
                            lexicalHandler.startCDATA();

                        dispatchChars(node);

                        if (lexicalHandler != null)
                            lexicalHandler.endCDATA();
                    }
                    break;
                case Node.TEXT_NODE:
                    {
                        dispatchChars(node);
                    }
                    break;
                case Node.ENTITY_REFERENCE_NODE:
                    {
                        EntityReference eref = (EntityReference) node;

                        if (lexicalHandler != null) {
                            lexicalHandler.startEntity(eref.getNodeName());
                        } else {
                            // warning("Can not output entity to a pure SAX ContentHandler");
                        }
                    }
                    break;
                default :
            }
        }