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