📄 hashmapelement.java
字号:
/*
Copyright (C) 2003 Together
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.enhydra.xml;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.HashMap;
import java.util.HashMap;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author Tweety
*
* A class representing a node in a meta-data tree, which implements
* the <a href="../../../../api/org/w3c/dom/Element.html">
*
* <p> Namespaces are ignored in this implementation. The terms "tag
* name" and "node name" are always considered to be synonymous.
*
* @version 1.0
*/
public class HashMapElement extends ElementImpl {
/**
* All <code>Element<code> type children of this <code>Element<code>
*/
protected HashMap children = null;
/**
* Constructs an empty <code>HashMapElement</code>.
*/
public HashMapElement() {
super();
children = new HashMap();
}
/**
* Constructs a <code>HashMapElement</code> from the given node,
* without creating entire children subtree.
*
* @param element , as a <code>HashMapElement</code>.
*/
public HashMapElement(HashMapElement element) {
super(element);
children = element.children;
}
/**
* Constructs an <code>HashMapElement</code> with the given
* document owner and node name.
*
* @param ownerDoc the document owner of the node, as a <code>Document</code>.
* @param name is the name of the node, as a <code>String</code>.
*/
public HashMapElement(Document ownerDoc, String name) {
super(ownerDoc, name);
this.children = new HashMap();
}
/**
* Constructs an <code>HashMapElement</code> with the given
* document owner, node name, node type and node value.
*
* @param ownerDoc the document owner of the node, as a <code>Document</code>.
* @param nodeName the name of the node, as a <code>String</code>.
* @param type the type of the node, as a <code>short</code>.
* @param value the value of the node, as a <code>String</code>.
*/
protected HashMapElement(Document ownerDoc, String nodeName, short type, String value) {
super(ownerDoc, nodeName, type, value);
}
/**
* Constructs an <code>HashMapElement</code> from a given node
* (creates the children subtree too), as a <code>Node</code>
*
* @param node , as a <code>Node</code>.
*/
public HashMapElement(Node node) {
this(node, true);
}
/**
* Constructs an <code>HashMapElement</code> from a given node,
* as a <code>Node</code>, and deep as <code>boolean</code>.
*
* @param node , as a <code>Node</code>.
* @param deep if <code>true</code>, recursively clone the subtree
* under the specified node; if <code>false</code>, clone only the
* node itself.
*/
public HashMapElement(Node node, boolean deep) {
super(node, false);
children = new HashMap();
if (deep)
initNodeImplChildren(node);
}
/**
* Creates new instance of the HashMapElement class from the given <code>Node</code>.
*
* @param node , as a <code>Node</code>.
*
* @return new instance of the HashMapElement class.
*/
protected Node newElementInstance(Node node) {
return new HashMapElement(node);
}
/**
* Creates new instance of <code>HashMapElement</code> from a given document
* as a <code>Document</code>.
*
* @param document document.
*
* @return new <code>Element</code> node as a root of the <code>Document</code>.
*/
public static Element newInstance(Document document) {
Node root = document.getDocumentElement();
return new HashMapElement(root);
}
/**
* Inserts the node <code>newChild</code> before the existing
* child node <code>refChild</code>. If <code>refChild</code> is
* <code>null</code>, insert <code>newChild</code> at the end of
* the list of children.
*
* @param newChild the <code>Node</code> to insert.
* @param refChild the reference <code>Node</code>.
*
* @return the node being inserted.
*
* @exception IllegalArgumentException if <code>newChild</code> is
* <code>null</code>.
*/
public Node insertBefore(Node newChild, Node refChild) {
super.insertBefore(newChild, refChild);
if (newChild.getNodeType() == ELEMENT_NODE) {
HashMapElement newChildNode = (HashMapElement) newChild;
List list = (List) children.get(newChildNode.getTagName());
if (list == null)
list = new ArrayList();
list.add(newChildNode);
children.put(newChildNode.getTagName(), list);
}
return newChild;
}
/**
* Replaces the child node <code>oldChild</code> with
* <code>newChild</code> in the list of children, and returns the
* <code>oldChild</code> node.
*
* @param newChild the <code>Node</code> to insert.
* @param oldChild the <code>Node</code> to be replaced.
*
* @return the node replaced.
*
* @exception IllegalArgumentException if <code>newChild</code> is
* <code>null</code>.
*/
public Node replaceChild(Node newChild, Node oldChild) {
super.replaceChild(newChild, oldChild);
if (oldChild.getNodeType() == ELEMENT_NODE) {
HashMapElement oldChildNode = (HashMapElement) oldChild;
List list = (List) children.get(oldChildNode.getTagName());
if (list != null) {
int index = list.indexOf(oldChildNode);
if (index != -1)
list.remove(index);
if (list.size() == 0)
children.remove(oldChildNode.getTagName());
}
}
if (newChild.getNodeType() == ELEMENT_NODE) {
HashMapElement newChildNode = (HashMapElement) newChild;
List list = (List) children.get(newChildNode.getTagName());
if (list == null)
list = new ArrayList();
list.add(newChildNode);
children.put(newChildNode.getTagName(), list);
}
return oldChild;
}
/**
* Removes the child node indicated by <code>oldChild</code> from
* the list of children, and returns it.
*
* @param oldChild the <code>Node</code> to be removed.
*
* @return the node removed.
*
* @exception IllegalArgumentException if <code>oldChild</code> is
* <code>null</code>.
*/
public Node removeChild(Node oldChild) {
super.removeChild(oldChild);
if (oldChild.getNodeType() == ELEMENT_NODE) {
HashMapElement oldChildNode = (HashMapElement) oldChild;
List list = (List) children.get(oldChildNode.getTagName());
if (list != null) {
int index = list.indexOf(oldChildNode);
if (index != -1)
list.remove(index);
if (list.size() == 0)
children.remove(oldChildNode.getTagName());
}
}
return oldChild;
}
/**
* Check that the node is either <code>null</code> or an
* <code>NodeImpl</code>.
*
* @exception DOMException if node is not an instance of <code>NodeImpl</code>.
*/
// protected void checkNode(Node node) throws DOMException {
// if (node == null) {
// return;
// }
// if (!(node instanceof HashMapElement))
// throw new NodeDOMException(DOMException.WRONG_DOCUMENT_ERR, "Node is not an instance of HashMapElement!");
// }
/**
* Returns a duplicate of this node. The duplicate node has no
* parent (<code>getParentNode</code> returns <code>null</code>).
* If a shallow clone is being performed (<code>deep</code> is
* <code>false</code>), the new node will not have any children or
* siblings. If a deep clone is being performed, the new node
* will form the root of a complete cloned subtree.
*
* @param deep if <code>true</code>, recursively clone the subtree
* under the specified node; if <code>false</code>, clone only the
* node itself.
*
* @return the duplicate node.
*/
public Node cloneNode(boolean deep) {
return new HashMapElement(this, deep);
}
/**
* Returns all <code>Element</code> nodes with given name,
* searching by all sub nodes from this node.
*
* @param name tag name.
*
* @return all <code>Element</code> vith given name as <code>NodeList</code>.
*/
public NodeList getElementsByTagName(String name) {
List list = new ArrayList();
// added for new search
if (nodeName.equals(name)) {
list.add(this);
}
getElementsByTagName(name, list);
return new NodeListImpl(list);
}
private void getElementsByTagName(String name, List list) {
if (numChildren == 0)
return;
List fList = (List) children.get(name);
if (fList != null);
list.addAll(fList);
for (Iterator iter = children.values().iterator(); iter.hasNext();) {
fList = (List) iter.next();
for (int i = 0; i < fList.size(); i++) {
((HashMapElement) fList.get(i)).getElementsByTagName(
name,
list);
}
}
}
/**
* Returns <code>true</code> if this node has child nodes.
*
* @return <code>true</code> if this node has children.
*/
public boolean hasElementChildNodes() {
return children.size() > 0;
}
/**
* Returns the list of all children nodes with the given tag name.
*
* @param name tag name.
*
* @return the list of all children nodes with the given tag name.
*/
public NodeList getChildrenByTagName(String name) {
List list = (List) this.children.get(name);
if (list != null)
return new NodeListImpl(list);
return null;
}
/**
* Returns the first child <code>Element</code> with the given tag name.
*
* @param name tag name.
*
* @return the first child <code>Element</code> with the given tag name.
*/
public Element getFirstChildByTagName(String name) {
NodeList children = getChildrenByTagName(name);
if (children != null && children.getLength() > 0)
return (HashMapElement) children.item(0);
return null;
}
/**
* Returns the next <code>Element</code> node (if exists) with the same tag name.
*
* @return the next <code>Element</code> node (if exists) with the same tag name.
*/
public Element getNextSameNameNode() {
try {
HashMapElement parent = (HashMapElement) this.getParentNode();
List tagList = (List) parent.children.get(this.nodeName);
int index = tagList.indexOf(this);
if (++index <= tagList.size())
return (HashMapElement) tagList.get(index);
} catch (NullPointerException e) {
throw new NodeDOMException(
DOMException.NOT_FOUND_ERR,
"Root node doesn't have a successor");
}
return null;
}
/**
* Returns the concatenation of values of all text type children.
*
* @return the concatenation of values of all text type children.
*/
public String getText() {
String text = "";
Node child = this.getFirstChild();
while (child != null) {
if (child.getNodeType() == Node.TEXT_NODE)
text += child.getNodeValue();
child = child.getNextSibling();
}
if (!text.equals(""))
return text;
return null;
}
/**
* Set the value of the first text child node to the given text,
* and remove all other text child nodes.
*
* @param text new text.
*/
public void setText(String text) {
Node child = this.getFirstChild();
if (child != null) {
child.setNodeValue(text);
child = child.getNextSibling();
while (child != null) {
if (child.getNodeType() == Node.TEXT_NODE) {
Node temp = child;
child = child.getNextSibling();
this.removeChild(temp);
} else {
child = child.getNextSibling();
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -