
org.xmind.core.util.DOMUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xmindjbehaveplugin Show documentation
Show all versions of xmindjbehaveplugin Show documentation
Plugin that manages JBehave stories storage in XMind mindmap file, which allows design jBehave tests right after the brainstorm
The newest version!
/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.core.util;
import static org.xmind.core.internal.dom.DOMConstants.ATTR_ID;
import static org.xmind.core.internal.dom.DOMConstants.TAG_TOPIC;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmind.core.Core;
import org.xmind.core.CoreException;
import org.xmind.core.IAdaptable;
import org.xmind.core.ITopic;
import org.xmind.core.internal.dom.INodeAdaptableProvider;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class DOMUtils {
private static class ElementIterator implements Iterator {
private String tagName;
private Node child;
// private NodeList children;
//
// private int index;
private Element next;
public ElementIterator(Node parent) {
this(parent, null);
}
public ElementIterator(Node parent, String tagName) {
this.tagName = tagName;
this.child = parent.getFirstChild();
// this.children = parent.getChildNodes();
// this.index = 0;
this.next = findNextElement();
}
private Element findNextElement() {
if (child == null) {
next = null;
} else {
while (child != null && !isElementByTag(child, tagName)) {
child = child.getNextSibling();
}
if (child != null) {
next = (Element) child;
child = child.getNextSibling();
} else {
next = null;
}
}
// for (int i = index; i < children.getLength(); i++) {
// Node n = children.item(i);
// if (isElementByTag(n, tagName)) {
// next = (Element) n;
// index = i + 1;
// return next;
// }
// }
return next;
}
public boolean hasNext() {
return next != null;
}
public Element next() {
Element result = next;
next = findNextElement();
return result;
}
public void remove() {
}
}
public static class AdaptableIterator implements
Iterator {
private Node node;
private String tagName;
private INodeAdaptableProvider provider;
private boolean reversed;
private T next;
public AdaptableIterator(Node parent, String tagName,
INodeAdaptableProvider provider, boolean reversed) {
this.tagName = tagName;
this.provider = provider;
this.reversed = reversed;
this.node = reversed ? parent.getLastChild() : parent
.getFirstChild();
this.next = findNext();
}
@SuppressWarnings("unchecked")
private T findNext() {
while (node != null) {
IAdaptable obj;
if (isElementByTag(node, tagName)) {
obj = provider.getAdaptable(node);
} else {
obj = null;
}
node = reversed ? node.getPreviousSibling() : node
.getNextSibling();
if (obj != null)
return (T) obj;
}
return null;
}
public boolean hasNext() {
return next != null;
}
public T next() {
T n = next;
next = findNext();
return n;
}
public void remove() {
}
}
private static class DelegateSet extends AbstractSet {
private Collection c;
public DelegateSet(Collection c) {
this.c = c;
}
public Iterator iterator() {
return c.iterator();
}
public int size() {
return c.size();
}
}
private static final ErrorHandler NULL_ERROR_HANDLER = new ErrorHandler() {
public void warning(SAXParseException exception) throws SAXException {
}
public void fatalError(SAXParseException exception) throws SAXException {
}
public void error(SAXParseException exception) throws SAXException {
}
};
// private static Transformer transformer = null;
// private static DocumentBuilder documentBuilder = null;
private DOMUtils() {
}
private static Transformer getDefaultTransformer() throws CoreException {
try {
return TransformerFactory.newInstance().newTransformer();
} catch (TransformerException e) {
throw new CoreException(Core.ERROR_FAIL_ACCESS_XML_TRANSFORMER, e);
}
}
public static DocumentBuilder getDefaultDocumentBuilder()
throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setAttribute(
"http://apache.org/xml/features/continue-after-fatal-error", //$NON-NLS-1$
true);
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
documentBuilder.setErrorHandler(NULL_ERROR_HANDLER);
return documentBuilder;
}
public static String toString(Node node) {
if (node == null)
return "null"; //$NON-NLS-1$
StringBuilder sb = new StringBuilder();
sb.append('[');
sb.append(node.getNodeName());
NamedNodeMap attributes = node.getAttributes();
if (attributes != null && attributes.getLength() > 0) {
for (int i = 0; i < attributes.getLength(); i++) {
sb.append(' ');
Node item = attributes.item(i);
sb.append(item.getNodeName());
sb.append('=');
sb.append('"');
sb.append(item.getNodeValue());
sb.append('"');
}
}
sb.append(']');
return sb.toString();
}
public static Document doCreateDocument()
throws ParserConfigurationException {
return getDefaultDocumentBuilder().newDocument();
}
/**
* @return
*/
public static Document createDocument() {
try {
return getDefaultDocumentBuilder().newDocument();
} catch (ParserConfigurationException e) {
return null;
}
}
/**
* @param docTag
* =manifest
* @return
*/
public static Document createDocument(String docTag) {
Document ret = createDocument();
createElement(ret, docTag);
return ret;
}
/**
* @param is
* @return
* @throws java.io.IOException
*/
public static Document loadDocument(InputStream is) throws IOException {
if (is == null)
throw new IllegalArgumentException();
try {
return getDefaultDocumentBuilder().parse(is);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
public static Document loadDocument(byte[] bytes) throws IOException {
if (bytes == null)
throw new IllegalArgumentException();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
try {
return loadDocument(in);
} finally {
in.close();
}
}
public static void save(Node dom, OutputStream out, boolean closeOnFinish)
throws IOException, CoreException {
save(getDefaultTransformer(), dom, out, closeOnFinish);
}
//manifest, zob, false
public static void save(IAdaptable adaptable, OutputStream out,
boolean closeOnFinish) throws IOException, CoreException {
save(getDefaultTransformer(), adaptable, out, closeOnFinish);
}
public static void save(Transformer t, IAdaptable adaptable,
OutputStream out, boolean closeOnFinish) throws IOException {
Node dom = (Node) adaptable.getAdapter(Node.class);
if (dom != null) {
save(t, dom, out, closeOnFinish);
}
}
public static void save(Transformer t, Node dom, OutputStream out,
boolean closeOnFinish) throws IOException {
try {
t.transform(new DOMSource(dom), new StreamResult(out));
} catch (TransformerException e) {
throw new IOException(e.getMessage());
} finally {
if (closeOnFinish) {
out.close();
}
}
}
/**
* @param parent
* @param tag
* =manifest
* @return
*/
public static Element createElement(Node parent, String tag) {
Document doc = parent.getNodeType() == Node.DOCUMENT_NODE ? (Document) parent
: parent.getOwnerDocument();
Element e = doc.createElement(tag);
parent.appendChild(e);
return e;
}
public static String getPrefix(String qualifiedName) {
int index = qualifiedName.indexOf(':');
if (index >= 0)
return qualifiedName.substring(0, index);
return null;
}
public static String getLocalName(String qualifiedName) {
int index = qualifiedName.indexOf(':');
if (index >= 0)
return qualifiedName.substring(index + 1);
return qualifiedName;
}
public static String getQualifiedName(String prefix, String localName) {
return prefix + ":" + localName; //$NON-NLS-1$
}
/**
* @param parent
* @param tag
* @param text
* @return
*/
public static Element createText(Node parent, String tag, String text) {
Element e = createElement(parent, tag);
Node t = parent.getOwnerDocument().createTextNode(text);
e.appendChild(t);
return e;
}
/**
* @param parent
* @param name
* @param value
* @return
*/
public static Attr createAttr(Element parent, String name, Object value) {
if (value == null)
return null;
Attr a = parent.getOwnerDocument().createAttribute(name);
a.setNodeValue(value.toString());
parent.getAttributes().setNamedItem(a);
return a;
}
/**
* @param element
* @param attrName
* @param value
*/
public static void setAttribute(Element element, String attrName,
Object value) {
if (value != null) {
element.setAttribute(attrName, value.toString());
} else if (element.hasAttribute(attrName)) {
element.removeAttribute(attrName);
}
}
public static String getAttribute(Element element, String attrName) {
if (!element.hasAttribute(attrName)) {
String localName = getLocalName(attrName);
if (!attrName.equals(localName))
return getAttribute(element, localName);
return null;
}
return element.getAttribute(attrName);
}
public static boolean isElementByTag(Node node, String tagName) {
if (!(node instanceof Element))
return false;
if (tagName == null)
return true;
Element element = (Element) node;
String tag = element.getTagName();
return tag.equals(tagName)
|| getLocalName(tag).equals(getLocalName(tagName));
}
public static Iterator childElementIter(Node parent) {
return new ElementIterator(parent);
}
public static Iterator childElementIterByTag(Node parent,
String tagName) {
return new ElementIterator(parent, tagName);
}
public static boolean hasChildElement(Node parent) {
return childElementIter(parent).hasNext();
}
public static boolean hasChildElementByTag(Node parent, String tagName) {
return childElementIterByTag(parent, tagName).hasNext();
}
public static int getElementIndex(Node parent, String tagName, Element child) {
Iterator it = childElementIterByTag(parent, tagName);
for (int i = 0; it.hasNext(); i++) {
if (it.next() == child)
return i;
}
return -1;
}
public static int getNodeIndex(Node parent, Node child) {
NodeList children = parent.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
if (child == children.item(i))
return i;
}
return -1;
}
public static Element getFirstChildElement(Node parent) {
return childElementIter(parent).next();
}
public static Element getFirstChildElementByTag(Node parent, String tag) {
return childElementIterByTag(parent, tag).next();
}
public static int getNumChildElementsByTag(Node parent, String tag) {
int num = 0;
Iterator it = childElementIterByTag(parent, tag);
while (it.hasNext()) {
it.next();
num++;
}
return num;
}
/**
* @param parent
* @param tag
* @return
*/
public static Element[] getChildElementsByTag(Node parent, String tag) {
List list = new ArrayList(parent.getChildNodes()
.getLength());
Iterator it = childElementIterByTag(parent, tag);
while (it.hasNext()) {
list.add(it.next());
}
return list.toArray(new Element[list.size()]);
}
public static Element[] getChildElements(Node parent) {
List list = new ArrayList(parent.getChildNodes()
.getLength());
Iterator it = childElementIter(parent);
while (it.hasNext()) {
list.add(it.next());
}
return list.toArray(new Element[list.size()]);
}
public static Element ensureChildElement(Node parent, String tagName) {
Element ele;
if (parent.getNodeType() == Node.DOCUMENT_NODE) {
ele = ((Document) parent).getDocumentElement();
} else {
ele = getFirstChildElementByTag(parent, tagName);
}
if (ele == null) {
ele = createElement(parent, tagName);
}
return ele;
}
public static void createCentalTopicElement(Node parent, ITopic topic) {
if (topic == null)
createElement(parent, TAG_TOPIC);
else
createElement(parent, topic.getTitleText());
}
public static List getChildList(Element element,
String childTag, INodeAdaptableProvider finder) {
List list = getChildren(element, childTag, finder);
return list;
}
public static Set getChildSet(Element element,
String childTag, INodeAdaptableProvider finder) {
List list = getChildren(element, childTag, finder);
return unmodifiableSet(list);
}
public static Iterator emptyIter() {
return new Iterator() {
public boolean hasNext() {
return false;
}
public T next() {
return null;
}
public void remove() {
}
};
}
@SuppressWarnings("unchecked")
public static List getChildren(Element element,
String childTag, INodeAdaptableProvider finder) {
ArrayList list = new ArrayList(element.getChildNodes()
.getLength());
Iterator it = childElementIterByTag(element, childTag);
while (it.hasNext()) {
Element child = it.next();
IAdaptable a = finder.getAdaptable(child);
if (a != null) {
list.add((T) a);
}
}
return list;
}
@SuppressWarnings("unchecked")
public static List getChildren(Node parent,
INodeAdaptableProvider finder) {
NodeList childNodes = parent.getChildNodes();
int num = childNodes.getLength();
ArrayList list = new ArrayList(num);
for (int i = 0; i < num; i++) {
Node n = childNodes.item(i);
IAdaptable a = finder.getAdaptable(n);
if (a != null) {
list.add((T) a);
}
}
return list;
}
public static Set unmodifiableSet(Collection c) {
return new DelegateSet(c);
}
/**
* @param parent
* @param tag
* @return
*/
public static String getTextContentByTag(Node parent, String tag) {
Element ele = getFirstChildElementByTag(parent, tag);
if (ele == null)
return null;
Node firstChild = ele.getFirstChild();
return firstChild == null ? null : firstChild.getTextContent();
}
/**
* @param titleNode
* @param textContent
*/
public static void setText(Node titleNode, String textContent) {
Node textNode = findTextNode(titleNode);
if (textNode != null) {
if (textContent == null) {
titleNode.removeChild(textNode);
} else {
textNode.setTextContent(textContent);
}
} else {
titleNode.setTextContent(textContent);
}
}
public static Node findTextNode(Node node) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node c = children.item(i);
if (c.getNodeType() == Node.TEXT_NODE)
return c;
}
return null;
}
/**
* @param parent
* @param tag
* @param text
*/
public static void setText(Node parent, String tag, String text) {
Element titleElement = getFirstChildElementByTag(parent, tag);
if (titleElement == null) {
if (text != null)
createText(parent, tag, text);
} else {
setText(titleElement, text);
if (!titleElement.hasChildNodes() && !titleElement.hasAttributes()) {
parent.removeChild(titleElement);
}
}
}
/**
* @param element
* @return
*/
public static Element addIdAttribute(Element element) {
if (!element.hasAttribute(ATTR_ID)) {
element.setAttribute(ATTR_ID, Core.getIdFactory().createId());
element.setIdAttribute(ATTR_ID, true);
}
return element;
}
public static String replaceId(Element element) {
String newId = Core.getIdFactory().createId();
replaceId(element, newId);
return newId;
}
public static Element replaceId(Element element, String newId) {
if (newId == null)
return element;
element.setAttribute(ATTR_ID, newId);
element.setIdAttribute(ATTR_ID, true);
return element;
}
public static boolean isOrphanNode(Node node) {
if (node == null)
return true;
if (node.getNodeType() == Node.DOCUMENT_NODE)
return false;
return isOrphanNode(node.getParentNode());
}
public static Document getOwnerDocument(Node node) {
return node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node
: node.getOwnerDocument();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy