1 /*
   2  * Copyright (c) 2006, 2019, 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 
  24 package jnlp.converter.parser.xml;
  25 
  26 import java.io.PrintWriter;
  27 import java.io.StringWriter;
  28 
  29 /**
  30  * Class that contains information about an XML Node
  31  */
  32 public class XMLNode {
  33     private final boolean _isElement;     // Element/PCTEXT
  34     private final String _name;
  35     private final XMLAttribute _attr;
  36     private XMLNode _parent;  // Parent Node
  37     private XMLNode _nested;  // Nested XML tags
  38     private XMLNode _next;    // Following XML tag on the same level
  39 
  40     public final static String WILDCARD = "*";
  41 
  42     /** Creates a PCTEXT node */
  43     public XMLNode(String name) {
  44         _isElement = false;
  45         _name = name;
  46         _attr = null;
  47         _nested = null;
  48         _next = null;
  49         _parent = null;
  50     }
  51 
  52     /** Creates a ELEMENT node */
  53     public XMLNode(String name, XMLAttribute attr) {
  54         _isElement = true;
  55         _name = stripNameSpace(name);
  56         _attr = attr;
  57         _nested = null;
  58         _next = null;
  59         _parent = null;
  60     }
  61 
  62     public String getName() {
  63         return _name;
  64     }
  65 
  66     public XMLAttribute getAttributes() {
  67         return _attr;
  68     }
  69 
  70     public XMLNode getNested() {
  71         return _nested;
  72     }
  73 
  74     public XMLNode getNext() {
  75         return _next;
  76     }
  77 
  78     public boolean isElement() {
  79         return _isElement;
  80     }
  81 
  82     public void setParent(XMLNode parent) {
  83         _parent = parent;
  84     }
  85 
  86     public XMLNode getParent() {
  87         return _parent;
  88     }
  89 
  90     public void setNext(XMLNode next) {
  91         _next = next;
  92     }
  93 
  94     public void setNested(XMLNode nested) {
  95         _nested = nested;
  96     }
  97 
  98     public static String stripNameSpace(String name) {
  99         if (name != null && !name.startsWith("xmlns:")) {
 100             int i = name.lastIndexOf(":");
 101             if (i >= 0 && i < name.length()) {
 102                 return name.substring(i+1);
 103             }
 104         }
 105         return name;
 106     }
 107 
 108     @Override
 109     public int hashCode() {
 110         int hash = 3;
 111         hash = 83 * hash + (this._name != null ? this._name.hashCode() : 0);
 112         hash = 83 * hash + (this._attr != null ? this._attr.hashCode() : 0);
 113         hash = 83 * hash + (this._nested != null ? this._nested.hashCode() : 0);
 114         hash = 83 * hash + (this._next != null ? this._next.hashCode() : 0);
 115         return hash;
 116     }
 117 
 118     @Override
 119     public boolean equals(Object o) {
 120         if (o == null || !(o instanceof XMLNode)) return false;
 121         XMLNode other = (XMLNode)o;
 122         boolean result =
 123             match(_name, other._name) &&
 124             match(_attr, other._attr) &&
 125             match(_nested, other._nested) &&
 126             match(_next, other._next);
 127         return result;
 128     }
 129 
 130     public String getAttribute(String name) {
 131         XMLAttribute cur = _attr;
 132         while(cur != null) {
 133             if (name.equals(cur.getName())) return cur.getValue();
 134             cur = cur.getNext();
 135         }
 136         return "";
 137     }
 138 
 139     private static boolean match(Object o1, Object o2) {
 140         if (o1 == null) {
 141             return (o2 == null);
 142         }
 143         return o1.equals(o2);
 144     }
 145 
 146     public void printToStream(PrintWriter out) {
 147         printToStream(out, false);
 148     }
 149 
 150     public void printToStream(PrintWriter out, boolean trim) {
 151         printToStream(out, 0, trim);
 152     }
 153 
 154     public void printToStream(PrintWriter out, int n, boolean trim) {
 155         if (!isElement()) {
 156             String value = _name; // value node (where name is data of parent)
 157             if (trim && value.length() > 512) {
 158                 value = "...";
 159             }
 160             out.print(value);
 161         } else {
 162             if (_nested == null) {
 163                 String attrString = (_attr == null) ? "" : (" " + _attr.toString());
 164                 lineln(out, n, "<" + _name + attrString + "/>");
 165             } else {
 166                 String attrString = (_attr == null) ? "" : (" " + _attr.toString());
 167                 lineln(out, n, "<" + _name + attrString + ">");
 168                 _nested.printToStream(out, n + 1, trim);
 169                 if (_nested.isElement()) {
 170                     lineln(out, n, "</" + _name + ">");
 171                 } else {
 172                     out.print("</" + _name + ">");
 173                 }
 174             }
 175         }
 176         if (_next != null) {
 177             _next.printToStream(out, n, trim);
 178         }
 179     }
 180 
 181     private static void lineln(PrintWriter out, int indent, String s) {
 182         out.println("");
 183         for(int i = 0; i < indent; i++) {
 184             out.print("  ");
 185         }
 186         out.print(s);
 187     }
 188 
 189     @Override
 190     public String toString() {
 191         return toString(false);
 192     }
 193 
 194     public String toString(boolean hideLongElementValue) {
 195         StringWriter sw = new StringWriter(1000);
 196         PrintWriter pw = new PrintWriter(sw);
 197         printToStream(pw, hideLongElementValue);
 198         pw.close();
 199         return sw.toString();
 200     }
 201 }