1 /*
   2  * Copyright (c) 2015, 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.DTM;
  23 import java.io.FilePermission;
  24 import java.io.IOException;
  25 import java.util.ArrayList;
  26 import java.util.List;
  27 import jaxp.library.JAXPBaseTest;
  28 import static jaxp.library.JAXPTestUtilities.compareLinesWithGold;
  29 import static org.apache.qetest.dtm.QeDtmConst.GOLDEN_DIR;
  30 import static org.apache.qetest.dtm.QeDtmConst.TYPENAME;
  31 import static org.apache.qetest.dtm.QeDtmConst.generateDTM;
  32 import org.testng.annotations.Test;
  33 
  34 /**
  35  * Loads an XML document from a file (or, if no filename is supplied,
  36  * an internal string), then dumps its contents. Replaces the old
  37  * version, which was specific to the ultra-compressed implementation.
  38  * (Which, by the way, we probably ought to revisit as part of our ongoing
  39  * speed/size performance evaluation.)
  40  */
  41 public class TestDTM extends JAXPBaseTest { 
  42     /**
  43      * Create AxisIterator and walk CHILD axis. Dump every walked node and 
  44      * compare with expected golden file.
  45      * 
  46      * @throws IOException if any I/O operation error.
  47      */
  48     @Test
  49     public void test() throws IOException {
  50         setPermissions(new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.utils"),
  51                 new RuntimePermission("accessClassInPackage.com.sun.org.apache.xpath.internal.objects"));
  52         String goldFile = GOLDEN_DIR + "DTM_testcase1.out";
  53         
  54         // Create dtm and generate initial context
  55         DTM dtm = generateDTM();
  56 
  57             // DTM -- which will always be true for a node obtained this way, but
  58         // won't be true for "shared" DTMs used to hold XSLT variables
  59         int rootNode = dtm.getDocument();
  60         List<String> lines = new ArrayList<>();
  61         lines.add("DOCUMENT PROPERTIES:");
  62         lines.add("DocURI=\"" + dtm.getDocumentBaseURI() + "\" \"SystemID=\""
  63                 + dtm.getDocumentSystemIdentifier(rootNode) + "\"");
  64         lines.add("StandAlone=\"" + dtm.getDocumentStandalone(rootNode)
  65                 + "\" DocVersion=\"" + dtm.getDocumentVersion(rootNode) + "\"");
  66         lines.add("");
  67         lines.add("DOCUMENT DATA:");
  68             // Simple test: Recursively dump the DTM's content.
  69         // We'll want to replace this with more serious examples
  70         lines.add("DOCUMENT DATA:");
  71 
  72         recursiveDumpNode(dtm, rootNode, lines);
  73         setPermissions(new FilePermission(goldFile, "read"));
  74         compareLinesWithGold(goldFile, lines);
  75     }
  76     
  77     /**
  78      * Format node info to a string list.
  79      * @param dtm DTM instance.
  80      * @param nodeHandle node handle that represent node will be dumped.
  81      * @param indent a format indention.
  82      * @return 
  83      */
  84     private List<String> getNodeInfo(DTM dtm, int nodeHandle, String indent) {
  85         List<String> nodeLines = new ArrayList<>();
  86         String value = dtm.getNodeValue(nodeHandle);
  87         String vq = (value == null) ? "" : "\"";
  88 
  89         // Skip outputing of text nodes. In most cases they clutter the output,
  90         // besides I'm only interested in the elemental structure of the dtm.
  91         nodeLines.add(indent + nodeHandle + ": " 
  92                 + TYPENAME[dtm.getNodeType(nodeHandle)] + " "
  93                 + dtm.getNodeNameX(nodeHandle) + " : "
  94                 + dtm.getNodeName(nodeHandle) + "\""
  95                 + " E-Type=" + dtm.getExpandedTypeID(nodeHandle)
  96                 + " Level=" + dtm.getLevel(nodeHandle) 
  97                 + " Value=" + vq + value + vq);
  98 
  99         nodeLines.add(indent + "\tPrefix= " + "\"" + dtm.getPrefix(nodeHandle) + "\"" 
 100                 + " Name= " + "\"" + dtm.getLocalName(nodeHandle) + "\"" 
 101                 + " URI= " + "\"" + dtm.getNamespaceURI(nodeHandle) + "\"" 
 102                 + " Parent=" + dtm.getParent(nodeHandle) 
 103                 + " 1stChild=" + dtm.getFirstChild(nodeHandle) 
 104                 + " NextSib=" + dtm.getNextSibling(nodeHandle));
 105         return nodeLines;
 106     }
 107     
 108     /**
 109      * Recursively access every children of the node. Dump every information of
 110      * every node to given string list.
 111      * @param dtm DTM instance.
 112      * @param nodeHandle node handle that will be accessed.
 113      * @param lines a string list that recursive accessed node information will
 114      *              be dumped.
 115      */
 116     private void recursiveDumpNode(DTM dtm, int nodeHandle, List<String> lines) {
 117         // ITERATE over siblings
 118         while (DTM.NULL != nodeHandle) {
 119             lines.addAll(getNodeInfo(dtm, nodeHandle, ""));
 120 
 121             // List the namespaces, if any. Include only node's local 
 122             // namespaces, not inherited
 123             int kid = dtm.getFirstNamespaceNode(nodeHandle, false);
 124             if (kid != DTM.NULL) {
 125                 lines.add("\tNAMESPACES:");
 126                 //builder.append("\n\tNAMESPACES:");
 127                 for (; kid != DTM.NULL; kid = dtm.getNextNamespaceNode(nodeHandle, kid, false)) {
 128                     lines.addAll(getNodeInfo(dtm, kid, "\t"));
 129                 }
 130             }
 131 
 132             // List the attributes, if any
 133             kid = dtm.getFirstAttribute(nodeHandle);
 134             if (kid != DTM.NULL) {
 135                 lines.add("\tATTRIBUTES:");
 136                 for (; kid != DTM.NULL; kid = dtm.getNextSibling(kid)) {
 137                     lines.addAll(getNodeInfo(dtm, kid, "\t"));
 138                 }
 139             }
 140 
 141             // Recurse into the children, if any
 142             recursiveDumpNode(dtm, dtm.getFirstChild(nodeHandle), lines);
 143             nodeHandle = dtm.getNextSibling(nodeHandle);
 144         }
 145     }
 146 }