package org.nate.internal.dom4j;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.Node;
import org.nate.encoder.NateDocument;
import org.nate.encoder.NateNode;
//Aaaarrrgggg... what a horrible inheritance hierarchy I have created!
public class Dom4jBackedDocumentFragment extends Dom4jBackedAbstactDocument implements NateDocument {
private static final DocumentFactory DOCUMENT_FACTORY = new DocumentFactory();
private Element pseudoRoot;
public Dom4jBackedDocumentFragment(List<? extends Node> rootNodes) {
this(wrapInPseudoRoot(new ArrayList<Node>(rootNodes)));
}
private Dom4jBackedDocumentFragment(Element pseudoRoot) {
super(pseudoRoot);
this.pseudoRoot = pseudoRoot;
}
@SuppressWarnings("unchecked")
@Override
protected Collection<? extends Node> getDom4jNodes() {
return pseudoRoot.content();
}
@Override
public NateDocument copy() {
return new Dom4jBackedDocumentFragment(pseudoRoot.createCopy());
}
@Override
public void removeAttribute(String attributeName) {
throw new IllegalStateException("Internal error.");
}
@Override
public String render() {
StringBuilder result = new StringBuilder();
for (Node node : getDom4jNodes()) {
result.append(node.asXML());
}
return result.toString();
}
@Override
public void replaceChildren(NateDocument newChildrenSource) {
if (!(newChildrenSource instanceof Dom4jBackedDocumentFragment)) {
throw new IllegalStateException(
"Internal Error. Expected Dom4jBackedDocumentFragment, but got: " + newChildrenSource);
}
Collection<? extends Node> newChildren = ((Dom4jBackedDocumentFragment)newChildrenSource).getDom4jNodes();
pseudoRoot = createPseudoRootElement();
for (Node newNode : newChildren) {
pseudoRoot.add((Node) newNode.clone());
}
}
@Override
public void replaceWith(List<NateNode> newNateNodes) {
this.pseudoRoot = createPseudoRootElement();
for (NateNode newNode : newNateNodes) {
Collection<? extends Node> dom4jNodes = ((Dom4jBackedAbstractNode)newNode.copy()).getDom4jNodes();
for (Node dom4jNode : dom4jNodes) {
pseudoRoot.add((Node) dom4jNode.clone());
}
}
}
@Override
public void setAttribute(String name, String value) {
throw new IllegalStateException("Internal error.");
}
@Override
public void setTextContent(String text) {
pseudoRoot = createPseudoRootElement();
pseudoRoot.setText(text);
}
private static Element wrapInPseudoRoot(List<? extends Node> nodes) {
Element result = createPseudoRootElement();
for (Node node : nodes) {
node.detach();
result.add(node);
}
return result;
}
private static Element createPseudoRootElement() {
return DOCUMENT_FACTORY.createElement("PseudoRoot");
}
}