1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package org.apache.qetest.dtm; 21 22 import com.sun.org.apache.xml.internal.dtm.Axis; 23 import com.sun.org.apache.xml.internal.dtm.DTM; 24 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 25 import com.sun.org.apache.xml.internal.dtm.DTMManager; 26 import com.sun.org.apache.xml.internal.dtm.DTMWSFilter; 27 import com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault; 28 import com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl; 29 import java.io.IOException; 30 import java.io.PrintWriter; 31 import java.io.StringReader; 32 import javax.xml.transform.Source; 33 import javax.xml.transform.stream.StreamSource; 34 import jaxp.library.JAXPFileBaseTest; 35 import static jaxp.library.JAXPTestUtilities.compareWithGold; 36 import static jaxp.library.JAXPTestUtilities.getNextFile; 37 import static org.apache.qetest.dtm.QeDtmConst.GOLDEN_DIR; 38 import static org.apache.qetest.dtm.QeDtmConst.TYPENAME; 39 import static org.testng.Assert.assertTrue; 40 import org.testng.annotations.Test; 41 42 /** 43 * 44 * Loads an XML document from a file (or, if no filename is supplied, 45 * an internal string), then dumps its contents. Replaces the old 46 * version, which was specific to the ultra-compressed implementation. 47 */ 48 public class TestDTMIterator extends JAXPFileBaseTest { 49 /** 50 * Test DTMIterator on a well-formed XML string. Checking on expected output. 51 * @throws IOException if any error on File I/O operation. 52 */ 53 @Test 54 public void test() throws IOException { 55 setPermissions(new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.utils"), 56 new RuntimePermission("accessClassInPackage.com.sun.org.apache.xpath.internal.objects")); 57 String goldFile = GOLDEN_DIR + "TestDTMIterator.out"; 58 59 String defaultSource = "<?xml version=\"1.0\"?>\n" 60 + "<Document xmlns:d=\"www.d.com\" a1=\"hello\" a2=\"goodbye\">" 61 + "<!-- Default test document -->" 62 + "<?api a1=\"yes\" a2=\"no\"?>" 63 + "<A><!-- A Subtree --><B><C><D><E>" 64 + "<F xmlns:f=\"www.f.com\" a1=\"down\" a2=\"up\"/>" 65 + "</E></D></C></B></A>" 66 + "<Aa/><Ab/><Ac><Ac1/></Ac>" 67 + "<Ad xmlns:Ad=\"www.Ad.com\" xmlns:y=\"www.y.com\" xmlns:z=\"www.z.com\">" 68 + "<Ad1/></Ad>" 69 + "</Document>"; 70 71 try(StringReader sw = new StringReader(defaultSource)) { 72 Source source = new StreamSource(sw); 73 74 // Get a DTM manager, and ask it to load the DTM "uniquely", 75 // with no whitespace filtering, nonincremental, but _with_ 76 // indexing (a fairly common case, and avoids the special 77 // mode used for RTF DTMs). 78 // For testing with some of David Marston's files I do want to strip whitespace. 79 DTMManager manager = DTMManagerDefault.newInstance(new XMLStringFactoryImpl()); 80 DTM dtm = manager.getDTM(source, true, (e, d) -> DTMWSFilter.STRIP, false, true); 81 82 // Get various nodes to use as context nodes. 83 int dtmRoot = dtm.getDocument(); // #document 84 int DNode = dtm.getFirstChild(dtmRoot); // <Document> 85 int CNode = dtm.getFirstChild(DNode); // <Comment> 86 int PINode = dtm.getNextSibling(CNode); // <PI> 87 int ANode = dtm.getNextSibling(PINode); // <A> 88 int lastNode = 0; 89 90 // Get a Iterator for CHILD:: axis. 91 DTMAxisIterator iter = dtm.getAxisIterator(Axis.CHILD); 92 iter.setStartNode(DNode); 93 94 String outputFile = getNextFile(this.getClass()); 95 96 try(PrintWriter pw = new PrintWriter(outputFile)) { 97 // Iterate the axis and print out node info. 98 for (int itNode = iter.next(); DTM.NULL != itNode; 99 itNode = iter.next()) { 100 printNode(dtm, itNode, " ", pw); 101 lastNode = itNode; 102 } 103 104 // Get iterator for PARENT:: Axis 105 iter = dtm.getAxisIterator(Axis.PARENT); 106 iter.setStartNode(lastNode); 107 108 // Iterate the axis and print out node info. 109 for (int itNode = iter.next(); DTM.NULL != itNode; 110 itNode = iter.next()) { 111 printNode(dtm, itNode, " ", pw); 112 } 113 114 // Get iterator for SELF:: Axis 115 iter = dtm.getAxisIterator(Axis.SELF); 116 iter.setStartNode(lastNode); 117 118 // Iterate the axis and print out node info. 119 for (int itNode = iter.next(); DTM.NULL != itNode; 120 itNode = iter.next()) { 121 printNode(dtm, itNode, " ", pw); 122 } 123 124 // Get iterator for NAMESPACE:: Axis 125 iter = dtm.getAxisIterator(Axis.NAMESPACE); 126 iter.setStartNode(lastNode); 127 128 // Iterate the axis and print out node info. 129 for (int itNode = iter.next(); DTM.NULL != itNode; 130 itNode = iter.next()) { 131 printNode(dtm, itNode, " ", pw); 132 } 133 134 // Get iterator for PRECEDING:: Axis 135 iter = dtm.getAxisIterator(Axis.PRECEDING); 136 iter.setStartNode(lastNode); 137 138 // Iterate the axis and print out node info. 139 for (int itNode = iter.next(); DTM.NULL != itNode; 140 itNode = iter.next()) { 141 printNode(dtm, itNode, " ", pw); 142 } 143 144 // Get iterator for PRECEDINGSIBLING:: Axis 145 iter = dtm.getAxisIterator(Axis.PRECEDINGSIBLING); 146 iter.setStartNode(lastNode); 147 148 // Iterate the axis and print out node info. 149 for (int itNode = iter.next(); DTM.NULL != itNode; 150 itNode = iter.next()) { 151 printNode(dtm, itNode, " ", pw); 152 } 153 154 // Get iterator for FOLLOWING:: Axis 155 iter = dtm.getAxisIterator(Axis.FOLLOWING); 156 iter.setStartNode(ANode); 157 158 // Iterate the axis and print out node info. 159 for (int itNode = iter.next(); DTM.NULL != itNode; 160 itNode = iter.next()) { 161 printNode(dtm, itNode, " ", pw); 162 } 163 164 // Get iterator for FOLLOWINGSIBLING:: Axis 165 iter = dtm.getAxisIterator(Axis.FOLLOWINGSIBLING); 166 iter.setStartNode(ANode); 167 168 // Iterate the axis and print out node info. 169 for (int itNode = iter.next(); DTM.NULL != itNode; 170 itNode = iter.next()) { 171 printNode(dtm, itNode, " ", pw); 172 } 173 174 // Get a iterator for DESCENDANT:: axis. 175 iter = dtm.getAxisIterator(Axis.DESCENDANT); 176 iter.setStartNode(ANode); 177 178 // Iterate the axis and print out node info. 179 for (int itNode = iter.next(); DTM.NULL != itNode; 180 itNode = iter.next()) { 181 printNode(dtm, itNode, " ", pw); 182 lastNode = itNode; 183 } 184 185 // Get iterator for DESCENDANTORSELF:: Axis 186 iter = dtm.getAxisIterator(Axis.DESCENDANTORSELF); 187 iter.setStartNode(ANode); 188 189 // Iterate the axis and print out node info. 190 for (int itNode = iter.next(); DTM.NULL != itNode; 191 itNode = iter.next()) { 192 printNode(dtm, itNode, " ", pw); 193 lastNode = itNode; 194 } 195 196 // The output from Ancestor and Ancestor-or-self is the topic 197 // of Bugzilla 7886 198 // Get iterator for ANCESTOR:: Axis 199 iter = dtm.getAxisIterator(Axis.ANCESTOR); 200 iter.setStartNode(lastNode); 201 202 // Iterate the axis and print out node info. 203 for (int itNode = iter.next(); DTM.NULL != itNode; 204 itNode = iter.next()) { 205 printNode(dtm, itNode, " ", pw); 206 } 207 208 // Get iterator for ANCESTORORSELF:: Axis 209 iter = dtm.getAxisIterator(Axis.ANCESTORORSELF); 210 iter.setStartNode(lastNode); 211 212 // Iterate the axis and print out node info. 213 for (int itNode = iter.next(); DTM.NULL != itNode; 214 itNode = iter.next()) { 215 printNode(dtm, itNode, " ", pw); 216 } 217 } 218 assertTrue(compareWithGold(goldFile, outputFile)); 219 } 220 } 221 222 /** 223 * Print a node info by given node handle. 224 * @param dtm DTM instance. 225 * @param nodeHandle node handle. 226 * @param indent a format indention. 227 */ 228 private void printNode(DTM dtm, int nodeHandle, String indent, PrintWriter pw) { 229 // Briefly display this node 230 // Don't bother displaying namespaces or attrs; we do that at the 231 // next level up. 232 // %REVIEW% Add namespace info, type info, ... 233 234 // Formatting hack -- suppress quotes when value is null, to distinguish 235 // it from "null". 236 String value = dtm.getNodeValue(nodeHandle); 237 String vq = (value == null) ? "" : "\""; 238 239 // Skip outputing of text nodes. In most cases they clutter the output, 240 // besides I'm only interested in the elemental structure of the dtm. 241 if (!"TEXT".equals(TYPENAME[dtm.getNodeType(nodeHandle)])) { 242 pw.println(indent 243 + +nodeHandle + ": " 244 + TYPENAME[dtm.getNodeType(nodeHandle)] + " " 245 + dtm.getNodeName(nodeHandle) + " " 246 + " Level=" + dtm.getLevel(nodeHandle) + " " 247 + "\tValue=" + vq + value + vq 248 ); 249 } 250 } 251 }