/****************************************************************** * * CyberXML for Java * * Copyright (C) Satoshi Konno 2002 * * File: Element.java * * Revision; * * 11/27/02 * - first revision. * 11/01/03 * - Terje Bakken * - fixed missing escaping of reserved XML characters * 11/19/04 * - Theo Beisch <theo.beisch@gmx.de> * - Added "&" and "\"" "\\" to toXMLString(). * 11/19/04 * - Theo Beisch <theo.beisch@gmx.de> * - Changed XML::output() to use short notation when the tag value is null. * 12/02/04 * - Brian Owens <brian@b-owens.com> * - Fixed toXMLString() to convert from "'" to "'" instead of "\". * 11/07/05 * - Changed toString() to return as utf-8 string. * 02/08/08 * - Added addValue(). * ******************************************************************/ package org.cybergarage.xml; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.Iterator; public class Node { /** * Create a Node with empty UserData and no Parent Node * */ public Node() { setUserData(null); setParentNode(null); } public Node(String name) { this(); setName(name); } public Node(String ns, String name) { this(); setName(ns, name); } public Node(Node otherNode) { this(); set(otherNode); } //////////////////////////////////////////////// // parent node //////////////////////////////////////////////// private Node parentNode = null; public void setParentNode(Node node) { parentNode = node; } public Node getParentNode() { return parentNode; } //////////////////////////////////////////////// // root node //////////////////////////////////////////////// public Node getRootNode() { Node rootNode = null; Node parentNode = getParentNode(); while (parentNode != null) { rootNode = parentNode; parentNode = rootNode.getParentNode(); } return rootNode; } //////////////////////////////////////////////// // name //////////////////////////////////////////////// private String name = new String(); public void setName(String name) { this.name = name; } public void setName(String ns, String name) { this.name = ns + ":" + name; } public String getName() { return name; } public boolean isName(String value) { return name.equals(value); } //////////////////////////////////////////////// // value //////////////////////////////////////////////// private String value = new String(); public void setValue(String value) { this.value = value; } public void setValue(int value) { setValue(Integer.toString(value)); } public void addValue(String value) { if (this.value == null) { this.value = value; return; } if (value != null) this.value += value; } public String getValue() { return value; } //////////////////////////////////////////////// // Attribute (Basic) //////////////////////////////////////////////// private AttributeList attrList = new AttributeList(); public int getNAttributes() { return attrList.size(); } public Attribute getAttribute(int index) { return attrList.getAttribute(index); } public Attribute getAttribute(String name) { return attrList.getAttribute(name); } public void addAttribute(Attribute attr) { attrList.add(attr); } public void insertAttributeAt(Attribute attr, int index) { attrList.insertElementAt(attr, index); } public void addAttribute(String name, String value) { Attribute attr = new Attribute(name, value); addAttribute(attr); } public boolean removeAttribute(Attribute attr) { return attrList.remove(attr); } public boolean removeAttribute(String name) { return removeAttribute(getAttribute(name)); } public void removeAllAttributes() { attrList.clear(); } public boolean hasAttributes() { if (0 < getNAttributes()) return true; return false; } //////////////////////////////////////////////// // Attribute (Extention) //////////////////////////////////////////////// public void setAttribute(String name, String value) { Attribute attr = getAttribute(name); if (attr != null) { attr.setValue(value); return; } attr = new Attribute(name, value); addAttribute(attr); } public void setAttribute(String name, int value) { setAttribute(name, Integer.toString(value)); } public String getAttributeValue(String name) { Attribute attr = getAttribute(name); if (attr != null) return attr.getValue(); return ""; } public int getAttributeIntegerValue(String name) { String val = getAttributeValue(name); try { return Integer.parseInt(val); } catch (Exception e) {} return 0; } //////////////////////////////////////////////// // Attribute (xmlns) //////////////////////////////////////////////// public void setNameSpace(String ns, String value) { setAttribute("xmlns:" + ns, value); } //////////////////////////////////////////////// // set //////////////////////////////////////////////// public boolean set(Node otherNode) { if (otherNode == null) return false; setName(otherNode.getName()); setValue(otherNode.getValue()); removeAllAttributes(); int nOtherAttributes = otherNode.getNAttributes(); for (int n=0; n<nOtherAttributes; n++) { Attribute otherAttr = otherNode.getAttribute(n); Attribute thisAttr = new Attribute(otherAttr); addAttribute(thisAttr); } removeAllNodes(); int nOtherChildNodes = otherNode.getNNodes(); for (int n=0; n<nOtherChildNodes; n++) { Node otherChildNode = otherNode.getNode(n); Node thisChildNode = new Node(); thisChildNode.set(otherChildNode); addNode(thisChildNode); } return true; } //////////////////////////////////////////////// // equals //////////////////////////////////////////////// @Override public boolean equals(Object o) { if (this == o) return true; if (o == null) return false; if (!(o instanceof Node)) return false; Node otherNode = (Node) o; String thisNodeString = toString(); String otherNodeString = otherNode.toString(); return thisNodeString.equals(otherNodeString); } //////////////////////////////////////////////// // Child node //////////////////////////////////////////////// private NodeList nodeList = new NodeList(); public int getNNodes() { return nodeList.size(); } public Node getNode(int index) { return nodeList.getNode(index); } public Node getNode(String name) { return nodeList.getNode(name); } public Node getNodeEndsWith(String name) { return nodeList.getEndsWith(name); } public void addNode(Node node) { node.setParentNode(this); nodeList.add(node); } public void insertNode(Node node, int index) { node.setParentNode(this); nodeList.insertElementAt(node, index); } public int getIndex(String name){ int index = -1; for (Iterator<Node> i = nodeList.iterator(); i.hasNext();) { index++; Node n = i.next(); if(n.getName().equals(name)) return index; } return index; } public boolean removeNode(Node node) { node.setParentNode(null); return nodeList.remove(node); } public boolean removeNode(String name) { return nodeList.remove(getNode(name)); } public void removeAllNodes() { nodeList.clear(); } public boolean hasNodes() { if (0 < getNNodes()) return true; return false; } //////////////////////////////////////////////// // Element (Child Node) //////////////////////////////////////////////// public boolean hasNode(String name) { Node node = getNode(name); if (node != null) { return true; } return false; } public void setNode(String name) { if (hasNode(name)) { return; } Node node = new Node(name); addNode(node); } public void setNode(String name, String value) { Node node = getNode(name); if (node == null) { node = new Node(name); addNode(node); } node.setValue(value); } public String getNodeValue(String name) { Node node = getNode(name); if (node != null) return node.getValue(); return ""; } //////////////////////////////////////////////// // userData //////////////////////////////////////////////// private Object userData = null; public void setUserData(Object data) { userData = data; } public Object getUserData() { return userData; } //////////////////////////////////////////////// // toString //////////////////////////////////////////////// /** * Inovoke {@link #getIndentLevelString(int, String)} with <code>" "</code> as String * * @see #getIndentLevelString(int, String) */ public String getIndentLevelString(int nIndentLevel) { return getIndentLevelString(nIndentLevel," "); } /** * * @param nIndentLevel the level of indentation to produce * @param space the String to use for the intendation * @since 1.8.0 * @return an indentation String */ public String getIndentLevelString(int nIndentLevel,String space) { StringBuffer indentString = new StringBuffer(nIndentLevel*space.length()); for (int n=0; n<nIndentLevel; n++){ indentString.append(space); } return indentString.toString(); } public void outputAttributes(PrintWriter ps) { int nAttributes = getNAttributes(); for (int n=0; n<nAttributes; n++) { Attribute attr = getAttribute(n); ps.print(" " + attr.getName() + "=\"" + XML.escapeXMLChars(attr.getValue()) + "\""); } } public void output(PrintWriter ps, int indentLevel, boolean hasChildNode) { String indentString = getIndentLevelString(indentLevel); String name = getName(); String value = getValue(); if (hasNodes() == false || hasChildNode == false) { ps.print(indentString + "<" + name); outputAttributes(ps); // Thnaks for Tho Beisch (11/09/04) if (value == null || value.length() == 0) { // Not using the short notation <node /> because it cause compatibility trouble ps.println("></" + name + ">"); } else { ps.println(">" + XML.escapeXMLChars(value) + "</" + name + ">"); } return; } ps.print(indentString + "<" + name); outputAttributes(ps); ps.println(">"); int nChildNodes = getNNodes(); for (int n=0; n<nChildNodes; n++) { Node cnode = getNode(n); cnode.output(ps, indentLevel+1, true); } ps.println(indentString +"</" + name + ">"); } public String toString(String enc, boolean hasChildNode) { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); PrintWriter pr = new PrintWriter(byteOut); output(pr, 0, hasChildNode); pr.flush(); try { if (enc != null && 0 < enc.length()) return byteOut.toString(enc); } catch (UnsupportedEncodingException e) { } return byteOut.toString(); } public String toString() { return toString(XML.CHARSET_UTF8, true); } public String toXMLString(boolean hasChildNode) { String xmlStr = toString(); xmlStr = xmlStr.replaceAll("<", "<"); xmlStr = xmlStr.replaceAll(">", ">"); // Thanks for Theo Beisch (11/09/04) xmlStr = xmlStr.replaceAll("&", "&"); xmlStr = xmlStr.replaceAll("\"", """); // Thanks for Brian Owens (12/02/04) xmlStr = xmlStr.replaceAll("'", "'"); return xmlStr; } public String toXMLString() { return toXMLString(true); } public void print(boolean hasChildNode) { PrintWriter pr = new PrintWriter(System.out); output(pr, 0, hasChildNode); pr.flush(); } public void print() { print(true); } }