This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 136595
Collapse All | Expand All

(-)a/openide.util/src/org/openide/xml/XMLUtil.java (+173 lines)
Lines 45-52 Link Here
45
import java.io.IOException;
45
import java.io.IOException;
46
import java.io.OutputStream;
46
import java.io.OutputStream;
47
import java.io.StringReader;
47
import java.io.StringReader;
48
import java.util.ArrayList;
49
import java.util.Arrays;
48
import java.util.HashMap;
50
import java.util.HashMap;
49
import java.util.HashSet;
51
import java.util.HashSet;
52
import java.util.Iterator;
53
import java.util.List;
50
import java.util.Map;
54
import java.util.Map;
51
import java.util.Set;
55
import java.util.Set;
52
import javax.xml.parsers.DocumentBuilder;
56
import javax.xml.parsers.DocumentBuilder;
Lines 66-71 Link Here
66
import javax.xml.validation.Validator;
70
import javax.xml.validation.Validator;
67
import org.w3c.dom.Attr;
71
import org.w3c.dom.Attr;
68
import org.w3c.dom.CDATASection;
72
import org.w3c.dom.CDATASection;
73
import org.w3c.dom.Comment;
69
import org.w3c.dom.DOMException;
74
import org.w3c.dom.DOMException;
70
import org.w3c.dom.DOMImplementation;
75
import org.w3c.dom.DOMImplementation;
71
import org.w3c.dom.Document;
76
import org.w3c.dom.Document;
Lines 842-845 Link Here
842
        }
847
        }
843
        return doc;
848
        return doc;
844
    }
849
    }
850
851
    /**
852
     * Append child element to the correct position according to given
853
     * order.
854
     * @param parent parent to which the child will be added
855
     * @param el element to be added
856
     * @param order order of the elements which must be followed
857
     */
858
    public static void appendChildElement(Element parent, Element el, String[] order) {
859
        Element insertBefore = null;
860
        List l = Arrays.asList(order);
861
        int index = l.indexOf(el.getLocalName());
862
        assert index != -1 : el.getLocalName() + " was not found in " + l; // NOI18N
863
        Iterator it = findSubElements(parent).iterator();
864
        while (it.hasNext()) {
865
            Element e = (Element) it.next();
866
            int index2 = l.indexOf(e.getLocalName());
867
            assert index2 != -1 : e.getLocalName() + " was not found in " + l; // NOI18N
868
            if (index2 > index) {
869
                insertBefore = e;
870
                break;
871
            }
872
        }
873
        parent.insertBefore(el, insertBefore);
874
    }
875
876
    /**
877
     * Find all direct child elements of an element.
878
     * Children which are all-whitespace text nodes or comments are ignored; others cause
879
     * an exception to be thrown.
880
     * @param parent a parent element in a DOM tree
881
     * @return a list of direct child elements (may be empty)
882
     * @throws IllegalArgumentException if there are non-element children besides whitespace
883
     */
884
    public static List<Element> findSubElements(Element parent) throws IllegalArgumentException {
885
        NodeList l = parent.getChildNodes();
886
        List<Element> elements = new ArrayList<Element>(l.getLength());
887
        for (int i = 0; i < l.getLength(); i++) {
888
            Node n = l.item(i);
889
            if (n.getNodeType() == Node.ELEMENT_NODE) {
890
                elements.add((Element) n);
891
            } else if (n.getNodeType() == Node.TEXT_NODE) {
892
                String text = ((Text) n).getNodeValue();
893
                if (text.trim().length() > 0) {
894
                    throw new IllegalArgumentException("non-ws text encountered in " + parent + ": " + text); // NOI18N
895
                }
896
            } else if (n.getNodeType() == Node.COMMENT_NODE) {
897
                // OK, ignore
898
            } else {
899
                throw new IllegalArgumentException("unexpected non-element child of " + parent + ": " + n); // NOI18N
900
            }
901
        }
902
        return elements;
903
    }
904
905
    /**
906
     * Search for an XML element in the direct children of a parent. DOM
907
     * provides a similar method but it does a recursive search which we do not
908
     * want. It also gives a node list and we want only one result.
909
     *
910
     * @param parent a parent element
911
     * @param name the intended local name
912
     * @param namespace the intended namespace (or null)
913
     * @return the one child element with that name, or null if none
914
     * @throws IllegalArgumentException if there is multiple elements of the same name
915
     */
916
    public static Element findElement(Element parent, String name, String namespace) throws IllegalArgumentException {
917
        Element result = null;
918
        NodeList l = parent.getChildNodes();
919
        for (int i = 0; i < l.getLength(); i++) {
920
            if (l.item(i).getNodeType() == Node.ELEMENT_NODE) {
921
                Element el = (Element) l.item(i);
922
                if ((namespace == null && name.equals(el.getTagName()))
923
                        || (namespace != null && name.equals(el.getLocalName()) && namespace.equals(el.getNamespaceURI()))) {
924
                    if (result == null) {
925
                        result = el;
926
                    } else {
927
                        throw new IllegalArgumentException("more than one element with same name found");
928
                    }
929
                }
930
            }
931
        }
932
        return result;
933
    }
934
935
    /**
936
     * Extract nested text from a node.
937
     * Currently does not handle coalescing text nodes, CDATA sections, etc.
938
     * @param parent a parent element
939
     * @return the nested text, or null if none was found
940
     */
941
    public static String findText(Node parent) {
942
        NodeList l = parent.getChildNodes();
943
        for (int i = 0; i < l.getLength(); i++) {
944
            if (l.item(i).getNodeType() == Node.TEXT_NODE) {
945
                Text text = (Text) l.item(i);
946
                return text.getNodeValue();
947
            }
948
        }
949
        return null;
950
    }
951
952
    /**
953
     * Convert an XML fragment from one namespace to another.
954
     */
955
    public static Element translateXML(Element from, String namespace) {
956
        Element to = from.getOwnerDocument().createElementNS(namespace, from.getLocalName());
957
        NodeList nl = from.getChildNodes();
958
        int length = nl.getLength();
959
        for (int i = 0; i < length; i++) {
960
            Node node = nl.item(i);
961
            Node newNode;
962
            if (node.getNodeType() == Node.ELEMENT_NODE) {
963
                newNode = translateXML((Element) node, namespace);
964
            } else {
965
                newNode = node.cloneNode(true);
966
            }
967
            to.appendChild(newNode);
968
        }
969
        NamedNodeMap m = from.getAttributes();
970
        for (int i = 0; i < m.getLength(); i++) {
971
            Node attr = m.item(i);
972
            to.setAttribute(attr.getNodeName(), attr.getNodeValue());
973
        }
974
        return to;
975
    }
976
977
    /**
978
     * Copy elements from one document to another attaching at the specified element
979
     * and translating to the namespace.
980
     *
981
     * @param doc doc to be copied to
982
     * @param from copy the children of this element (exclusive)
983
     * @param to where to attach the copied elements
984
     * @param newNamespace destination namespace
985
     */
986
    public static void copyDocument(Document doc, Element from, Element to, String newNamespace) {
987
        NodeList nl = from.getChildNodes();
988
        int length = nl.getLength();
989
        for (int i = 0; i < length; i++) {
990
            Node node = nl.item(i);
991
            Node newNode = null;
992
            switch (node.getNodeType()) {
993
                case Node.ELEMENT_NODE:
994
                    Element oldElement = (Element) node;
995
                    newNode = doc.createElementNS(newNamespace, oldElement.getTagName());
996
                    NamedNodeMap m = oldElement.getAttributes();
997
                    Element newElement = (Element) newNode;
998
                    for (int index = 0; index < m.getLength(); index++) {
999
                        Node attr = m.item(index);
1000
                        newElement.setAttribute(attr.getNodeName(), attr.getNodeValue());
1001
                    }
1002
                    copyDocument(doc, oldElement, newElement, newNamespace);
1003
                    break;
1004
                case Node.TEXT_NODE:
1005
                    Text oldText = (Text) node;
1006
                    newNode = doc.createTextNode(oldText.getData());
1007
                    break;
1008
                case Node.COMMENT_NODE:
1009
                    Comment oldComment = (Comment) node;
1010
                    newNode = doc.createComment(oldComment.getData());
1011
                    break;
1012
            }
1013
            if (newNode != null) {
1014
                to.appendChild(newNode);
1015
            }
1016
        }
1017
    }
845
}
1018
}

Return to bug 136595