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