package com.onaro.client.leekui.ui;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
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.w3c.dom.Text;
import com.onaro.client.leekui.ui.internal.WorkbenchPlugin;
/**
* This class represents the default implementation of the IMemento
interface.
*
* This class is not intended to be extended by clients. *
* * @see IMemento * This class is a reimplementation of the Eclipse class org.eclipse.ui.XMLMemento */ public final class XMLMemento implements IMemento { /** * Returns a root memento for writing a document. * * @param type the element node type to create on the document * @return the root memento for writing a document */ public static XMLMemento createWriteRoot(String type) { Document document; try { document = DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument(); Element element = document.createElement(type); document.appendChild(element); return new XMLMemento(document, element); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } } private final Document factory; private final Element element; public XMLMemento(Element element) { this(element.getOwnerDocument(), element); } /** * Creates a memento for the specified document and element. * * @param document * the document for the memento * @param element * the element node for the memento */ public XMLMemento(Document document, Element element) { super(); this.factory = document; this.element = element; } /* * (non-Javadoc) Method declared in IMemento. */ public IMemento createChild(String type) { return createChild(type,StringUtils.EMPTY); } /* * (non-Javadoc) Method declared in IMemento. */ public IMemento createChild(String type, String id) { Element child = factory.createElement(type); child.setAttribute(TAG_ID, id == null ? StringUtils.EMPTY : id); element.appendChild(child); return new XMLMemento(factory, child); } /* * (non-Javadoc) Method declared in IMemento. */ public IMemento getChild(String type) { // Get the nodes. NodeList nodes = element.getChildNodes(); int size = nodes.getLength(); if (size == 0) { return null; } // Find the first node which is a child of this node. for (int nX = 0; nX < size; nX++) { Node node = nodes.item(nX); if (node instanceof Element) { Element element = (Element) node; if (element.getNodeName().equals(type)) { return new XMLMemento(factory, element); } } } // A child was not found. return null; } /* * (non-Javadoc) Method declared in IMemento. */ public IMemento[] getChildren(String type) { // Get the nodes. NodeList nodes = element.getChildNodes(); int size = nodes.getLength(); if (size == 0) { return new IMemento[0]; } // Extract each node with given type. ArrayListnull
if the memento has no Text node.
*/
private Text getTextNode() {
// Get the nodes.
NodeList nodes = element.getChildNodes();
int size = nodes.getLength();
if (size == 0) {
return null;
}
for (int nX = 0; nX < size; nX++) {
Node node = nodes.item(nX);
if (node instanceof Text) {
return (Text) node;
}
}
// a Text node was not found
return null;
}
/**
* Places the element's attributes into the document.
*
* @param copyText
* true if the first text node should be copied
*/
private void putElement(Element element, boolean copyText) {
NamedNodeMap nodeMap = element.getAttributes();
int size = nodeMap.getLength();
for (int i = 0; i < size; i++) {
Attr attr = (Attr) nodeMap.item(i);
putString(attr.getName(), attr.getValue());
}
NodeList nodes = element.getChildNodes();
size = nodes.getLength();
// Copy first text node (fixes bug 113659).
// Note that text data will be added as the first child (see putTextData)
boolean needToCopyText = copyText;
for (int i = 0; i < size; i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
XMLMemento child = (XMLMemento) createChild(node.getNodeName());
child.putElement((Element) node, true);
}
else if (node instanceof Text && needToCopyText) {
putTextData(((Text) node).getData());
needToCopyText = false;
}
}
}
/*
* (non-Javadoc) Method declared in IMemento.
*/
public void putFloat(String key, float f) {
element.setAttribute(key, String.valueOf(f));
}
/*
* (non-Javadoc) Method declared in IMemento.
*/
public void putInteger(String key, int n) {
element.setAttribute(key, String.valueOf(n));
}
/*
* (non-Javadoc) Method declared in IMemento.
*/
public void putMemento(IMemento memento) {
// Do not copy the element's top level text node (this would overwrite the existing text).
// Text nodes of children are copied.
putElement(((XMLMemento) memento).element, false);
}
/*
* (non-Javadoc) Method declared in IMemento.
*/
public void putString(String key, String value) {
if (value == null) {
return;
}
element.setAttribute(key, value);
}
/*
* (non-Javadoc) Method declared in IMemento.
*/
public void putTextData(String data) {
Text textNode = getTextNode();
if (textNode == null) {
textNode = factory.createTextNode(data);
// Always add the text node as the first child (fixes bug 93718)
element.insertBefore(textNode, element.getFirstChild());
}
else {
textNode.setData(data);
}
}
public Element getElement() {
return element;
}
}