11ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson/*
21ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Copyright (C) 2009 The Android Open Source Project
3f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
41ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
51ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * you may not use this file except in compliance with the License.
61ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * You may obtain a copy of the License at
7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
81ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
101ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Unless required by applicable law or agreed to in writing, software
111ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
121ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * See the License for the specific language governing permissions and
141ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * limitations under the License.
151ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson */
161ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
171c92541d38ed4d0b6e958f478cd7b129f140cd44Jesse Wilsonpackage libcore.xml;
181ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
191ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport junit.framework.TestCase;
201ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport org.w3c.dom.Document;
211ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport org.w3c.dom.Element;
221ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport org.w3c.dom.Node;
231ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport org.w3c.dom.NodeList;
241ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport tests.support.resource.Support_Resources;
251ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
261ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport javax.xml.parsers.DocumentBuilder;
271ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport javax.xml.parsers.DocumentBuilderFactory;
281ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport java.io.ByteArrayInputStream;
291ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport java.io.File;
301ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport java.util.ArrayList;
311ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport java.util.List;
321ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
331ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonpublic class NodeTest extends TestCase {
341ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
351ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    /**
361ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson     * For bug 779: Node#getNextSibling throws IndexOutOfBoundsException.
371ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson     */
381ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    public void test_getNextSibling() throws Exception {
391ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        // Calling getNextSibling when there is no next sibling should return null.
401ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        // From http://code.google.com/p/android/issues/detail?id=779.
411ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        ByteArrayInputStream bis = new ByteArrayInputStream("<root/>".getBytes());
421ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(bis);
431ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        Node root = document.getDocumentElement();
441ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        assertNull(root.getNextSibling());
451ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    }
461ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
471ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    public void testGetBaseUri() throws Exception {
481ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
491ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        File file = Support_Resources.resourceToTempFile("/simple.xml");
501ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        Document document = builder.parse(file);
511ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
525ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson        assertFileUriEquals(file, document.getBaseURI());
531ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
541ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        Element documentElement = document.getDocumentElement();
551ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        for (Node node : flattenSubtree(documentElement)) {
561ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson            if (node.getNodeType() == Node.ELEMENT_NODE
571ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson                    || node.getNodeType() == Node.DOCUMENT_NODE) {
585ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson                assertFileUriEquals(file, node.getBaseURI());
591ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson            } else {
601ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson                assertNull("Unexpected base URI for " + node, node.getBaseURI());
611ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson            }
621ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        }
631ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
641ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        // TODO: test other node types
651ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        // TODO: test resolution of relative paths
665d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes        // TODO: test URI sanitization
671ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    }
681ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
695ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson    private void assertFileUriEquals(File expectedFile, String actual) {
705ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson        assertTrue("Expected URI for: " + expectedFile + " but was " + actual + ". ",
715ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson                actual.equals("file:" + expectedFile)
725ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson                        || actual.equals("file://" + expectedFile));
735ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson    }
745ab82b77afbc8af3b91e90ab46b0a7cc0a090f04Jesse Wilson
751ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    private List<Node> flattenSubtree(Node subtree) {
761ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        List<Node> result = new ArrayList<Node>();
771ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        traverse(subtree, result);
781ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        return result;
791ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    }
801ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
811ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    private void traverse(Node node, List<Node> sink) {
821ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        sink.add(node);
831ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson
841ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        NodeList children = node.getChildNodes();
851ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        for (int i = 0; i < children.getLength(); i++) {
861ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson            traverse(children.item(i), sink);
871ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson        }
881ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson    }
891ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson}
90