1 /*
   2  * Copyright (c) 2014, 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 
  24 package javax.xml.common;
  25 
  26 import java.io.InputStream;
  27 import java.io.StringWriter;
  28 import java.security.AllPermission;
  29 import java.security.Permission;
  30 import java.security.Permissions;
  31 
  32 import javax.xml.XMLConstants;
  33 import javax.xml.parsers.DocumentBuilder;
  34 import javax.xml.parsers.DocumentBuilderFactory;
  35 import javax.xml.transform.Transformer;
  36 import javax.xml.transform.TransformerFactory;
  37 import javax.xml.transform.dom.DOMSource;
  38 import javax.xml.transform.sax.SAXSource;
  39 import javax.xml.transform.stream.StreamResult;
  40 import javax.xml.transform.stream.StreamSource;
  41 import javax.xml.validation.Schema;
  42 import javax.xml.validation.SchemaFactory;
  43 import javax.xml.validation.Validator;
  44 import javax.xml.xpath.XPath;
  45 import javax.xml.xpath.XPathFactory;
  46 
  47 import org.testng.Assert;
  48 import org.testng.annotations.Test;
  49 import org.w3c.dom.Document;
  50 import org.xml.sax.InputSource;
  51 
  52 /*
  53  * @bug 6941169
  54  * @summary Test use-service-mechanism feature.
  55  */
  56 public class Bug6941169Test {
  57     static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
  58     static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
  59 
  60     private static final String DOM_FACTORY_ID = "javax.xml.parsers.DocumentBuilderFactory";
  61     private static final String SAX_FACTORY_ID = "javax.xml.parsers.SAXParserFactory";
  62 
  63     // impl specific feature
  64     final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
  65 
  66     static String _xml = Bug6941169Test.class.getResource("Bug6941169.xml").getPath();
  67     static String _xsd = Bug6941169Test.class.getResource("Bug6941169.xsd").getPath();
  68 
  69     @Test
  70     public void testValidation_SAX_withoutServiceMech() {
  71         System.out.println("Validation using SAX Source;  Service mechnism is turned off;  SAX Impl should be the default:");
  72         InputSource is = new InputSource(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml"));
  73         SAXSource ss = new SAXSource(is);
  74         System.setProperty(SAX_FACTORY_ID, "MySAXFactoryImpl");
  75         long start = System.currentTimeMillis();
  76         try {
  77             SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
  78             factory.setFeature(ORACLE_FEATURE_SERVICE_MECHANISM, false);
  79             Schema schema = factory.newSchema(new StreamSource(_xsd));
  80             Validator validator = schema.newValidator();
  81             validator.validate(ss, null);
  82         } catch (Exception e) {
  83             // e.printStackTrace();
  84             String error = e.getMessage();
  85             if (error.indexOf("javax.xml.parsers.FactoryConfigurationError: Provider MySAXFactoryImpl not found") > 0) {
  86                 Assert.fail(e.getMessage());
  87             } else {
  88                 System.out.println("Default impl is used");
  89             }
  90 
  91             // System.out.println(e.getMessage());
  92 
  93         }
  94         long end = System.currentTimeMillis();
  95         double elapsedTime = ((end - start));
  96         System.out.println("Time elapsed: " + elapsedTime);
  97         System.clearProperty(SAX_FACTORY_ID);
  98     }
  99 
 100     @Test
 101     public void testValidation_SAX_withServiceMech() {
 102         System.out.println("Validation using SAX Source. Using service mechnism (by default) to find SAX Impl:");
 103         InputSource is = new InputSource(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml"));
 104         SAXSource ss = new SAXSource(is);
 105         System.setProperty(SAX_FACTORY_ID, "MySAXFactoryImpl");
 106         long start = System.currentTimeMillis();
 107         try {
 108             SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
 109             Schema schema = factory.newSchema(new StreamSource(_xsd));
 110             Validator validator = schema.newValidator();
 111             validator.validate(ss, null);
 112             Assert.fail("User impl MySAXFactoryImpl should be used.");
 113         } catch (Exception e) {
 114             String error = e.getMessage();
 115             if (error.indexOf("javax.xml.parsers.FactoryConfigurationError: Provider MySAXFactoryImpl not found") > 0) {
 116                 // expected
 117             }
 118             // System.out.println(e.getMessage());
 119 
 120         }
 121         long end = System.currentTimeMillis();
 122         double elapsedTime = ((end - start));
 123         System.out.println("Time elapsed: " + elapsedTime);
 124         System.clearProperty(SAX_FACTORY_ID);
 125     }
 126 
 127     @Test
 128     public void testValidation_SAX_withSM() {
 129         System.out.println("Validation using SAX Source with security manager:");
 130         InputSource is = new InputSource(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml"));
 131         SAXSource ss = new SAXSource(is);
 132         System.setProperty(SAX_FACTORY_ID, "MySAXFactoryImpl");
 133         Permissions granted = new java.security.Permissions();
 134         granted.add(new AllPermission());
 135         System.setSecurityManager(new MySM(granted));
 136 
 137         long start = System.currentTimeMillis();
 138         try {
 139             SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
 140             factory.setFeature(ORACLE_FEATURE_SERVICE_MECHANISM, false);
 141             Schema schema = factory.newSchema(new StreamSource(_xsd));
 142             Validator validator = schema.newValidator();
 143             validator.validate(ss, null);
 144         } catch (Exception e) {
 145             String error = e.getMessage();
 146             if (error.indexOf("javax.xml.parsers.FactoryConfigurationError: Provider MySAXFactoryImpl not found") > 0) {
 147                 Assert.fail(e.getMessage());
 148             } else {
 149                 System.out.println("Default impl is used");
 150             }
 151 
 152             // System.out.println(e.getMessage());
 153 
 154         } finally {
 155             System.clearProperty(SAX_FACTORY_ID);
 156             System.setSecurityManager(null);
 157         }
 158         long end = System.currentTimeMillis();
 159         double elapsedTime = ((end - start));
 160         System.out.println("Time elapsed: " + elapsedTime);
 161         System.setSecurityManager(null);
 162 
 163     }
 164 
 165     @Test
 166     public void testTransform_DOM_withoutServiceMech() {
 167         System.out.println("Transform using DOM Source;  Service mechnism is turned off;  Default DOM Impl should be the default:");
 168         DOMSource domSource = new DOMSource();
 169         domSource.setSystemId(_xml);
 170 
 171         // DOMSource domSource = new
 172         // DOMSource(getDocument(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml")));
 173         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 174         long start = System.currentTimeMillis();
 175         try {
 176             TransformerFactory factory = TransformerFactory.newInstance();
 177             factory.setFeature(ORACLE_FEATURE_SERVICE_MECHANISM, false);
 178 
 179             Transformer t = factory.newTransformer();
 180 
 181             StringWriter result = new StringWriter();
 182             StreamResult streamResult = new StreamResult(result);
 183             t.transform(domSource, streamResult);
 184             System.out.println("Writing to " + result.toString());
 185 
 186         } catch (Exception e) {
 187             // e.printStackTrace();
 188             String error = e.getMessage();
 189             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 190                 Assert.fail(e.getMessage());
 191             } else {
 192                 System.out.println("Default impl is used");
 193             }
 194 
 195             // System.out.println(e.getMessage());
 196 
 197         } catch (Error e) {
 198             // e.printStackTrace();
 199             String error = e.getMessage();
 200             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 201                 Assert.fail(e.getMessage());
 202             } else {
 203                 System.out.println("Default impl is used");
 204             }
 205 
 206             // System.out.println(e.getMessage());
 207 
 208         }
 209 
 210         long end = System.currentTimeMillis();
 211         double elapsedTime = ((end - start));
 212         System.out.println("Time elapsed: " + elapsedTime);
 213         System.clearProperty(DOM_FACTORY_ID);
 214     }
 215 
 216     /** this is by default */
 217     @Test
 218     public void testTransform_DOM_withServiceMech() {
 219         System.out.println("Transform using DOM Source;  By default, the factory uses services mechanism to look up impl:");
 220         DOMSource domSource = new DOMSource();
 221         domSource.setSystemId(_xml);
 222 
 223         // DOMSource domSource = new
 224         // DOMSource(getDocument(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml")));
 225         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 226         long start = System.currentTimeMillis();
 227         try {
 228             TransformerFactory factory = TransformerFactory.newInstance();
 229             Transformer t = factory.newTransformer();
 230 
 231             StringWriter result = new StringWriter();
 232             StreamResult streamResult = new StreamResult(result);
 233             t.transform(domSource, streamResult);
 234             System.out.println("Writing to " + result.toString());
 235 
 236             Assert.fail("User impl MyDOMFactoryImpl should be used.");
 237 
 238         } catch (Exception e) {
 239             String error = e.getMessage();
 240             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 241                 // expected
 242             }
 243             System.out.println(error);
 244 
 245         } catch (Error e) {
 246             String error = e.getMessage();
 247             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 248                 // expected
 249             }
 250             System.out.println(error);
 251 
 252         }
 253 
 254         long end = System.currentTimeMillis();
 255         double elapsedTime = ((end - start));
 256         System.out.println("Time elapsed: " + elapsedTime);
 257         System.clearProperty(DOM_FACTORY_ID);
 258     }
 259 
 260     @Test
 261     public void testTransform_DOM_withSM() {
 262         System.out.println("Transform using DOM Source;  Security Manager is set:");
 263         DOMSource domSource = new DOMSource();
 264         domSource.setSystemId(_xml);
 265 
 266         // DOMSource domSource = new
 267         // DOMSource(getDocument(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml")));
 268         Permissions granted = new java.security.Permissions();
 269         granted.add(new AllPermission());
 270         System.setSecurityManager(new MySM(granted));
 271         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 272         long start = System.currentTimeMillis();
 273         try {
 274             TransformerFactory factory = TransformerFactory.newInstance("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl",
 275                     TransformerFactory.class.getClassLoader());
 276             Transformer t = factory.newTransformer();
 277 
 278             StringWriter result = new StringWriter();
 279             StreamResult streamResult = new StreamResult(result);
 280             t.transform(domSource, streamResult);
 281             System.out.println("Writing to " + result.toString());
 282 
 283         } catch (Exception e) {
 284             String error = e.getMessage();
 285             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 286                 Assert.fail(e.getMessage());
 287             } else {
 288                 System.out.println("Default impl is used");
 289             }
 290 
 291             // System.out.println(e.getMessage());
 292 
 293         } catch (Error e) {
 294             String error = e.getMessage();
 295             if (error.indexOf("Provider MyDOMFactoryImpl not found") > 0) {
 296                 Assert.fail(e.getMessage());
 297             } else {
 298                 System.out.println("Default impl is used");
 299             }
 300 
 301             // System.out.println(e.getMessage());
 302 
 303         } finally {
 304             System.clearProperty(DOM_FACTORY_ID);
 305             System.setSecurityManager(null);
 306         }
 307         long end = System.currentTimeMillis();
 308         double elapsedTime = ((end - start));
 309         System.out.println("Time elapsed: " + elapsedTime);
 310         System.clearProperty(DOM_FACTORY_ID);
 311     }
 312 
 313     @Test
 314     public void testXPath_DOM_withoutServiceMech() {
 315         final String XPATH_EXPRESSION = "/fooTest";
 316         System.out.println("Evaluate DOM Source;  Service mechnism is turned off;  Default DOM Impl should be used:");
 317         Document doc = getDocument(Bug6941169Test.class.getResourceAsStream("Bug6941169.xml"));
 318         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 319         long start = System.currentTimeMillis();
 320         try {
 321             XPathFactory xPathFactory = XPathFactory.newInstance();
 322             xPathFactory.setFeature(ORACLE_FEATURE_SERVICE_MECHANISM, false);
 323 
 324             XPath xPath = xPathFactory.newXPath();
 325 
 326             String xPathResult = xPath.evaluate(XPATH_EXPRESSION, doc);
 327 
 328         } catch (Exception e) {
 329             // e.printStackTrace();
 330             String error = e.getMessage();
 331             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 332                 Assert.fail(e.getMessage());
 333             } else {
 334                 System.out.println("Default impl is used");
 335             }
 336 
 337             // System.out.println(e.getMessage());
 338 
 339         } catch (Error e) {
 340             // e.printStackTrace();
 341             String error = e.getMessage();
 342             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 343                 Assert.fail(e.getMessage());
 344             } else {
 345                 System.out.println("Default impl is used");
 346             }
 347 
 348             // System.out.println(e.getMessage());
 349 
 350         }
 351 
 352         long end = System.currentTimeMillis();
 353         double elapsedTime = ((end - start));
 354         System.out.println("Time elapsed: " + elapsedTime);
 355         System.clearProperty(DOM_FACTORY_ID);
 356     }
 357 
 358     @Test
 359     public void testXPath_DOM_withServiceMech() {
 360         final String XPATH_EXPRESSION = "/fooTest";
 361         System.out.println("Evaluate DOM Source;  Service mechnism is on by default;  It would try to use MyDOMFactoryImpl:");
 362         InputStream input = getClass().getResourceAsStream("Bug6941169.xml");
 363         InputSource source = new InputSource(input);
 364         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 365         long start = System.currentTimeMillis();
 366         try {
 367             XPathFactory xPathFactory = XPathFactory.newInstance();
 368 
 369             XPath xPath = xPathFactory.newXPath();
 370 
 371             String xPathResult = xPath.evaluate(XPATH_EXPRESSION, source);
 372             Assert.fail("User impl MyDOMFactoryImpl should be used.");
 373 
 374         } catch (Exception e) {
 375             // e.printStackTrace();
 376             String error = e.getMessage();
 377             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 378                 System.out.println("Tried to locate MyDOMFactoryImpl");
 379             } else {
 380                 Assert.fail(e.getMessage());
 381 
 382             }
 383 
 384             // System.out.println(e.getMessage());
 385 
 386         } catch (Error e) {
 387             // e.printStackTrace();
 388             String error = e.getMessage();
 389             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 390                 System.out.println("Tried to locate MyDOMFactoryImpl");
 391             } else {
 392                 Assert.fail(e.getMessage());
 393 
 394             }
 395 
 396             // System.out.println(e.getMessage());
 397 
 398         }
 399 
 400         long end = System.currentTimeMillis();
 401         double elapsedTime = ((end - start));
 402         System.out.println("Time elapsed: " + elapsedTime);
 403         System.clearProperty(DOM_FACTORY_ID);
 404     }
 405 
 406     @Test
 407     public void testXPath_DOM_withSM() {
 408         final String XPATH_EXPRESSION = "/fooTest";
 409         System.out.println("Evaluate DOM Source;  Security Manager is set:");
 410         Permissions granted = new java.security.Permissions();
 411         granted.add(new AllPermission());
 412         System.setSecurityManager(new MySM(granted));
 413         InputStream input = getClass().getResourceAsStream("Bug6941169.xml");
 414         InputSource source = new InputSource(input);
 415         System.setProperty(DOM_FACTORY_ID, "MyDOMFactoryImpl");
 416         long start = System.currentTimeMillis();
 417         try {
 418             XPathFactory xPathFactory = XPathFactory.newInstance("http://java.sun.com/jaxp/xpath/dom",
 419                     "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", null);
 420 
 421             XPath xPath = xPathFactory.newXPath();
 422 
 423             String xPathResult = xPath.evaluate(XPATH_EXPRESSION, source);
 424             System.out.println("Use default impl");
 425         } catch (Exception e) {
 426             // e.printStackTrace();
 427             String error = e.getMessage();
 428             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 429                 Assert.fail(e.getMessage());
 430             } else {
 431                 System.out.println("Default impl should be used");
 432             }
 433 
 434             // System.out.println(e.getMessage());
 435 
 436         } catch (Error e) {
 437             // e.printStackTrace();
 438             String error = e.getMessage();
 439             if (error.indexOf("MyDOMFactoryImpl not found") > 0) {
 440                 Assert.fail(e.getMessage());
 441             } else {
 442                 System.out.println("Default impl should be used");
 443             }
 444 
 445             // System.out.println(e.getMessage());
 446 
 447         } finally {
 448             System.clearProperty(DOM_FACTORY_ID);
 449             System.setSecurityManager(null);
 450         }
 451         long end = System.currentTimeMillis();
 452         double elapsedTime = ((end - start));
 453         System.out.println("Time elapsed: " + elapsedTime);
 454         System.clearProperty(DOM_FACTORY_ID);
 455     }
 456 
 457     @Test
 458     public void testSM() {
 459         SecurityManager sm = System.getSecurityManager();
 460         if (System.getSecurityManager() != null) {
 461             System.out.println("Security manager not cleared: " + sm.toString());
 462         } else {
 463             System.out.println("Security manager cleared: ");
 464         }
 465     }
 466 
 467     private static Document getDocument(InputStream in) {
 468 
 469         Document document = null;
 470 
 471         try {
 472             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 473             dbf.setNamespaceAware(true);
 474             DocumentBuilder db = dbf.newDocumentBuilder();
 475             document = db.parse(in);
 476         } catch (Exception e) {
 477             e.printStackTrace();
 478             Assert.fail(e.toString());
 479         }
 480 
 481         return document;
 482     }
 483 
 484     class MySM extends SecurityManager {
 485         Permissions granted;
 486 
 487         public MySM(Permissions perms) {
 488             granted = perms;
 489         }
 490 
 491         @Override
 492         public void checkPermission(Permission perm) {
 493             if (granted.implies(perm)) {
 494                 return;
 495             }
 496             super.checkPermission(perm);
 497         }
 498 
 499     }
 500 
 501 }