1 /*
   2  * Copyright (c) 2003, 2015, 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 test.auctionportal;
  24 
  25 import static test.auctionportal.HiBidConstants.SP_ENTITY_EXPANSION_LIMIT;
  26 import static test.auctionportal.HiBidConstants.SP_MAX_OCCUR_LIMIT;
  27 import static test.auctionportal.HiBidConstants.JAXP_SCHEMA_LANGUAGE;
  28 import static test.auctionportal.HiBidConstants.JAXP_SCHEMA_SOURCE;
  29 import static org.testng.Assert.assertTrue;
  30 import java.io.File;
  31 import java.io.FileInputStream;
  32 import java.io.FileOutputStream;
  33 import java.io.FilePermission;
  34 import java.io.InputStream;
  35 import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
  36 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
  37 import javax.xml.parsers.DocumentBuilder;
  38 import javax.xml.parsers.DocumentBuilderFactory;
  39 import javax.xml.parsers.SAXParser;
  40 import javax.xml.parsers.SAXParserFactory;
  41 import javax.xml.transform.TransformerFactory;
  42 import javax.xml.transform.dom.DOMSource;
  43 import javax.xml.transform.stream.StreamResult;
  44 import jaxp.library.JAXPFileBaseTest;
  45 import static jaxp.library.JAXPTestUtilities.USER_DIR;
  46 import static jaxp.library.JAXPTestUtilities.compareDocumentWithGold;
  47 import static org.testng.Assert.assertFalse;
  48 import org.testng.annotations.Test;
  49 import org.w3c.dom.Document;
  50 import org.xml.sax.SAXParseException;
  51 import static test.auctionportal.HiBidConstants.GOLDEN_DIR;
  52 import static test.auctionportal.HiBidConstants.XML_DIR;
  53 
  54 /**
  55  * This is a test class for the Auction portal HiBid.com.
  56  */
  57 public class AuctionItemRepository extends JAXPFileBaseTest {
  58     /**
  59      * XML file for parsing.
  60      */
  61     private final static String ENTITY_XML = XML_DIR + "entity.xml";
  62 
  63     /**
  64      * Feature name.
  65      */
  66     private final static String FEATURE_NAME = "http://xml.org/sax/features/namespace-prefixes";
  67 
  68     /**
  69      * Setting the EntityExpansion Limit to 128000 and checks if the XML
  70      * document that has more than two levels of entity expansion is parsed or
  71      * not. Previous system property was changed to jdk.xml.entityExpansionLimit
  72      * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html.
  73      *
  74      * @throws Exception If any errors occur.
  75      */
  76     @Test
  77     public void testEntityExpansionSAXPos() throws Exception {
  78         SAXParserFactory factory = SAXParserFactory.newInstance();
  79         // Secure processing will limit XML processing to conform to
  80         // implementation limits.
  81         factory.setFeature(FEATURE_SECURE_PROCESSING, true);
  82         // Set entityExpansionLimit as 2 should expect fatalError
  83         setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(128000));
  84         SAXParser parser = factory.newSAXParser();
  85 
  86         MyErrorHandler fatalHandler = new MyErrorHandler();
  87         setPermissions(new FilePermission(ENTITY_XML, "read"));
  88         parser.parse(new File(ENTITY_XML), fatalHandler);
  89         assertFalse(fatalHandler.isAnyError());
  90     }
  91     /**
  92      * Setting the EntityExpansion Limit to 2 and checks if the XML
  93      * document that has more than two levels of entity expansion is parsed or
  94      * not. Previous system property was changed to jdk.xml.entityExpansionLimit
  95      * see http://docs.oracle.com/javase/tutorial/jaxp/limits/limits.html.
  96      *
  97      * @throws Exception If any errors occur.
  98      */
  99     @Test(expectedExceptions = SAXParseException.class)
 100     public void testEntityExpansionSAXNeg() throws Exception {
 101         SAXParserFactory factory = SAXParserFactory.newInstance();
 102         // Secure processing will limit XML processing to conform to
 103         // implementation limits.
 104         factory.setFeature(FEATURE_SECURE_PROCESSING, true);
 105         // Set entityExpansionLimit as 2 should expect SAXParseException.
 106         setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2));
 107 
 108         SAXParser parser = factory.newSAXParser();
 109         MyErrorHandler fatalHandler = new MyErrorHandler();
 110         setPermissions(new FilePermission(ENTITY_XML, "read"));
 111         parser.parse(new File(ENTITY_XML), fatalHandler);
 112     }
 113 
 114     /**
 115      * Testing set MaxOccursLimit to 10000 in the secure processing enabled for
 116      * SAXParserFactory.
 117      *
 118      * @throws Exception If any errors occur.
 119      */
 120     @Test
 121     public void testMaxOccurLimitPos() throws Exception {
 122         String schema_file = XML_DIR + "toys.xsd";
 123         String xml_file = XML_DIR + "toys.xml";
 124         SAXParserFactory factory = SAXParserFactory.newInstance();
 125         factory.setValidating(true);
 126         factory.setFeature(FEATURE_SECURE_PROCESSING, true);
 127         setSystemProperty(SP_MAX_OCCUR_LIMIT, String.valueOf(10000));
 128         SAXParser parser = factory.newSAXParser();
 129         parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA_NS_URI);
 130         setPermissions(new FilePermission(XML_DIR + "-", "read"));
 131         parser.setProperty(JAXP_SCHEMA_SOURCE, new File(schema_file));
 132         try (InputStream is = new FileInputStream(xml_file)) {
 133             MyErrorHandler eh = new MyErrorHandler();
 134             parser.parse(is, eh);
 135             assertFalse(eh.isAnyError());
 136         }
 137     }
 138 
 139     /**
 140      * Use a DocumentBuilder to create a DOM object and see if Secure Processing
 141      * feature affects the entity expansion.
 142      *
 143      * @throws Exception If any errors occur.
 144      */
 145     @Test
 146     public void testEntityExpansionDOMPos() throws Exception  {
 147         DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
 148         dfactory.setFeature(FEATURE_SECURE_PROCESSING, true);
 149         setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(10000));
 150         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
 151         MyErrorHandler eh = new MyErrorHandler();
 152         dBuilder.setErrorHandler(eh);
 153         try {
 154             setPermissions(new FilePermission(ENTITY_XML, "read"));
 155             dBuilder.parse(ENTITY_XML);
 156             assertFalse(eh.isAnyError());
 157         } finally {
 158             setPermissions();
 159         }
 160     }
 161 
 162     /**
 163      * Use a DocumentBuilder to create a DOM object and see how does the Secure
 164      * Processing feature and entityExpansionLimit value affects output.
 165      * Negative test that when entityExpansionLimit is too small.
 166      *
 167      * @throws Exception If any errors occur.
 168      */
 169     @Test(expectedExceptions = SAXParseException.class)
 170     public void testEntityExpansionDOMNeg() throws Exception {
 171         DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
 172         dfactory.setFeature(FEATURE_SECURE_PROCESSING, true);
 173         setSystemProperty(SP_ENTITY_EXPANSION_LIMIT, String.valueOf(2));
 174         DocumentBuilder dBuilder = dfactory.newDocumentBuilder();
 175         MyErrorHandler eh = new MyErrorHandler();
 176         dBuilder.setErrorHandler(eh);
 177         setPermissions(new FilePermission(ENTITY_XML, "read"));
 178         dBuilder.parse(ENTITY_XML);
 179     }
 180 
 181     /**
 182      * Test xi:include with a SAXParserFactory.
 183      *
 184      * @throws Exception If any errors occur.
 185      */
 186     @Test(groups = {"readWriteLocalFiles"})
 187     public void testXIncludeSAXPos() throws Exception {
 188         String resultFile = USER_DIR + "doc_xinclude.out";
 189         String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml";
 190         String xmlFile = XML_DIR + "doc_xinclude.xml";
 191 
 192         try(FileOutputStream fos = new FileOutputStream(resultFile)) {
 193             XInclHandler xh = new XInclHandler(fos, null);
 194             SAXParserFactory spf = SAXParserFactory.newInstance();
 195             spf.setNamespaceAware(true);
 196             spf.setXIncludeAware(true);
 197             spf.setFeature(FEATURE_NAME, true);
 198             spf.newSAXParser().parse(new File(xmlFile), xh);
 199         }
 200         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 201     }
 202 
 203     /**
 204      * Test the simple case of including a document using xi:include using a
 205      * DocumentBuilder.
 206      *
 207      * @throws Exception If any errors occur.
 208      */
 209     @Test(groups = {"readWriteLocalFiles"})
 210     public void testXIncludeDOMPos() throws Exception {
 211         String resultFile = USER_DIR + "doc_xincludeDOM.out";
 212         String goldFile = GOLDEN_DIR + "doc_xincludeGold.xml";
 213         String xmlFile = XML_DIR + "doc_xinclude.xml";
 214         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 215             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 216             dbf.setXIncludeAware(true);
 217             dbf.setNamespaceAware(true);
 218             Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile));
 219             doc.setXmlStandalone(true);
 220             TransformerFactory.newInstance().newTransformer().
 221                     transform(new DOMSource(doc), new StreamResult(fos));
 222         }
 223         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 224     }
 225 
 226     /**
 227      * Test the simple case of including a document using xi:include within a
 228      * xi:fallback using a DocumentBuilder.
 229      *
 230      * @throws Exception If any errors occur.
 231      */
 232     @Test(groups = {"readWriteLocalFiles"})
 233     public void testXIncludeFallbackDOMPos() throws Exception {
 234         String resultFile = USER_DIR + "doc_fallbackDOM.out";
 235         String goldFile = GOLDEN_DIR + "doc_fallbackGold.xml";
 236         String xmlFile = XML_DIR + "doc_fallback.xml";
 237         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 238             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 239             dbf.setXIncludeAware(true);
 240             dbf.setNamespaceAware(true);
 241 
 242             Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile));
 243             doc.setXmlStandalone(true);
 244             TransformerFactory.newInstance().newTransformer()
 245                     .transform(new DOMSource(doc), new StreamResult(fos));
 246         }
 247         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 248     }
 249 
 250     /**
 251      * Test for xi:fallback where the fall back text is parsed as text. This
 252      * test uses a nested xi:include for the fallback test.
 253      *
 254      * @throws Exception If any errors occur.
 255      */
 256     @Test(groups = {"readWriteLocalFiles"})
 257     public void testXIncludeFallbackTextPos() throws Exception {
 258         String resultFile = USER_DIR + "doc_fallback_text.out";
 259         String goldFile = GOLDEN_DIR + "doc_fallback_textGold.xml";
 260         String xmlFile = XML_DIR + "doc_fallback_text.xml";
 261         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 262             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 263             dbf.setXIncludeAware(true);
 264             dbf.setNamespaceAware(true);
 265 
 266             Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile));
 267             doc.setXmlStandalone(true);
 268             TransformerFactory.newInstance().newTransformer()
 269                     .transform(new DOMSource(doc), new StreamResult(fos));
 270         }
 271         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 272     }
 273 
 274     /**
 275      * Test the XPointer element() framework with XInclude.
 276      *
 277      * @throws Exception If any errors occur.
 278      */
 279     @Test(groups = {"readWriteLocalFiles"})
 280     public void testXpointerElementPos() throws Exception {
 281         String resultFile = USER_DIR + "doc_xpointer_element.out";
 282         String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml";
 283         String xmlFile = XML_DIR + "doc_xpointer_element.xml";
 284         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 285             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 286             dbf.setXIncludeAware(true);
 287             dbf.setNamespaceAware(true);
 288 
 289             DocumentBuilder db = dbf.newDocumentBuilder();
 290 
 291             TransformerFactory.newInstance().newTransformer()
 292                     .transform(new DOMSource(db.parse(new File(xmlFile))),
 293                             new StreamResult(fos));
 294         }
 295         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 296     }
 297 
 298     /**
 299      * Test the XPointer framework with a SAX object.
 300      *
 301      * @throws Exception If any errors occur.
 302      */
 303     @Test(groups = {"readWriteLocalFiles"})
 304     public void testXPointerPos() throws Exception {
 305         String resultFile = USER_DIR + "doc_xpointer.out";
 306         String goldFile = GOLDEN_DIR + "doc_xpointerGold.xml";
 307         String xmlFile = XML_DIR + "doc_xpointer.xml";
 308 
 309         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 310             SAXParserFactory spf = SAXParserFactory.newInstance();
 311             spf.setNamespaceAware(true);
 312             spf.setXIncludeAware(true);
 313             spf.setFeature(FEATURE_NAME, true);
 314             // parse the file
 315             spf.newSAXParser().parse(new File(xmlFile), new XInclHandler(fos, null));
 316         }
 317         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 318     }
 319 
 320     /**
 321      * Test if xi:include may reference the doc containing the include if the
 322      * parse type is text.
 323      *
 324      * @throws Exception If any errors occur.
 325      */
 326     @Test(groups = {"readWriteLocalFiles"})
 327     public void testXIncludeLoopPos() throws Exception {
 328         String resultFile = USER_DIR + "doc_xinc_loops.out";
 329         String goldFile = GOLDEN_DIR + "doc_xinc_loopGold.xml";
 330         String xmlFile = XML_DIR + "doc_xinc_loops.xml";
 331 
 332         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 333             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 334             dbf.setXIncludeAware(true);
 335             dbf.setNamespaceAware(true);
 336             DocumentBuilder db = dbf.newDocumentBuilder();
 337             Document doc = db.parse(new File(xmlFile));
 338             doc.normalizeDocument();
 339             doc.setXmlStandalone(true);
 340 
 341             TransformerFactory.newInstance().newTransformer()
 342                     .transform(new DOMSource(doc), new StreamResult(fos));
 343         }
 344         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 345     }
 346 
 347     /**
 348      * Test if two non nested xi:include elements can include the same document
 349      * with an xi:include statement.
 350      *
 351      * @throws Exception If any errors occur.
 352      */
 353     @Test(groups = {"readWriteLocalFiles"})
 354     public void testXIncludeNestedPos() throws Exception {
 355         String resultFile = USER_DIR + "schedule.out";
 356         String goldFile = GOLDEN_DIR + "scheduleGold.xml";
 357         String xmlFile = XML_DIR + "schedule.xml";
 358 
 359         try (FileOutputStream fos = new FileOutputStream(resultFile)) {
 360             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 361             dbf.setXIncludeAware(true);
 362             dbf.setNamespaceAware(true);
 363 
 364             Document doc = dbf.newDocumentBuilder().parse(new File(xmlFile));
 365             doc.setXmlStandalone(true);
 366             TransformerFactory.newInstance().newTransformer()
 367                     .transform(new DOMSource(doc), new StreamResult(fos));
 368         }
 369         assertTrue(compareDocumentWithGold(goldFile, resultFile));
 370     }
 371 }