⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlnode.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino DOM-only E4X implementation. * * The Initial Developer of the Original Code is * David P. Caldwell. * Portions created by David P. Caldwell are Copyright (C) * 2007 David P. Caldwell. All Rights Reserved. * * * Contributor(s): *   David P. Caldwell <inonit@inonit.com> * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript.xmlimpl;import java.util.*;import org.w3c.dom.*;import org.mozilla.javascript.*;//    Disambiguate with org.mozilla.javascriptimport org.w3c.dom.Node;class XmlNode {    private static final String XML_NAMESPACES_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";    private static final String USER_DATA_XMLNODE_KEY = XmlNode.class.getName();    private static final boolean DOM_LEVEL_3 = true;    private static XmlNode getUserData(Node node) {        if (DOM_LEVEL_3) {            return (XmlNode)node.getUserData(USER_DATA_XMLNODE_KEY);        }        return null;    }    private static void setUserData(Node node, XmlNode wrap) {        if (DOM_LEVEL_3) {            node.setUserData(USER_DATA_XMLNODE_KEY, wrap, wrap.events);        }    }    private static XmlNode createImpl(Node node) {        if (node instanceof Document) throw new IllegalArgumentException();        XmlNode rv = null;        if (getUserData(node) == null) {            rv = new XmlNode();            rv.dom = node;            setUserData(node, rv);        } else {            rv = getUserData(node);        }        return rv;    }    static XmlNode newElementWithText(XmlProcessor processor, XmlNode reference, XmlNode.QName qname, String value) {        if (reference instanceof org.w3c.dom.Document) throw new IllegalArgumentException("Cannot use Document node as reference");        Document document = null;        if (reference != null) {            document = reference.dom.getOwnerDocument();        } else {            document = processor.newDocument();        }        Node referenceDom = (reference != null) ? reference.dom : null;        Element e = document.createElementNS(qname.getUri(), qname.qualify(referenceDom));        if (value != null) {            e.appendChild(document.createTextNode(value));        }        return XmlNode.createImpl(e);    }    static XmlNode createText(XmlProcessor processor, String value) {        return createImpl( processor.newDocument().createTextNode(value) );    }    static XmlNode createElementFromNode(Node node) {        if (node instanceof Document)            node = ((Document) node).getDocumentElement();        return createImpl(node);    }    static XmlNode createElement(XmlProcessor processor, String namespaceUri, String xml) throws org.xml.sax.SAXException {        return createImpl( processor.toXml(namespaceUri, xml) );    }    static XmlNode createEmpty(XmlProcessor processor) {        return createText(processor, "");    }    private static XmlNode copy(XmlNode other) {        return createImpl( other.dom.cloneNode(true) );    }    private static final long serialVersionUID = 1L;    private UserDataHandler events = new UserDataHandler() {        public void handle(short operation, String key, Object data, Node src, Node dest) {        }    };    private Node dom;    private XML xml;    private XmlNode() {    }    String debug() {        XmlProcessor raw = new XmlProcessor();        raw.setIgnoreComments(false);        raw.setIgnoreProcessingInstructions(false);        raw.setIgnoreWhitespace(false);        raw.setPrettyPrinting(false);        return raw.ecmaToXmlString(this.dom);    }    public String toString() {        return "XmlNode: type=" + dom.getNodeType() + " dom=" + dom.toString();    }    XML getXml() {        return xml;    }    void setXml(XML xml) {        this.xml = xml;    }    int getChildCount() {        return this.dom.getChildNodes().getLength();    }    XmlNode parent() {        Node domParent = dom.getParentNode();        if (domParent instanceof Document) return null;        if (domParent == null) return null;        return createImpl(domParent);    }    int getChildIndex() {        if (this.isAttributeType()) return -1;        if (parent() == null) return -1;        org.w3c.dom.NodeList siblings = this.dom.getParentNode().getChildNodes();        for (int i=0; i<siblings.getLength(); i++) {            if (siblings.item(i) == dom) {                return i;            }        }        //    Either the parent is -1 or one of the this node's parent's children is this node.        throw new RuntimeException("Unreachable.");    }    void removeChild(int index) {        this.dom.removeChild( this.dom.getChildNodes().item(index) );    }    String toXmlString(XmlProcessor processor) {        return processor.ecmaToXmlString(this.dom);    }    String ecmaValue() {        //    TODO    See ECMA 357 Section 9.1        if (isTextType()) {            return ((org.w3c.dom.Text)dom).getData();        } else if (isAttributeType()) {            return ((org.w3c.dom.Attr)dom).getValue();        } else if (isProcessingInstructionType()) {            return ((org.w3c.dom.ProcessingInstruction)dom).getData();        } else if (isCommentType()) {            return ((org.w3c.dom.Comment)dom).getNodeValue();        } else if (isElementType()) {            throw new RuntimeException("Unimplemented ecmaValue() for elements.");        } else {            throw new RuntimeException("Unimplemented for node " + dom);        }    }    void deleteMe() {        if (dom instanceof Attr) {            Attr attr = (Attr)this.dom;            attr.getOwnerElement().getAttributes().removeNamedItemNS(attr.getNamespaceURI(), attr.getLocalName());        } else {            if (this.dom.getParentNode() != null) {                this.dom.getParentNode().removeChild(this.dom);            } else {                //    This case can be exercised at least when executing the regression                //    tests under https://bugzilla.mozilla.org/show_bug.cgi?id=354145            }        }    }    void normalize() {        this.dom.normalize();    }    void insertChildAt(int index, XmlNode node) {        Node parent = this.dom;        Node child = parent.getOwnerDocument().importNode( node.dom, true );        if (parent.getChildNodes().getLength() < index) {            //    TODO    Check ECMA for what happens here            throw new IllegalArgumentException("index=" + index + " length=" + parent.getChildNodes().getLength());        }        if (parent.getChildNodes().getLength() == index) {            parent.appendChild(child);        } else {            parent.insertBefore(child, parent.getChildNodes().item(index));        }    }    void insertChildrenAt(int index, XmlNode[] nodes) {        for (int i=0; i<nodes.length; i++) {            insertChildAt(index+i, nodes[i]);        }    }    XmlNode getChild(int index) {        Node child = dom.getChildNodes().item(index);        return createImpl(child);    }    //    Helper method for XML.hasSimpleContent()    boolean hasChildElement() {        org.w3c.dom.NodeList nodes = this.dom.getChildNodes();        for (int i=0; i<nodes.getLength(); i++) {            if (nodes.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) return true;        }        return false;    }    boolean isSameNode(XmlNode other) {        //    TODO    May need to be changed if we allow XmlNode to refer to several Node objects        return this.dom == other.dom;    }    private String toUri(String ns) {        return (ns == null) ? "" : ns;    }    private void addNamespaces(Namespaces rv, Element element) {        if (element == null) throw new RuntimeException("element must not be null");        String myDefaultNamespace = toUri(element.lookupNamespaceURI(null));        String parentDefaultNamespace = "";        if (element.getParentNode() != null) {            parentDefaultNamespace = toUri(element.getParentNode().lookupNamespaceURI(null));        }        if (!myDefaultNamespace.equals(parentDefaultNamespace) || !(element.getParentNode() instanceof Element) ) {            rv.declare(Namespace.create("", myDefaultNamespace));        }        NamedNodeMap attributes = element.getAttributes();        for (int i=0; i<attributes.getLength(); i++) {            Attr attr = (Attr)attributes.item(i);            if (attr.getPrefix() != null && attr.getPrefix().equals("xmlns")) {                rv.declare(Namespace.create(attr.getLocalName(), attr.getValue()));            }        }    }    private Namespaces getAllNamespaces() {        Namespaces rv = new Namespaces();        Node target = this.dom;        if (target instanceof Attr) {            target = ((Attr)target).getOwnerElement();        }        while(target != null) {            if (target instanceof Element) {                addNamespaces(rv, (Element)target);            }            target = target.getParentNode();        }        //    Fallback in case no namespace was declared        rv.declare(Namespace.create("", ""));        return rv;    }    Namespace[] getInScopeNamespaces() {        Namespaces rv = getAllNamespaces();        return rv.getNamespaces();    }    Namespace[] getNamespaceDeclarations() {        //    ECMA357 13.4.4.24        if (this.dom instanceof Element) {            Namespaces rv = new Namespaces();            addNamespaces( rv, (Element)this.dom );            return rv.getNamespaces();        } else {            return new Namespace[0];        }    }    Namespace getNamespaceDeclaration(String prefix) {        if (prefix.equals("") && dom instanceof Attr) {            //    Default namespaces do not apply to attributes; see XML Namespaces section 5.2            return Namespace.create("", "");        }        Namespaces rv = getAllNamespaces();        return rv.getNamespace(prefix);    }    Namespace getNamespaceDeclaration() {        if (dom.getPrefix() == null) return getNamespaceDeclaration("");        return getNamespaceDeclaration(dom.getPrefix());    }    private static class Namespaces {        private HashMap map = new HashMap();        private HashMap uriToPrefix = new HashMap();        Namespaces() {        }        void declare(Namespace n) {            if (map.get(n.prefix) == null) {                map.put(n.prefix, n.uri);            }            //    TODO    I think this is analogous to the other way, but have not really thought it through ... should local scope            //            matter more than outer scope?            if (uriToPrefix.get(n.uri) == null) {                uriToPrefix.put(n.uri, n.prefix);            }        }        Namespace getNamespaceByUri(String uri) {            if (uriToPrefix.get(uri) == null) return null;            return Namespace.create(uri, (String)uriToPrefix.get(uri));        }        Namespace getNamespace(String prefix) {            if (map.get(prefix) == null) return null;            return Namespace.create(prefix, (String)map.get(prefix));        }        Namespace[] getNamespaces() {            Iterator i = map.keySet().iterator();            ArrayList rv = new ArrayList();            while(i.hasNext()) {                String prefix = (String)i.next();                String uri = (String)map.get(prefix);                Namespace n = Namespace.create(prefix, uri);                if (!n.isEmpty()) {                    rv.add( n );                }            }            return (Namespace[])rv.toArray(new Namespace[0]);        }    }    final XmlNode copy() {        return copy( this );    }    //    Returns whether this node is capable of being a parent    final boolean isParentType() {        return isElementType();    }    final boolean isTextType() {        return dom.getNodeType() == Node.TEXT_NODE || dom.getNodeType() == Node.CDATA_SECTION_NODE;    }    final boolean isAttributeType() {        return dom.getNodeType() == Node.ATTRIBUTE_NODE;    }    final boolean isProcessingInstructionType() {        return dom.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE;    }    final boolean isCommentType() {        return dom.getNodeType() == Node.COMMENT_NODE;    }    final boolean isElementType() {        return dom.getNodeType() == Node.ELEMENT_NODE;    }    final void renameNode(QName qname) {        this.dom = dom.getOwnerDocument().renameNode(dom, qname.getUri(), qname.qualify(dom));    }    void invalidateNamespacePrefix() {        if (!(dom instanceof Element)) throw new IllegalStateException();        String prefix = this.dom.getPrefix();        QName after = QName.create(this.dom.getNamespaceURI(), this.dom.getLocalName(), null);        renameNode(after);        NamedNodeMap attrs = this.dom.getAttributes();        for (int i=0; i<attrs.getLength(); i++) {            if (attrs.item(i).getPrefix().equals(prefix)) {                createImpl( attrs.item(i) ).renameNode( QName.create(attrs.item(i).getNamespaceURI(), attrs.item(i).getLocalName(), null) );            }        }    }    private void declareNamespace(Element e, String prefix, String uri) {        if (prefix.length() > 0) {            e.setAttributeNS(XML_NAMESPACES_NAMESPACE_URI, "xmlns:" + prefix, uri);        } else {            e.setAttribute("xmlns", uri);        }    }    void declareNamespace(String prefix, String uri) {        if (!(dom instanceof Element)) throw new IllegalStateException();        if (dom.lookupNamespaceURI(uri) != null && dom.lookupNamespaceURI(uri).equals(prefix)) {            //    do nothing        } else {            Element e = (Element)dom;            declareNamespace(e, prefix, uri);        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -