1/*
2 * Copyright (c) 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 */
23
24import static org.testng.Assert.assertEquals;
25import static org.testng.Assert.assertTrue;
26
27import java.io.File;
28import java.net.URL;
29import java.net.URLClassLoader;
30import java.nio.file.Files;
31import java.nio.file.Path;
32import java.nio.file.Paths;
33
34import jdk.test.lib.compiler.CompilerUtils;
35
36import org.testng.Assert;
37import org.testng.annotations.BeforeTest;
38import org.testng.annotations.Test;
39import org.xml.sax.XMLReader;
40import org.xml.sax.helpers.XMLReaderFactory;
41
42/*
43 * @test
44 * @library /test/lib
45 * @run testng XMLReaderFactoryTest
46 * @bug 8152912 8015099 8156119
47 * @summary Tests XMLReaderFactory can work as ServiceLoader compliant, as well as backward compatible
48 */
49
50@Test
51public class XMLReaderFactoryTest {
52    private static final String TEST_SRC = System.getProperty("test.src");
53
54    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src").resolve("xmlprovider3");
55    private static final Path CLASSES_DIR = Paths.get("classes");
56    private static final Path LEGACY_DIR = CLASSES_DIR.resolve("legacy");
57    private static final Path SERVICE_DIR = CLASSES_DIR.resolve("service");
58
59    // resources to copy to the class path
60    private static final String LEGACY_SERVICE_FILE = "legacy/META-INF/services/org.xml.sax.driver";
61    private static final String SERVICE_FILE = "service/META-INF/services/org.xml.sax.XMLReader";
62
63    /*
64     * Compile class and copy service files
65     */
66    @BeforeTest
67    public void setup() throws Exception {
68        setup(LEGACY_DIR, LEGACY_SERVICE_FILE);
69        setup(SERVICE_DIR, SERVICE_FILE);
70    }
71
72    private void setup(Path dest, String serviceFile) throws Exception {
73        Files.createDirectories(dest);
74        assertTrue(CompilerUtils.compile(SRC_DIR, dest));
75
76        Path file = Paths.get(serviceFile.replace('/', File.separatorChar));
77        Path source = SRC_DIR.resolve(file);
78        Path target = CLASSES_DIR.resolve(file);
79        Files.createDirectories(target.getParent());
80        Files.copy(source, target);
81
82    }
83
84    public void testService() throws Exception {
85        ClassLoader clBackup = Thread.currentThread().getContextClassLoader();
86        try {
87            URL[] classUrls = { SERVICE_DIR.toUri().toURL() };
88            URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent());
89
90            // set TCCL and try locating the provider
91            Thread.currentThread().setContextClassLoader(loader);
92            XMLReader reader = XMLReaderFactory.createXMLReader();
93            assertEquals(reader.getClass().getName(), "xp3.XMLReaderImpl");
94        } finally {
95            Thread.currentThread().setContextClassLoader(clBackup);
96        }
97    }
98
99    public void testLegacy() throws Exception {
100        ClassLoader clBackup = Thread.currentThread().getContextClassLoader();
101        try {
102            URL[] classUrls = { LEGACY_DIR.toUri().toURL() };
103            URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent());
104
105            // set TCCL and try locating the provider
106            Thread.currentThread().setContextClassLoader(loader);
107            XMLReader reader1 = XMLReaderFactory.createXMLReader();
108            assertEquals(reader1.getClass().getName(), "xp3.XMLReaderImpl");
109
110            // now point to a random URL
111            Thread.currentThread().setContextClassLoader(
112                    new URLClassLoader(new URL[0], ClassLoader.getSystemClassLoader().getParent()));
113            // ClassNotFoundException if also trying to load class of reader1, which
114            // would be the case before 8152912
115            XMLReader reader2 = XMLReaderFactory.createXMLReader();
116            assertEquals(reader2.getClass().getName(), "com.sun.org.apache.xerces.internal.parsers.SAXParser");
117        } finally {
118            Thread.currentThread().setContextClassLoader(clBackup);
119        }
120    }
121}
122