1 /* 2 * Copyright (c) 2002, 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.astro; 24 25 import static jaxp.library.JAXPTestUtilities.USER_DIR; 26 import static jaxp.library.JAXPTestUtilities.filenameToURL; 27 import static org.w3c.dom.ls.DOMImplementationLS.MODE_SYNCHRONOUS; 28 import static org.w3c.dom.traversal.NodeFilter.SHOW_ELEMENT; 29 30 import java.io.ByteArrayInputStream; 31 import java.io.FileReader; 32 import java.io.FileWriter; 33 import java.io.InputStreamReader; 34 import java.io.Reader; 35 import java.nio.file.Files; 36 import java.nio.file.Paths; 37 38 import javax.xml.parsers.DocumentBuilder; 39 import javax.xml.parsers.DocumentBuilderFactory; 40 41 import org.w3c.dom.DOMConfiguration; 42 import org.w3c.dom.Document; 43 import org.w3c.dom.Element; 44 import org.w3c.dom.Node; 45 import org.w3c.dom.ls.DOMImplementationLS; 46 import org.w3c.dom.ls.LSInput; 47 import org.w3c.dom.ls.LSParser; 48 import org.w3c.dom.ls.LSParserFilter; 49 import org.w3c.dom.ls.LSSerializer; 50 import org.w3c.dom.ls.LSSerializerFilter; 51 import org.xml.sax.InputSource; 52 53 /* 54 * A specialized implementation of an Input Source factory that utilizes 55 * DOM Level 3 implementations to build a Document (DOM) from the 56 * astro input file (XML) and then will serialize the DOM. The serialized DOM 57 * of the astro input file is then used to create the sax InputSource 58 * and set it's system id. It is then returned to the caller. 59 * 60 */ 61 public class DOML3InputSourceFactoryImpl implements InputSourceFactory { 62 public InputSource newInputSource(String filename) throws Exception { 63 // Create DOMImplementationLS, and DOM L3 LSParser 64 DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); 65 DocumentBuilder bldr = fact.newDocumentBuilder(); 66 DOMImplementationLS impl = (DOMImplementationLS) bldr.getDOMImplementation(); 67 LSParser domparser = impl.createLSParser(MODE_SYNCHRONOUS, null); 68 domparser.setFilter(new MyDOMBuilderFilter()); 69 70 // Parse the xml document to create the DOM Document using 71 // the DOM L3 LSParser and a LSInput (formerly LSInputSource) 72 Document doc = null; 73 LSInput src = impl.createLSInput(); 74 // register the input file with the input source... 75 String systemId = filenameToURL(filename); 76 src.setSystemId(systemId); 77 try (Reader reader = new FileReader(filename)) { 78 src.setCharacterStream(reader); 79 src.setEncoding("UTF-8"); 80 doc = domparser.parse(src); 81 } 82 83 // Use DOM L3 LSSerializer (previously called a DOMWriter) 84 // to serialize the xml doc DOM to a file stream. 85 String tmpCatalog = Files.createTempFile(Paths.get(USER_DIR + "/astro"), "catalog.xml", null).toString(); 86 87 LSSerializer domserializer = impl.createLSSerializer(); 88 domserializer.setFilter(new MyDOMWriterFilter()); 89 domserializer.getNewLine(); 90 DOMConfiguration config = domserializer.getDomConfig(); 91 config.setParameter("xml-declaration", Boolean.TRUE); 92 String result = domserializer.writeToString(doc); 93 try (FileWriter os = new FileWriter(tmpCatalog, false)) { 94 os.write(result); 95 os.flush(); 96 } 97 98 // Return the Input Source created from the Serialized DOM L3 Document. 99 InputSource catsrc = new InputSource(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(tmpCatalog))))); 100 catsrc.setSystemId(systemId); 101 return catsrc; 102 } 103 104 /* 105 * Implementation of a DOM L3 DOM Builder Filter. The filter is capable of 106 * examining nodes as they are available during the parse. This 107 * implementation both rejects (filters) and modifies particular nodes 108 * during the parse of the document. As such, the document in memory will 109 * become a subset of the document on the stream in accordance with the DOM 110 * Level 3 Load and Save Specification, v1.0, sect. 1.3 Load Interfaces. 111 */ 112 private static class MyDOMBuilderFilter implements LSParserFilter { 113 114 /* 115 * Filter the DOM. Define element(s) and their children that should be 116 * efficiently skipped thereby filtering them out of the stream. 117 */ 118 @Override 119 public short startElement(Element e) { 120 return "_test01".equals(e.getTagName()) ? FILTER_REJECT : FILTER_ACCEPT; 121 } 122 123 /* 124 * Modify the DOM 'in situ'. Find a particular Node and change the Node 125 * value of its child, allow other nodes to pass through unchanged. 126 */ 127 @Override 128 public short acceptNode(Node n) { 129 String localname = n.getLocalName(); 130 if (localname.equals("_test-04")) { 131 Node child = n.getFirstChild(); 132 String text = child.getNodeValue(); 133 if (text.equals("T%e!s#t$")) { 134 child.setNodeValue("T%E!S#T$"); 135 } 136 } 137 return FILTER_ACCEPT; 138 } 139 140 /* 141 * Tells the DOMBuilder what types of nodes to show to the filter. 142 */ 143 @Override 144 public int getWhatToShow() { 145 return SHOW_ELEMENT; 146 } 147 } 148 149 /* 150 * Implementation of a DOM Serializer Filter (previously called a DOM Writer 151 * Filter) which is a specialization of the NodeFilter interface. 152 */ 153 private static class MyDOMWriterFilter implements LSSerializerFilter { 154 public MyDOMWriterFilter() { 155 } 156 157 /* 158 * Must implement method from NodeFilter interface 159 */ 160 @Override 161 public short acceptNode(Node node) { 162 return FILTER_ACCEPT; 163 } 164 165 /* 166 * Tells the DOMBuilder what types of nodes to show to the filter. 167 */ 168 @Override 169 public int getWhatToShow() { 170 return SHOW_ELEMENT; 171 } 172 } 173 }