1 /*
   2  * Copyright (c) 1999, 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 package javax.xml.validation.ptests;
  24 
  25 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
  26 import static javax.xml.validation.ptests.ValidationTestConst.XML_DIR;
  27 import static org.testng.Assert.assertNotNull;
  28 import static org.testng.Assert.assertNull;
  29 import static org.testng.Assert.assertSame;
  30 import static org.testng.Assert.assertTrue;
  31 
  32 import java.io.ByteArrayInputStream;
  33 import java.io.File;
  34 import java.io.IOException;
  35 import java.io.InputStream;
  36 import java.net.URL;
  37 import java.nio.file.Files;
  38 import java.nio.file.Paths;
  39 
  40 import javax.xml.parsers.DocumentBuilder;
  41 import javax.xml.parsers.DocumentBuilderFactory;
  42 import javax.xml.parsers.ParserConfigurationException;
  43 import javax.xml.stream.XMLInputFactory;
  44 import javax.xml.stream.XMLStreamException;
  45 import javax.xml.transform.Source;
  46 import javax.xml.transform.dom.DOMSource;
  47 import javax.xml.transform.sax.SAXSource;
  48 import javax.xml.transform.stax.StAXSource;
  49 import javax.xml.transform.stream.StreamSource;
  50 import javax.xml.validation.Schema;
  51 import javax.xml.validation.SchemaFactory;
  52 
  53 import jaxp.library.JAXPDataProvider;
  54 
  55 import org.testng.annotations.BeforeClass;
  56 import org.testng.annotations.DataProvider;
  57 import org.testng.annotations.Test;
  58 import org.w3c.dom.Document;
  59 import org.xml.sax.ErrorHandler;
  60 import org.xml.sax.InputSource;
  61 import org.xml.sax.SAXException;
  62 import org.xml.sax.SAXNotRecognizedException;
  63 import org.xml.sax.SAXNotSupportedException;
  64 import org.xml.sax.SAXParseException;
  65 
  66 /*
  67  * @bug 8080907
  68  * @summary Class containing the test cases for SchemaFactory
  69  */
  70 @Test(singleThreaded = true)
  71 public class SchemaFactoryTest {
  72 
  73     @BeforeClass
  74     public void setup() throws SAXException, IOException, ParserConfigurationException {
  75         sf = newSchemaFactory();
  76         assertNotNull(sf);
  77 
  78         ifac = XMLInputFactory.newInstance();
  79 
  80         xsd1 = Files.readAllBytes(Paths.get(XML_DIR + "test.xsd"));
  81         xsd2 = Files.readAllBytes(Paths.get(XML_DIR + "test1.xsd"));
  82 
  83         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  84         dbf.setNamespaceAware(true);
  85         DocumentBuilder db = dbf.newDocumentBuilder();
  86         xsdDoc1 = db.parse(newInputStream(xsd1));
  87         xsdDoc2 = db.parse(newInputStream(xsd2));
  88 
  89         xml = Files.readAllBytes(Paths.get(XML_DIR + "test.xml"));
  90     }
  91 
  92 
  93     @DataProvider(name = "parameters")
  94     public Object[][] getValidateParameters() {
  95         return new Object[][] { { W3C_XML_SCHEMA_NS_URI, SCHEMA_FACTORY_CLASSNAME, null },
  96                 { W3C_XML_SCHEMA_NS_URI, SCHEMA_FACTORY_CLASSNAME, this.getClass().getClassLoader() } };
  97     }
  98 
  99     /*
 100      * test for SchemaFactory.newInstance(java.lang.String schemaLanguage,
 101      * java.lang.String factoryClassName, java.lang.ClassLoader classLoader)
 102      * factoryClassName points to correct implementation of
 103      * javax.xml.validation.SchemaFactory , should return newInstance of
 104      * SchemaFactory
 105      */
 106     @Test(dataProvider = "parameters")
 107     public void testNewInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) throws SAXException {
 108         SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI, SCHEMA_FACTORY_CLASSNAME, null);
 109         Schema schema = sf.newSchema();
 110         assertNotNull(schema);
 111     }
 112 
 113     /*
 114      * test for SchemaFactory.newInstance(java.lang.String schemaLanguage,
 115      * java.lang.String factoryClassName, java.lang.ClassLoader classLoader)
 116      * factoryClassName is null , should throw IllegalArgumentException
 117      */
 118     @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "new-instance-neg", dataProviderClass = JAXPDataProvider.class)
 119     public void testNewInstanceWithNullFactoryClassName(String factoryClassName, ClassLoader classLoader) {
 120 
 121         SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI, factoryClassName, classLoader);
 122     }
 123 
 124     /*
 125      * test for SchemaFactory.newInstance(java.lang.String schemaLanguage,
 126      * java.lang.String factoryClassName, java.lang.ClassLoader classLoader)
 127      * schemaLanguage is null , should throw NPE
 128      */
 129     @Test(expectedExceptions = NullPointerException.class)
 130     public void testNewInstanceWithNullSchemaLanguage() {
 131         SchemaFactory.newInstance(null, SCHEMA_FACTORY_CLASSNAME, this.getClass().getClassLoader());
 132     }
 133 
 134     /*
 135      * test for SchemaFactory.newInstance(java.lang.String schemaLanguage,
 136      * java.lang.String factoryClassName, java.lang.ClassLoader classLoader)
 137      * schemaLanguage is empty , should throw IllegalArgumentException
 138      */
 139     @Test(expectedExceptions = IllegalArgumentException.class)
 140     public void testNewInstanceWithEmptySchemaLanguage() {
 141         SchemaFactory.newInstance("", SCHEMA_FACTORY_CLASSNAME, this.getClass().getClassLoader());
 142     }
 143 
 144 
 145     @Test(expectedExceptions = SAXParseException.class)
 146     public void testNewSchemaDefault() throws SAXException, IOException {
 147         validate(sf.newSchema());
 148     }
 149 
 150     @Test
 151     public void testNewSchemaWithFile() throws SAXException, IOException {
 152         validate(sf.newSchema(new File(XML_DIR + "test.xsd")));
 153     }
 154 
 155     @Test(expectedExceptions = NullPointerException.class)
 156     public void testNewSchemaWithNullFile() throws SAXException {
 157         sf.newSchema((File) null);
 158     }
 159 
 160     @DataProvider(name = "valid-source")
 161     public Object[][] getValidSource() throws XMLStreamException {
 162         return new Object[][] {
 163                 { streamSource(xsd1) },
 164                 { saxSource(xsd1) },
 165                 { domSource(xsdDoc1) },
 166                 { staxStreamSource(xsd1) },
 167                 { staxEventSource(xsd1) } };
 168 
 169     }
 170 
 171     @Test(dataProvider = "valid-source")
 172     public void testNewSchemaWithValidSource(Source schema) throws SAXException, IOException {
 173         validate(sf.newSchema(schema));
 174     }
 175 
 176     @DataProvider(name = "invalid-source")
 177     public Object[][] getInvalidSource() {
 178         return new Object[][] {
 179                 { nullStreamSource() },
 180                 { nullSaxSource() } };
 181     }
 182 
 183     @Test(dataProvider = "invalid-source", expectedExceptions = SAXParseException.class)
 184     public void testNewSchemaWithInvalidSource(Source schema) throws SAXException {
 185         sf.newSchema(schema);
 186     }
 187 
 188     @Test(expectedExceptions = NullPointerException.class)
 189     public void testNewSchemaWithNullSource() throws SAXException {
 190         sf.newSchema((Source)null);
 191     }
 192 
 193     @DataProvider(name = "valid-sources")
 194     public Object[][] getValidSources() {
 195         return new Object[][] {
 196                 { streamSource(xsd1), streamSource(xsd2) },
 197                 { saxSource(xsd1), saxSource(xsd2) },
 198                 { domSource(xsdDoc1), domSource(xsdDoc2) } };
 199 
 200     }
 201 
 202     @Test(dataProvider = "valid-sources")
 203     public void testNewSchemaWithValidSourceArray(Source schema1, Source schema2) throws SAXException, IOException {
 204         validate(sf.newSchema(new Source[] { schema1, schema2 }));
 205     }
 206 
 207     @DataProvider(name = "invalid-sources")
 208     public Object[][] getInvalidSources() {
 209         return new Object[][] {
 210                 { streamSource(xsd1), nullStreamSource() },
 211                 { nullStreamSource(), nullStreamSource() },
 212                 { saxSource(xsd1), nullSaxSource() },
 213                 { nullSaxSource(), nullSaxSource() } };
 214     }
 215 
 216     @Test(dataProvider = "invalid-sources", expectedExceptions = SAXParseException.class)
 217     public void testNewSchemaWithInvalidSourceArray(Source schema1, Source schema2) throws SAXException {
 218         sf.newSchema(new Source[] { schema1, schema2 });
 219     }
 220 
 221     @DataProvider(name = "null-sources")
 222     public Object[][] getNullSources() {
 223         return new Object[][] {
 224                 { new Source[] { domSource(xsdDoc1), null } },
 225                 { new Source[] { null, null } },
 226                 { null } };
 227 
 228     }
 229 
 230     @Test(dataProvider = "null-sources", expectedExceptions = NullPointerException.class)
 231     public void testNewSchemaWithNullSourceArray(Source[] schemas) throws SAXException {
 232         sf.newSchema(schemas);
 233     }
 234 
 235     @Test(expectedExceptions = NullPointerException.class)
 236     public void testNewSchemaWithNullUrl() throws SAXException {
 237         sf.newSchema((URL) null);
 238     }
 239 
 240 
 241     @Test
 242     public void testErrorHandler() {
 243         SchemaFactory sf = newSchemaFactory();
 244         assertNull(sf.getErrorHandler(), "When SchemaFactory is created, initially ErrorHandler should not be set.");
 245 
 246         ErrorHandler handler = new MyErrorHandler();
 247         sf.setErrorHandler(handler);
 248         assertSame(sf.getErrorHandler(), handler);
 249 
 250         sf.setErrorHandler(null);
 251         assertNull(sf.getErrorHandler());
 252     }
 253 
 254     @Test(expectedExceptions = SAXNotRecognizedException.class)
 255     public void testGetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
 256         SchemaFactory sf = newSchemaFactory();
 257         sf.getProperty(UNRECOGNIZED_NAME);
 258 
 259     }
 260 
 261     @Test(expectedExceptions = SAXNotRecognizedException.class)
 262     public void testSetUnrecognizedProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
 263         SchemaFactory sf = newSchemaFactory();
 264         sf.setProperty(UNRECOGNIZED_NAME, "test");
 265     }
 266 
 267     @Test(expectedExceptions = NullPointerException.class)
 268     public void testGetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
 269         SchemaFactory sf = newSchemaFactory();
 270         assertNotNull(sf);
 271         sf.getProperty(null);
 272 
 273     }
 274 
 275     @Test(expectedExceptions = NullPointerException.class)
 276     public void testSetNullProperty() throws SAXNotRecognizedException, SAXNotSupportedException {
 277         SchemaFactory sf = newSchemaFactory();
 278         assertNotNull(sf);
 279         sf.setProperty(null, "test");
 280     }
 281 
 282     @Test(expectedExceptions = SAXNotRecognizedException.class)
 283     public void testGetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
 284         SchemaFactory sf = newSchemaFactory();
 285         sf.getFeature(UNRECOGNIZED_NAME);
 286 
 287     }
 288 
 289     @Test(expectedExceptions = SAXNotRecognizedException.class)
 290     public void testSetUnrecognizedFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
 291         SchemaFactory sf = newSchemaFactory();
 292         sf.setFeature(UNRECOGNIZED_NAME, true);
 293     }
 294 
 295     @Test(expectedExceptions = NullPointerException.class)
 296     public void testGetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
 297         SchemaFactory sf = newSchemaFactory();
 298         assertNotNull(sf);
 299         sf.getFeature(null);
 300 
 301     }
 302 
 303     @Test(expectedExceptions = NullPointerException.class)
 304     public void testSetNullFeature() throws SAXNotRecognizedException, SAXNotSupportedException {
 305         SchemaFactory sf = newSchemaFactory();
 306         assertNotNull(sf);
 307         sf.setFeature(null, true);
 308     }
 309 
 310     @DataProvider(name = "source-feature")
 311     public Object[][] getSourceFeature() {
 312         return new Object[][] {
 313                 { StreamSource.FEATURE },
 314                 { SAXSource.FEATURE },
 315                 { DOMSource.FEATURE },
 316                 { DOMSource.FEATURE } };
 317 
 318     }
 319 
 320     /*
 321      * Return true for each of the JAXP Source features to indicate that this
 322      * SchemaFactory supports all of the built-in JAXP Source types.
 323      */
 324     @Test(dataProvider = "source-feature")
 325     public void testSourceFeatureGet(String sourceFeature) throws Exception {
 326         assertTrue(newSchemaFactory().getFeature(sourceFeature));
 327     }
 328 
 329     /*
 330      * JAXP Source features are read-only because this SchemaFactory always
 331      * supports all JAXP Source types.
 332      */
 333     @Test(dataProvider = "source-feature", expectedExceptions = SAXNotSupportedException.class)
 334     public void testSourceFeatureSet(String sourceFeature) throws Exception {
 335         newSchemaFactory().setFeature(sourceFeature, false);
 336     }
 337 
 338     @Test(expectedExceptions = IllegalArgumentException.class)
 339     public void testInvalidSchemaLanguage() {
 340         final String INVALID_SCHEMA_LANGUAGE = "http://relaxng.org/ns/structure/1.0";
 341         SchemaFactory.newInstance(INVALID_SCHEMA_LANGUAGE);
 342     }
 343 
 344     @Test(expectedExceptions = NullPointerException.class)
 345     public void testNullSchemaLanguage() {
 346         SchemaFactory.newInstance(null);
 347     }
 348 
 349     private void validate(Schema schema) throws SAXException, IOException {
 350         schema.newValidator().validate(new StreamSource(new ByteArrayInputStream(xml)));
 351     }
 352     private InputStream newInputStream(byte[] xsd) {
 353         return new ByteArrayInputStream(xsd);
 354     }
 355 
 356     private Source streamSource(byte[] xsd) {
 357         return new StreamSource(newInputStream(xsd));
 358     }
 359 
 360     private Source nullStreamSource() {
 361         return new StreamSource((InputStream) null);
 362     }
 363 
 364     private Source saxSource(byte[] xsd) {
 365         return new SAXSource(new InputSource(newInputStream(xsd)));
 366     }
 367 
 368     private Source nullSaxSource() {
 369         return new SAXSource(new InputSource((InputStream) null));
 370     }
 371 
 372     private Source domSource(Document xsdDoc) {
 373         return new DOMSource(xsdDoc);
 374     }
 375 
 376     private Source staxStreamSource(byte[] xsd) throws XMLStreamException {
 377         return new StAXSource(ifac.createXMLStreamReader(newInputStream(xsd)));
 378     }
 379 
 380     private Source staxEventSource(byte[] xsd) throws XMLStreamException {
 381         return new StAXSource(ifac.createXMLEventReader(newInputStream(xsd)));
 382     }
 383 
 384 
 385     private SchemaFactory newSchemaFactory() {
 386         return SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
 387     }
 388 
 389     private static final String UNRECOGNIZED_NAME = "http://xml.org/sax/features/namespace-prefixes";
 390 
 391     private static final String SCHEMA_FACTORY_CLASSNAME = "com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory";
 392 
 393     private SchemaFactory sf;
 394     private XMLInputFactory ifac;
 395     private byte[] xsd1;
 396     private byte[] xsd2;
 397     private Document xsdDoc1;
 398     private Document xsdDoc2;
 399     private byte[] xml;
 400 }