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.DTMAxisTraverser;
  25 import java.io.IOException;
  26 import jaxp.library.JAXPBaseTest;
  27 import static org.apache.qetest.dtm.QeDtmConst.generateDTM;
  28 import static org.apache.qetest.dtm.QeDtmConst.getNodeName;
  29 import static org.testng.Assert.assertEquals;
  30 import org.testng.annotations.DataProvider;
  31 import org.testng.annotations.Test;
  32 
  33 /**
  34  *
  35  * Test for Axis Traverser walking. 
  36  */
  37 public class TestDTMTrav extends JAXPBaseTest {
  38     /**
  39      * DTM instance.
  40      */
  41     private final DTM dtm;
  42 
  43     /*
  44      * Intiate by creating DTM instance and generate initial context.
  45      * 
  46      */
  47     public TestDTMTrav() {
  48         dtm = generateDTM();
  49     }
  50     
  51     /**
  52      * A provider that provides validation parameters and expected lines.
  53      * 
  54      * @return an two dimensional array that provide axis type and expected 
  55      * lines.
  56      */
  57     @DataProvider
  58     public Object[][] travProvider(){
  59         final Object[][] chkChild = new Object[][] {
  60             { 65542, "COMMENT", "#comment", 3, " Default test document " },
  61             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\"" },
  62             { 65544, "ELEMENT", "A", 3, null },
  63             { 65554, "ELEMENT", "Aa", 3, null },
  64             { 65555, "ELEMENT", "Ab", 3, null },
  65             { 65556, "ELEMENT", "Ac", 3, null },
  66             { 65558, "ELEMENT", "Ad", 3, null }
  67         };
  68 
  69         final Object[][] chkParent = new Object[][]{
  70             {65537, "ELEMENT", "Document", 2, null}
  71         };
  72 
  73         Object[][] chkSelf = new Object[][]{
  74             {65558, "ELEMENT", "Ad", 3, null}
  75         };
  76 
  77         final Object[][] chkNamespace = new Object[][]{
  78             {65538, "NAMESPACE", "xmlns:xml", 3, "http://www.w3.org/XML/1998/namespace"},
  79             {65539, "NAMESPACE", "xmlns:d", 3, "www.d.com"},
  80             {65559, "NAMESPACE", "xmlns:Ad", 4, "www.Ad.com"},
  81             {65560, "NAMESPACE", "xmlns:y", 4, "www.y.com"},
  82             {65561, "NAMESPACE", "xmlns:z", 4, "www.z.com"}
  83         };
  84 
  85         final Object[][] chkNamespaceDecls = new Object[][]{
  86             {65559, "NAMESPACE", "xmlns:Ad", 4, "www.Ad.com"},
  87             {65560, "NAMESPACE", "xmlns:y", 4, "www.y.com"},
  88             {65561, "NAMESPACE", "xmlns:z", 4, "www.z.com"}
  89         };
  90 
  91         final Object[][] chkPreceding = new Object[][]{
  92             { 65557, "ELEMENT", "Ac1", 4, null},
  93             { 65556, "ELEMENT", "Ac", 3, null},
  94             { 65555, "ELEMENT", "Ab", 3, null},
  95             { 65554, "ELEMENT", "Aa", 3, null},
  96             { 65550, "ELEMENT", "F", 8, null},
  97             { 65549, "ELEMENT", "E", 7, null},
  98             { 65548, "ELEMENT", "D", 6, null},
  99             { 65547, "ELEMENT", "C", 5, null},
 100             { 65546, "ELEMENT", "B", 4, null},
 101             { 65545, "COMMENT", "#comment", 4, " A Subtree "},
 102             { 65544, "ELEMENT", "A", 3, null},
 103             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\""},
 104             { 65542, "COMMENT", "#comment", 3, " Default test document "},
 105         };
 106 
 107         final Object[][] chkPrecedingsibling = new Object[][]{
 108             { 65556, "ELEMENT", "Ac", 3, null},
 109             { 65555, "ELEMENT", "Ab", 3,  null},
 110             { 65554, "ELEMENT", "Aa", 3, null},
 111             { 65544, "ELEMENT", "A", 3, null},
 112             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\""},
 113             { 65542, "COMMENT", "#comment", 3, " Default test document "}
 114         };
 115 
 116         final Object[][] chkFollowing = new Object[][]{
 117             { 65554, "ELEMENT", "Aa", 3, null},
 118             { 65555, "ELEMENT", "Ab", 3,  null},
 119             { 65556, "ELEMENT", "Ac", 3, null},
 120             { 65557, "ELEMENT", "Ac1", 4, null},
 121             { 65558, "ELEMENT", "Ad", 3, null},
 122             { 65562, "ELEMENT", "Ad1", 4, null}
 123         };
 124         
 125         final Object[][] checkFollowingSibling = new Object[][]{
 126             { 65554, "ELEMENT", "Aa", 3, null},
 127             { 65555, "ELEMENT", "Ab", 3, null},
 128             { 65556, "ELEMENT", "Ac", 3, null},
 129             { 65558, "ELEMENT", "Ad", 3, null},
 130         };
 131         
 132         final Object[][] checkDescendant = new Object[][]{
 133             {  65545, "COMMENT", "#comment", 4, " A Subtree "},
 134             {  65546, "ELEMENT", "B", 4, null},
 135             {  65547, "ELEMENT", "C", 5, null},
 136             {  65548, "ELEMENT", "D", 6, null},
 137             {  65549, "ELEMENT", "E", 7, null},
 138             {  65550, "ELEMENT", "F", 8, null}
 139         };
 140         
 141         final Object[][] checkDescendantSelf = new Object[][]{
 142             {   65544, "ELEMENT", "A", 3, null},
 143             {   65545, "COMMENT", "#comment", 4, " A Subtree "},
 144             {   65546, "ELEMENT", "B", 4, null},
 145             {   65547, "ELEMENT", "C", 5, null},
 146             {   65548, "ELEMENT", "D", 6, null},
 147             {   65549, "ELEMENT", "E", 7, null},
 148             {   65550, "ELEMENT", "F", 8, null}
 149         };
 150         
 151         final Object[][] checkAncestor = new Object[][]{
 152             { 65549, "ELEMENT", "E", 7, null},
 153             { 65548, "ELEMENT", "D", 6, null},
 154             { 65547, "ELEMENT", "C", 5, null},
 155             { 65546, "ELEMENT", "B", 4, null},
 156             { 65544, "ELEMENT", "A", 3, null},
 157             { 65537, "ELEMENT", "Document", 2, null},
 158             { 65536, "DOCUMENT", "#document", 1, null},
 159         };
 160  
 161         final Object[][] checkAncestorSelf = new Object[][]{
 162             { 65550, "ELEMENT", "F", 8, null},
 163             { 65549, "ELEMENT", "E", 7, null},
 164             { 65548, "ELEMENT", "D", 6, null},
 165             { 65547, "ELEMENT", "C", 5, null},
 166             { 65546, "ELEMENT", "B", 4, null},
 167             { 65544, "ELEMENT", "A", 3, null},
 168             { 65537, "ELEMENT", "Document", 2, null},
 169             { 65536, "DOCUMENT", "#document", 1, null}
 170         }; 
 171         
 172         final Object[][] checkAllFromNode = new Object[][]{
 173             { 65550, "ELEMENT", "F", 8, null},
 174             { 65551, "NAMESPACE", "xmlns:f", 9, "www.f.com"},
 175             { 65552, "ATTRIBUTE", "a1", 9, "down"},
 176             { 65553, "ATTRIBUTE", "a2", 9, "up"}
 177         }; 
 178         
 179         final Object[][] checkAttribute = new Object[][]{
 180             { 65540, "ATTRIBUTE", "a1", 3, "hello"},
 181             { 65541, "ATTRIBUTE", "a2", 3, "goodbye"}
 182         };
 183         
 184         final Object[][] checkAll = new Object[][]{
 185             { 65536, "DOCUMENT", "#document", 1, null},
 186             { 65537, "ELEMENT", "Document", 2, null},
 187             { 65538, "NAMESPACE", "xmlns:xml", 3, "http://www.w3.org/XML/1998/namespace"},
 188             { 65539, "NAMESPACE", "xmlns:d", 3, "www.d.com"},
 189             { 65540, "ATTRIBUTE", "a1", 3, "hello"},
 190             { 65541, "ATTRIBUTE", "a2", 3, "goodbye"},
 191             { 65542, "COMMENT", "#comment", 3, " Default test document "},
 192             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\""},
 193             { 65544, "ELEMENT", "A", 3, null},
 194             { 65545, "COMMENT", "#comment", 4, " A Subtree "},
 195             { 65546, "ELEMENT", "B", 4, null},
 196             { 65547, "ELEMENT", "C", 5, null},
 197             { 65548, "ELEMENT", "D", 6, null},
 198             { 65549, "ELEMENT", "E", 7, null},
 199             { 65550, "ELEMENT", "F", 8, null},
 200             { 65551, "NAMESPACE", "xmlns:f", 9, "www.f.com"},
 201             { 65552, "ATTRIBUTE", "a1", 9, "down"},
 202             { 65553, "ATTRIBUTE", "a2", 9, "up"},
 203             { 65554, "ELEMENT", "Aa", 3, null},
 204             { 65555, "ELEMENT", "Ab", 3, null},
 205             { 65556, "ELEMENT", "Ac", 3, null},
 206             { 65557, "ELEMENT", "Ac1", 4, null},
 207             { 65558, "ELEMENT", "Ad", 3, null},
 208             { 65559, "NAMESPACE", "xmlns:Ad", 4, "www.Ad.com"},
 209             { 65560, "NAMESPACE", "xmlns:y", 4, "www.y.com"},
 210             { 65561, "NAMESPACE", "xmlns:z", 4, "www.z.com"},
 211             { 65562, "ELEMENT", "Ad1", 4, null}
 212         };
 213 
 214         final Object[][] checkDescentsFromRoot = new Object[][]{
 215             { 65537, "ELEMENT", "Document", 2, null},
 216             { 65542, "COMMENT", "#comment", 3, " Default test document "},
 217             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\""},
 218             { 65544, "ELEMENT", "A", 3, null},
 219             { 65545, "COMMENT", "#comment", 4, " A Subtree "},
 220             { 65546, "ELEMENT", "B", 4, null},
 221             { 65547, "ELEMENT", "C", 5, null},
 222             { 65548, "ELEMENT", "D", 6, null},
 223             { 65549, "ELEMENT", "E", 7, null},
 224             { 65550, "ELEMENT", "F", 8, null},
 225             { 65554, "ELEMENT", "Aa", 3, null},
 226             { 65555, "ELEMENT", "Ab", 3, null},
 227             { 65556, "ELEMENT", "Ac", 3, null},
 228             { 65557, "ELEMENT", "Ac1", 4, null},
 229             { 65558, "ELEMENT", "Ad", 3, null},
 230             { 65562, "ELEMENT", "Ad1", 4, null}
 231         };
 232         
 233         final Object[][] checkDescentsOrSelfFromRoot = new Object[][]{
 234             { 65536, "DOCUMENT", "#document", 1, null},
 235             { 65537, "ELEMENT", "Document", 2, null},
 236             { 65542, "COMMENT", "#comment", 3, " Default test document "},
 237             { 65543, "PROCESSING_INSTRUCTION", "api", 3, "a1=\"yes\" a2=\"no\""},
 238             { 65544, "ELEMENT", "A", 3, null},
 239             { 65545, "COMMENT", "#comment", 4, " A Subtree "},
 240             { 65546, "ELEMENT", "B", 4, null},
 241             { 65547, "ELEMENT", "C", 5, null},
 242             { 65548, "ELEMENT", "D", 6, null},
 243             { 65549, "ELEMENT", "E", 7, null},
 244             { 65550, "ELEMENT", "F", 8, null},
 245             { 65554, "ELEMENT", "Aa", 3, null},
 246             { 65555, "ELEMENT", "Ab", 3, null},
 247             { 65556, "ELEMENT", "Ac", 3, null},
 248             { 65557, "ELEMENT", "Ac1", 4, null},
 249             { 65558, "ELEMENT", "Ad", 3, null},
 250             { 65562, "ELEMENT", "Ad1", 4, null}
 251         };
 252         
 253         final Object[][] checkANodeAll = new Object[][]{
 254             { 65544, "ELEMENT", "A", 3, null},
 255             { 65545, "COMMENT", "#comment", 4, " A Subtree "},
 256             { 65546, "ELEMENT", "B", 4, null},
 257             { 65547, "ELEMENT", "C", 5, null},
 258             { 65548, "ELEMENT", "D", 6, null},
 259             { 65549, "ELEMENT", "E", 7, null},
 260             { 65550, "ELEMENT", "F", 8, null},
 261             { 65551, "NAMESPACE", "xmlns:f", 9, "www.f.com"},
 262             { 65552, "ATTRIBUTE", "a1", 9, "down"},
 263             { 65553, "ATTRIBUTE", "a2", 9, "up"}
 264         };
 265         
 266         final Object[][] checkCNodeAll = new Object[][]{
 267             { 65542, "COMMENT", "#comment", 3, " Default test document "}
 268         };
 269     
 270         return new Object[][]{
 271             {65537, Axis.CHILD, "Document", chkChild},
 272             {65558, Axis.PARENT, "Ad", chkParent},
 273             {65558, Axis.SELF, "Ad", chkSelf},
 274             {65558, Axis.NAMESPACE, "Ad", chkNamespace},
 275             {65558, Axis.NAMESPACEDECLS, "Ad", chkNamespaceDecls},
 276             {65558, Axis.PRECEDING, "Ad", chkPreceding},
 277             {65558, Axis.PRECEDINGSIBLING, "Ad", chkPrecedingsibling},
 278             {65558, Axis.FOLLOWING, "Ad", chkFollowing},
 279             {65558, Axis.FOLLOWINGSIBLING, "Ad", checkFollowingSibling},
 280             {65544, Axis.DESCENDANT, "A", checkDescendant},
 281             {65544, Axis.DESCENDANTORSELF, "A", checkDescendantSelf},
 282             {65550, Axis.ANCESTOR, "F", checkAncestor},
 283             {65550, Axis.ANCESTORORSELF, "F", checkAncestorSelf},
 284             {65550, Axis.ALLFROMNODE, "F", checkAllFromNode},
 285             {65537, Axis.ATTRIBUTE, "Document", checkAttribute},
 286             {65550, Axis.ALL, "F", checkAll},   
 287             {65550, Axis.DESCENDANTSFROMROOT, "F", checkDescentsFromRoot},
 288             {65550, Axis.DESCENDANTSORSELFFROMROOT, "F", checkDescentsOrSelfFromRoot},
 289             {65544, Axis.ALLFROMNODE, "A", checkANodeAll},
 290             {65542, Axis.ALLFROMNODE, "#comment", checkCNodeAll}
 291         };
 292     }
 293 
 294     /**
 295      * Walk all kind of AxisTraversers and checking API as expected..
 296      *
 297      * @param startNode node id to get AxisTraverser.
 298      * @param axisType Axis type.
 299      * @param expectedName expected node name.
 300      * @param expectedLines an two dimensional array that will be validate
 301      *        traversal of AxisTraverser
 302      * @throws IOException if any I/O operation error.
 303      */
 304     @Test(dataProvider = "travProvider")
 305     public void test(int startNode, int axisType, String expectedName, 
 306             Object[][] expectedLines) throws IOException {
 307         // This permission is special for the testing.
 308         setPermissions(
 309             new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.utils"),
 310             new RuntimePermission("accessClassInPackage.com.sun.org.apache.xpath.internal.objects"));
 311 
 312         // Get a Traverser by given axis type.
 313         assertEquals(dtm.getNodeName(startNode), expectedName);
 314         DTMAxisTraverser at = dtm.getAxisTraverser(axisType);
 315 
 316         int line = 0;
 317         // Traverse the axis and validate API output.
 318         for (int travNode = at.first(startNode); DTM.NULL != travNode;
 319                 travNode = at.next(startNode, travNode), line++) {
 320             assertEquals(travNode, expectedLines[line][0]);
 321             assertEquals(getNodeName(dtm, travNode), expectedLines[line][1]);
 322             assertEquals(dtm.getNodeName(travNode), expectedLines[line][2]);
 323             Integer expectedLevel = (Integer)expectedLines[line][3];
 324             assertEquals(dtm.getLevel(travNode), expectedLevel.shortValue());
 325             assertEquals(dtm.getNodeValue(travNode), expectedLines[line][4]);
 326         }
 327     }
 328 }