package hu.jokeman.xparser.impl.document;
import hu.jokeman.xparser.document.DocumentBuilder;
import hu.jokeman.xparser.document.DocumentBuilderException;
import hu.jokeman.xparser.document.XMLNode;
import hu.jokeman.xparser.impl.document.nodes.Attribute;
import hu.jokeman.xparser.impl.document.nodes.CData;
import hu.jokeman.xparser.impl.document.nodes.Comment;
import hu.jokeman.xparser.impl.document.nodes.DocType;
import hu.jokeman.xparser.impl.document.nodes.Document;
import hu.jokeman.xparser.impl.document.nodes.Element;
import hu.jokeman.xparser.impl.document.nodes.EntityReference;
import hu.jokeman.xparser.impl.document.nodes.ProcessingInstruction;
import java.util.Stack;
public class DocumentBuilderImpl implements DocumentBuilder {
private Stack<XMLNode> _currentNodes;
private Document _rootNode;
public DocumentBuilderImpl () {
_currentNodes = null;
_rootNode = null;
}
private XMLNode peek () {
return _currentNodes.peek ();
}
private void push (XMLNode aNode) {
_currentNodes.push (aNode);
}
private XMLNode pop () {
return _currentNodes.pop ();
}
public void addCData (String content) throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Document ||
currentNode instanceof Element) {
currentNode.addChild (new CData (content));
} else {
throw new DocumentBuilderException ("CData isn't allowed here.");
}
}
public void addDocType (String docType) throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Document) {
currentNode.addChild (new DocType (docType));
} else {
throw new DocumentBuilderException (
"Document schema definitions aren't allowed here.");
}
}
public void createProcessingInstructionStart (String piName)
throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Document) {
ProcessingInstruction pi = new ProcessingInstruction (piName);
currentNode.addChild (pi);
push (pi);
} else {
throw new DocumentBuilderException (
"Document schema definitions aren't allowed here.");
}
}
public void finishProcessingInstructionStart ()
throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof ProcessingInstruction) {
pop ();
} else {
throw new DocumentBuilderException (
"Current node is not a processing instruction.");
}
}
public void createTagStart (String tagName) throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Document ||
currentNode instanceof Element) {
Element element = new Element (tagName);
currentNode.addChild (element);
push (element);
} else {
throw new DocumentBuilderException (
"Elements not allowed here.");
}
}
public void finishTagStart () throws DocumentBuilderException {
}
public void addAttribute (String attrName, String attrVal)
throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Element ||
currentNode instanceof ProcessingInstruction) {
Attribute attr = new Attribute (attrName);
attr.setValue (attrVal);
currentNode.addChild (attr);
} else {
throw new DocumentBuilderException (
"Attributes not allowed here.");
}
}
public void addTagClose (String tagName) throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (!(currentNode instanceof Element) ||
!((Element) currentNode).getName ().equals (tagName)) {
throw new DocumentBuilderException (
"Cannot close element: " + tagName + ".");
}
pop ();
}
public void addEntityReference (String entityName)
throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Element) {
currentNode.addChild (new EntityReference (entityName));
} else {
throw new DocumentBuilderException (
"Entity references not allowed here.");
}
}
public void addComment (String content) throws DocumentBuilderException {
XMLNode currentNode = peek ();
if (currentNode instanceof Element ||
currentNode instanceof Document) {
currentNode.addChild (new Comment (content));
} else {
throw new DocumentBuilderException (
"Comments not allowed here.");
}
}
public void createDocument () {
_rootNode = new Document ();
_currentNodes = new Stack<XMLNode> ();
push (_rootNode);
}
public Document getDocument () throws DocumentBuilderException {
if (null == _rootNode) {
throw new DocumentBuilderException ("Document not yet created.");
}
return _rootNode;
}
}