Home | History | Annotate | Download | only in parsers
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package tests.api.javax.xml.parsers;
     18 
     19 import junit.framework.TestCase;
     20 import org.w3c.dom.DOMImplementation;
     21 import org.w3c.dom.Document;
     22 import org.w3c.dom.Element;
     23 import org.w3c.dom.EntityReference;
     24 import org.w3c.dom.Text;
     25 import org.xml.sax.EntityResolver;
     26 import org.xml.sax.ErrorHandler;
     27 import org.xml.sax.InputSource;
     28 import org.xml.sax.SAXException;
     29 import org.xml.sax.SAXParseException;
     30 import tests.api.org.xml.sax.support.MethodLogger;
     31 import tests.api.org.xml.sax.support.MockHandler;
     32 import tests.api.org.xml.sax.support.MockResolver;
     33 import tests.support.resource.Support_Resources;
     34 
     35 import javax.xml.parsers.DocumentBuilder;
     36 import javax.xml.parsers.DocumentBuilderFactory;
     37 import java.io.ByteArrayInputStream;
     38 import java.io.File;
     39 import java.io.FileInputStream;
     40 import java.io.IOException;
     41 import java.io.InputStream;
     42 import java.net.URL;
     43 
     44 public class DocumentBuilderTest extends TestCase {
     45 
     46     private class MockDocumentBuilder extends DocumentBuilder {
     47 
     48         public MockDocumentBuilder() {
     49             super();
     50         }
     51 
     52         /*
     53          * @see javax.xml.parsers.DocumentBuilder#getDOMImplementation()
     54          */
     55         @Override
     56         public DOMImplementation getDOMImplementation() {
     57             // it is a fake
     58             return null;
     59         }
     60 
     61         /*
     62          * @see javax.xml.parsers.DocumentBuilder#isNamespaceAware()
     63          */
     64         @Override
     65         public boolean isNamespaceAware() {
     66             // it is a fake
     67             return false;
     68         }
     69 
     70         /*
     71          * @see javax.xml.parsers.DocumentBuilder#isValidating()
     72          */
     73         @Override
     74         public boolean isValidating() {
     75             // it is a fake
     76             return false;
     77         }
     78 
     79         /*
     80          * @see javax.xml.parsers.DocumentBuilder#newDocument()
     81          */
     82         @Override
     83         public Document newDocument() {
     84             // it is a fake
     85             return null;
     86         }
     87 
     88         /*
     89          * @see javax.xml.parsers.DocumentBuilder#parse(org.xml.sax.InputSource)
     90          */
     91         @Override
     92         public Document parse(InputSource is) throws SAXException, IOException {
     93             // it is a fake
     94             return null;
     95         }
     96 
     97         /*
     98          * @see javax.xml.parsers.DocumentBuilder#setEntityResolver(
     99          *  org.xml.sax.EntityResolver)
    100          */
    101         @Override
    102         public void setEntityResolver(EntityResolver er) {
    103             // it is a fake
    104         }
    105 
    106         /*
    107          * @see javax.xml.parsers.DocumentBuilder#setErrorHandler(
    108          *  org.xml.sax.ErrorHandler)
    109          */
    110         @Override
    111         public void setErrorHandler(ErrorHandler eh) {
    112             // it is a fake
    113         }
    114 
    115         public Object clone() throws CloneNotSupportedException {
    116             return super.clone();
    117         }
    118     }
    119 
    120     DocumentBuilderFactory dbf;
    121 
    122     DocumentBuilder db;
    123 
    124     protected void setUp() throws Exception {
    125 
    126         dbf = DocumentBuilderFactory.newInstance();
    127 
    128         dbf.setIgnoringElementContentWhitespace(true);
    129 
    130         db = dbf.newDocumentBuilder();
    131         super.setUp();
    132     }
    133 
    134     protected void tearDown() throws Exception {
    135         super.tearDown();
    136     }
    137 
    138     public void testDocumentBuilder() {
    139         try {
    140             new MockDocumentBuilder();
    141         } catch (Exception e) {
    142             fail("unexpected exception " + e.toString());
    143         }
    144     }
    145 
    146     /**
    147      *  javax.xml.parsers.DocumentBuilder#getSchema()
    148      *  TBD getSchema() is not supported
    149      */
    150  /*   public void test_getSchema() {
    151         assertNull(db.getSchema());
    152         SchemaFactory sf =
    153             SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    154         try {
    155             Schema schema = sf.newSchema();
    156             dbf.setSchema(schema);
    157             assertNotNull(dbf.newDocumentBuilder().getSchema());
    158         } catch (ParserConfigurationException pce) {
    159             fail("Unexpected ParserConfigurationException " + pce.toString());
    160         } catch (SAXException sax) {
    161             fail("Unexpected SAXException " + sax.toString());
    162         }
    163     }
    164 */
    165     public void testNewDocument() {
    166         Document d;
    167 
    168         try {
    169             d = dbf.newDocumentBuilder().newDocument();
    170         } catch (Exception e) {
    171             throw new RuntimeException("Unexpected exception", e);
    172         }
    173 
    174         assertNotNull(d);
    175         assertNull(d.getDoctype());
    176         assertNull(d.getDocumentElement());
    177         assertNull(d.getNamespaceURI());
    178     }
    179 
    180     public void testGetImplementation() {
    181         DOMImplementation d;
    182 
    183         try {
    184             d = dbf.newDocumentBuilder().getDOMImplementation();
    185         } catch (Exception e) {
    186             throw new RuntimeException("Unexpected exception", e);
    187         }
    188 
    189         assertNotNull(d);
    190     }
    191 
    192     public void testIsNamespaceAware() {
    193         try {
    194             dbf.setNamespaceAware(true);
    195             assertTrue(dbf.newDocumentBuilder().isNamespaceAware());
    196             dbf.setNamespaceAware(false);
    197             assertFalse(dbf.newDocumentBuilder().isNamespaceAware());
    198         } catch (Exception e) {
    199             throw new RuntimeException("Unexpected exception", e);
    200         }
    201     }
    202 
    203     public void testIsValidating() {
    204         try {
    205             dbf.setValidating(false);
    206             assertFalse(dbf.newDocumentBuilder().isValidating());
    207         } catch (Exception e) {
    208             throw new RuntimeException("Unexpected exception", e);
    209         }
    210     }
    211 
    212     public void testIsXIncludeAware() {
    213         try {
    214             dbf.setXIncludeAware(false);
    215             assertFalse(dbf.newDocumentBuilder().isXIncludeAware());
    216         } catch (Exception e) {
    217             throw new RuntimeException("Unexpected exception", e);
    218         }
    219     }
    220 
    221     /**
    222      * Tests that the Base URI for the document is populated with the file URI.
    223      */
    224     public void testGetBaseURI() throws IOException, SAXException {
    225         File f = Support_Resources.resourceToTempFile("/simple.xml");
    226         Document d = db.parse(f);
    227         assertTrue(d.getDocumentElement().getBaseURI().startsWith("file://"));
    228     }
    229 
    230     /**
    231      * javax.xml.parsers.DocumentBuilder#parse(java.io.File)
    232      * Case 1: Try to parse correct xml document.
    233      * Case 2: Try to call parse() with null argument.
    234      * Case 3: Try to parse a non-existent file.
    235      * Case 4: Try to parse incorrect xml file.
    236      */
    237     public void test_parseLjava_io_File() throws IOException {
    238         File f = Support_Resources.resourceToTempFile("/simple.xml");
    239 
    240         // case 1: Trivial use.
    241         try {
    242             Document d = db.parse(f);
    243             assertNotNull(d);
    244        //      TBD getXmlEncoding() IS NOT SUPPORTED
    245        //     assertEquals("ISO-8859-1", d.getXmlEncoding());
    246             assertEquals(2, d.getChildNodes().getLength());
    247             assertEquals("#comment",
    248                     d.getChildNodes().item(0).getNodeName());
    249             assertEquals("breakfast_menu",
    250                     d.getChildNodes().item(1).getNodeName());
    251         } catch (IOException ioe) {
    252             fail("Unexpected IOException " + ioe.toString());
    253         } catch (SAXException sax) {
    254             fail("Unexpected SAXException " + sax.toString());
    255         }
    256 
    257         // case 2: Try to call parse with null argument
    258         try {
    259             db.parse((File)null);
    260             fail("Expected IllegalArgumentException was not thrown");
    261         } catch (IllegalArgumentException iae) {
    262             // expected
    263         } catch (IOException ioe) {
    264             fail("Unexpected IOException " + ioe.toString());
    265         } catch (SAXException sax) {
    266             fail("Unexpected SAXException " + sax.toString());
    267         }
    268 
    269         // case 3: Try to parse a non-existent file
    270         try {
    271             db.parse(new File("_"));
    272             fail("Expected IOException was not thrown");
    273         } catch (IOException ioe) {
    274             // expected
    275         } catch (SAXException sax) {
    276             fail("Unexpected SAXException " + sax.toString());
    277         }
    278 
    279         // case 4: Try to parse incorrect xml file
    280         f = Support_Resources.resourceToTempFile("/wrong.xml");
    281         try {
    282             db.parse(f);
    283             fail("Expected SAXException was not thrown");
    284         } catch (IOException ioe) {
    285             fail("Unexpected IOException " + ioe.toString());
    286         } catch (SAXException sax) {
    287             // expected
    288         }
    289     }
    290 
    291     /**
    292      * javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
    293      * Case 1: Try to parse correct xml document.
    294      * Case 2: Try to call parse() with null argument.
    295      * Case 3: Try to parse a non-existent file.
    296      * Case 4: Try to parse incorrect xml file.
    297      */
    298     public void test_parseLjava_io_InputStream() {
    299         InputStream is = getClass().getResourceAsStream("/simple.xml");
    300         // case 1: Trivial use.
    301         try {
    302             Document d = db.parse(is);
    303             assertNotNull(d);
    304             // TBD getXmlEncoding() IS NOT SUPPORTED
    305             // assertEquals("ISO-8859-1", d.getXmlEncoding());
    306             assertEquals(2, d.getChildNodes().getLength());
    307             assertEquals("#comment",
    308                     d.getChildNodes().item(0).getNodeName());
    309             assertEquals("breakfast_menu",
    310                     d.getChildNodes().item(1).getNodeName());
    311         } catch (IOException ioe) {
    312             fail("Unexpected IOException " + ioe.toString());
    313         } catch (SAXException sax) {
    314             fail("Unexpected SAXException " + sax.toString());
    315         }
    316 
    317         // case 2: Try to call parse with null argument
    318         try {
    319             db.parse((InputStream)null);
    320             fail("Expected IllegalArgumentException was not thrown");
    321         } catch (IllegalArgumentException iae) {
    322             // expected
    323         } catch (IOException ioe) {
    324             fail("Unexpected IOException " + ioe.toString());
    325         } catch (SAXException sax) {
    326             fail("Unexpected SAXException " + sax.toString());
    327         }
    328 
    329         // case 3: Try to parse a non-existent file
    330         try {
    331             db.parse(new FileInputStream("_"));
    332             fail("Expected IOException was not thrown");
    333         } catch (IOException ioe) {
    334             // expected
    335         } catch (SAXException sax) {
    336             fail("Unexpected SAXException " + sax.toString());
    337         }
    338 
    339         // case 4: Try to parse incorrect xml file
    340         try {
    341             is = getClass().getResourceAsStream("/wrong.xml");
    342             db.parse(is);
    343             fail("Expected SAXException was not thrown");
    344         } catch (IOException ioe) {
    345             fail("Unexpected IOException " + ioe.toString());
    346         } catch (SAXException sax) {
    347             // expected
    348         }
    349     }
    350 
    351     /**
    352      * javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream)
    353      * Case 1: Try to parse correct xml document.
    354      * Case 2: Try to call parse() with null argument.
    355      * Case 3: Try to parse a non-existent file.
    356      * Case 4: Try to parse incorrect xml file.
    357      */
    358     public void testParseInputSource() {
    359         InputStream stream = getClass().getResourceAsStream("/simple.xml");
    360         InputSource is = new InputSource(stream);
    361 
    362         // case 1: Trivial use.
    363         try {
    364             Document d = db.parse(is);
    365             assertNotNull(d);
    366             // TBD getXmlEncoding() IS NOT SUPPORTED
    367             // assertEquals("ISO-8859-1", d.getXmlEncoding());
    368             assertEquals(2, d.getChildNodes().getLength());
    369             assertEquals("#comment",
    370                     d.getChildNodes().item(0).getNodeName());
    371             assertEquals("breakfast_menu",
    372                     d.getChildNodes().item(1).getNodeName());
    373         } catch (IOException ioe) {
    374             fail("Unexpected IOException " + ioe.toString());
    375         } catch (SAXException sax) {
    376             fail("Unexpected SAXException " + sax.toString());
    377         }
    378 
    379         // case 2: Try to call parse with null argument
    380         try {
    381             db.parse((InputSource)null);
    382             fail("Expected IllegalArgumentException was not thrown");
    383         } catch (IllegalArgumentException iae) {
    384             // expected
    385         } catch (IOException ioe) {
    386             fail("Unexpected IOException " + ioe.toString());
    387         } catch (SAXException sax) {
    388             fail("Unexpected SAXException " + sax.toString());
    389         }
    390 
    391         // case 3: Try to parse a non-existent file
    392         try {
    393             db.parse(new InputSource(new FileInputStream("_")));
    394             fail("Expected IOException was not thrown");
    395         } catch (IOException ioe) {
    396             // expected
    397         } catch (SAXException sax) {
    398             fail("Unexpected SAXException " + sax.toString());
    399         }
    400 
    401         // case 4: Try to parse incorrect xml file
    402         try {
    403             is = new InputSource(getClass().getResourceAsStream("/wrong.xml"));
    404             db.parse(is);
    405             fail("Expected SAXException was not thrown");
    406         } catch (IOException ioe) {
    407             fail("Unexpected IOException " + ioe.toString());
    408         } catch (SAXException sax) {
    409             // expected
    410         }
    411     }
    412 
    413     /**
    414      * javax.xml.parsers.DocumentBuilder#parse(java.io.InputStream,
    415      *     java.lang.String)
    416      * Case 1: Try to parse correct xml document.
    417      * Case 2: Try to call parse() with null argument.
    418      * Case 3: Try to parse a non-existent file.
    419      * Case 4: Try to parse incorrect xml file.
    420      */
    421     public void test_parseLjava_io_InputStreamLjava_lang_String() {
    422         InputStream is = getClass().getResourceAsStream("/systemid.xml");
    423         // case 1: Trivial use.
    424         try {
    425             Document d = db.parse(is, SAXParserTestSupport.XML_SYSTEM_ID);
    426             assertNotNull(d);
    427 //           TBD getXmlEncoding() is not supported
    428 //           assertEquals("UTF-8", d.getXmlEncoding());
    429             assertEquals(4, d.getChildNodes().getLength());
    430             assertEquals("collection",
    431                     d.getChildNodes().item(0).getNodeName());
    432             assertEquals("#comment",
    433                     d.getChildNodes().item(1).getNodeName());
    434             assertEquals("collection",
    435                     d.getChildNodes().item(2).getNodeName());
    436             assertEquals("#comment",
    437                     d.getChildNodes().item(3).getNodeName());
    438         } catch (IOException ioe) {
    439             fail("Unexpected IOException " + ioe.toString());
    440         } catch (SAXException sax) {
    441             fail("Unexpected SAXException " + sax.toString());
    442         }
    443 
    444         // case 2: Try to call parse with null argument
    445         try {
    446             db.parse((InputStream)null, SAXParserTestSupport.XML_SYSTEM_ID);
    447             fail("Expected IllegalArgumentException was not thrown");
    448         } catch (IllegalArgumentException iae) {
    449             // expected
    450         } catch (IOException ioe) {
    451             fail("Unexpected IOException " + ioe.toString());
    452         } catch (SAXException sax) {
    453             fail("Unexpected SAXException " + sax.toString());
    454         }
    455 
    456         // case 3: Try to parse a non-existent file
    457 // Doesn't make sense this way...
    458 //        try {
    459 //            db.parse(is, "/");
    460 //            fail("Expected IOException was not thrown");
    461 //        } catch (IOException ioe) {
    462 //            // expected
    463 //        } catch (SAXException sax) {
    464 //            fail("Unexpected SAXException " + sax.toString());
    465 //        }
    466 
    467         // case 4: Try to parse incorrect xml file
    468         try {
    469             is = getClass().getResourceAsStream("/wrong.xml");
    470             db.parse(is, SAXParserTestSupport.XML_SYSTEM_ID);
    471             fail("Expected SAXException was not thrown");
    472         } catch (IOException ioe) {
    473             fail("Unexpected IOException " + ioe.toString());
    474         } catch (SAXException sax) {
    475             // expected
    476         }
    477     }
    478 
    479     /**
    480      * javax.xml.parsers.DocumentBuilder#parse(java.lang.String)
    481      * Case 1: Try to parse correct xml document.
    482      * Case 2: Try to call parse() with null argument.
    483      * Case 3: Try to parse a non-existent uri.
    484      * Case 4: Try to parse incorrect xml file.
    485      */
    486     public void test_parseLjava_lang_String() throws Exception {
    487         // case 1: Trivial use.
    488         URL resource = getClass().getResource("/simple.xml");
    489         Document d = db.parse(resource.toString());
    490         assertNotNull(d);
    491 //          TBD  getXmlEncoding() is not supported
    492 //          assertEquals("ISO-8859-1", d.getXmlEncoding());
    493         assertEquals(2, d.getChildNodes().getLength());
    494         assertEquals("#comment",
    495                 d.getChildNodes().item(0).getNodeName());
    496         assertEquals("breakfast_menu",
    497                 d.getChildNodes().item(1).getNodeName());
    498 
    499         // case 2: Try to call parse with null argument
    500         try {
    501             db.parse((String)null);
    502             fail("Expected IllegalArgumentException was not thrown");
    503         } catch (IllegalArgumentException iae) {
    504             // expected
    505         }
    506 
    507         // case 3: Try to parse a non-existent uri
    508         try {
    509             db.parse("_");
    510             fail("Expected IOException was not thrown");
    511         } catch (IOException ioe) {
    512             // expected
    513         }
    514 
    515         // case 4: Try to parse incorrect xml file
    516         try {
    517             resource = getClass().getResource("/wrong.xml");
    518             db.parse(resource.toString());
    519             fail("Expected SAXException was not thrown");
    520         } catch (SAXException sax) {
    521             // expected
    522         }
    523     }
    524 
    525     public void testReset() {
    526         // Make sure EntityResolver gets reset
    527         InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
    528         InputStream entity = new ByteArrayInputStream("bar".getBytes());
    529 
    530         MockResolver resolver = new MockResolver();
    531         resolver.addEntity("foo", "foo", new InputSource(entity));
    532 
    533         Document d;
    534 
    535         try {
    536             db = dbf.newDocumentBuilder();
    537             db.setEntityResolver(resolver);
    538             db.reset();
    539             d = db.parse(source);
    540         } catch (Exception e) {
    541             throw new RuntimeException("Unexpected exception", e);
    542         }
    543 
    544         Element root = (Element)d.getElementsByTagName("a").item(0);
    545         assertEquals("foo", ((EntityReference)root.getFirstChild()).getNodeName());
    546 
    547         // Make sure ErrorHandler gets reset
    548         source = new ByteArrayInputStream("</a>".getBytes());
    549 
    550         MethodLogger logger = new MethodLogger();
    551         ErrorHandler handler = new MockHandler(logger);
    552 
    553         try {
    554             db = dbf.newDocumentBuilder();
    555             db.setErrorHandler(handler);
    556             db.reset();
    557             d = db.parse(source);
    558         } catch (SAXParseException e) {
    559             // Expected
    560         } catch (Exception e) {
    561             throw new RuntimeException("Unexpected exception", e);
    562         }
    563 
    564         assertEquals(0, logger.size());
    565     }
    566 
    567     public void testSetErrorHandler() {
    568         // Ordinary case
    569         InputStream source = new ByteArrayInputStream("</a>".getBytes());
    570 
    571         MethodLogger logger = new MethodLogger();
    572         ErrorHandler handler = new MockHandler(logger);
    573 
    574         try {
    575             db = dbf.newDocumentBuilder();
    576             db.setErrorHandler(handler);
    577             db.parse(source);
    578         } catch (SAXParseException e) {
    579             // Expected, ErrorHandler does not mask exception
    580         } catch (Exception e) {
    581             throw new RuntimeException("Unexpected exception", e);
    582         }
    583 
    584         assertEquals("error", logger.getMethod());
    585         assertTrue(logger.getArgs()[0] instanceof SAXParseException);
    586 
    587         // null case
    588         source = new ByteArrayInputStream("</a>".getBytes());
    589 
    590         try {
    591             db = dbf.newDocumentBuilder();
    592             db.setErrorHandler(null);
    593             db.parse(source);
    594         } catch (SAXParseException e) {
    595             // Expected
    596         } catch (Exception e) {
    597             throw new RuntimeException("Unexpected exception", e);
    598         }
    599     }
    600 
    601     public void testSetEntityResolver() {
    602         // Ordinary case
    603         InputStream source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
    604         InputStream entity = new ByteArrayInputStream("bar".getBytes());
    605 
    606         MockResolver resolver = new MockResolver();
    607         resolver.addEntity("foo", "foo", new InputSource(entity));
    608 
    609         Document d;
    610 
    611         try {
    612             db = dbf.newDocumentBuilder();
    613             db.setEntityResolver(resolver);
    614             d = db.parse(source);
    615         } catch (Exception e) {
    616             throw new RuntimeException("Unexpected exception", e);
    617         }
    618 
    619         Element root = (Element)d.getElementsByTagName("a").item(0);
    620         assertEquals("bar", ((Text)root.getFirstChild()).getData());
    621 
    622         // null case
    623         source = new ByteArrayInputStream("<a>&foo;</a>".getBytes());
    624 
    625         try {
    626             db = dbf.newDocumentBuilder();
    627             db.setEntityResolver(null);
    628             d = db.parse(source);
    629         } catch (Exception e) {
    630             throw new RuntimeException("Unexpected exception", e);
    631         }
    632 
    633         root = (Element)d.getElementsByTagName("a").item(0);
    634         assertEquals("foo", ((EntityReference)root.getFirstChild()).getNodeName());
    635     }
    636 
    637 }
    638