1/*
2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.xml.sax.ptests;
24
25import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
26import static jaxp.library.JAXPTestUtilities.USER_DIR;
27import static jaxp.library.JAXPTestUtilities.compareWithGold;
28import static org.testng.Assert.assertTrue;
29import static org.xml.sax.ptests.SAXTestConst.GOLDEN_DIR;
30import static org.xml.sax.ptests.SAXTestConst.XML_DIR;
31
32import java.io.BufferedWriter;
33import java.io.FileInputStream;
34import java.io.FileWriter;
35import java.io.IOException;
36import java.net.URI;
37import java.net.URISyntaxException;
38import java.nio.file.Files;
39import java.nio.file.Paths;
40
41import javax.xml.parsers.SAXParser;
42import javax.xml.parsers.SAXParserFactory;
43
44import org.testng.annotations.Listeners;
45import org.testng.annotations.Test;
46import org.xml.sax.InputSource;
47import org.xml.sax.SAXException;
48import org.xml.sax.XMLReader;
49import org.xml.sax.helpers.XMLFilterImpl;
50
51/**
52 * Entity resolver should be invoked in XML parse. This test verifies parsing
53 * process by checking the output with golden file.
54 */
55/*
56 * @test
57 * @library /javax/xml/jaxp/libs
58 * @run testng/othervm -DrunSecMngr=true org.xml.sax.ptests.ResolverTest
59 * @run testng/othervm org.xml.sax.ptests.ResolverTest
60 */
61@Test
62@Listeners({jaxp.library.FilePolicy.class})
63public class ResolverTest {
64    /**
65     * Unit test for entityResolver setter.
66     *
67     * @throws Exception If any errors occur.
68     */
69    public void testResolver() throws Exception {
70        String outputFile = USER_DIR + "EntityResolver.out";
71        String goldFile = GOLDEN_DIR + "EntityResolverGF.out";
72        String xmlFile = XML_DIR + "publish.xml";
73
74        Files.copy(Paths.get(XML_DIR + "publishers.dtd"),
75                Paths.get(USER_DIR + "publishers.dtd"), REPLACE_EXISTING);
76        Files.copy(Paths.get(XML_DIR + "familytree.dtd"),
77                Paths.get(USER_DIR + "familytree.dtd"), REPLACE_EXISTING);
78
79        try(FileInputStream instream = new FileInputStream(xmlFile);
80                MyEntityResolver eResolver = new MyEntityResolver(outputFile)) {
81            SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
82            XMLReader xmlReader = saxParser.getXMLReader();
83            xmlReader.setEntityResolver(eResolver);
84            InputSource is = new InputSource(instream);
85            xmlReader.parse(is);
86        }
87        assertTrue(compareWithGold(goldFile, outputFile));
88    }
89}
90
91/**
92 * Simple entity resolver to write every entity to an output file.
93 */
94class MyEntityResolver extends XMLFilterImpl implements AutoCloseable {
95    /**
96     * FileWriter to write string to output file.
97     */
98    private final BufferedWriter bWriter;
99
100    /**
101     * Initiate FileWriter when construct a MyContentHandler.
102     * @param outputFileName output file name.
103     * @throws SAXException creation of FileWriter failed.
104     */
105    MyEntityResolver(String outputFileName) throws SAXException {
106        super();
107        try {
108            bWriter = new BufferedWriter(new FileWriter(outputFileName));
109        } catch (IOException ex) {
110            throw new SAXException(ex);
111        }
112    }
113
114    /**
115     * Write In resolveEntity tag along with publicid and systemId when meet
116     * resolveEntity event.
117     * @throws IOException error happen when writing file.
118     */
119    @Override
120    public InputSource resolveEntity(String publicid, String systemid)
121            throws SAXException, IOException {
122        String str = "In resolveEntity.." + " " + publicid + " " + getFileName(systemid);
123        bWriter.write( str, 0,str.length());
124        bWriter.newLine();
125        return super.resolveEntity(publicid, systemid);
126    }
127
128    /**
129     * Flush the content and close the file.
130     * @throws IOException error happen when writing file or closing file.
131     */
132    @Override
133    public void close() throws IOException {
134        bWriter.flush();
135        bWriter.close();
136    }
137
138    private String getFileName(String systemid) {
139        try {
140            return Paths.get(new URI(systemid)).getFileName().toString();
141        } catch (URISyntaxException e) {
142            throw new RuntimeException(e);
143        }
144    }
145}
146