package es.iiia.shapegrammar.grammar;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import es.iiia.shapegrammar.model.ShapeGrammarModel;
import es.iiia.shapegrammar.rule.RuleCreationFactory;
import es.iiia.shapegrammar.rule.RuleModel;
import es.iiia.shapegrammar.shape.ShapeModel;
import es.iiia.shapegrammar.utils.XmlParser;
import es.iiia.shapegrammar.utils.XmlUtils;
public class ShapeGrammarParser extends XmlParser {
// No generics
private ShapeGrammarModel grammar;
private Element docEle;
public ShapeGrammarParser(ShapeGrammarModel grammar) {
// create a list to hold the employee objects
this.grammar = grammar;
}
public Element createDocument() {
Element root = this.initDocument("shapeGrammar");
if (this.grammar.getType() != null) {
XmlUtils.appendAttribute(root, "type", this.grammar.getType());
}
XmlUtils.appendNode(root, "shapes");
XmlUtils.appendNode(root, "rules");
return root;
}
public void loadXml(String xmlFilePath) {
this.grammar.getShapes().clear();
this.grammar.getRules().clear();
// load the xmlfile
// now parse opened document
// get the root elememt
docEle = this.getDocument(xmlFilePath).getDocumentElement();
// get a nodelist of shape elements
NodeList nl = docEle.getElementsByTagName("shape");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
// get the shape element
Element el = (Element) nl.item(i);
// initialize it and add it to collection
ShapeModel model = initShape(el);
this.grammar.getShapes().add(model);
}
}
// TODO: get a nodelist of rule elements
nl = docEle.getElementsByTagName("rule");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
// get the shape element
Element el = (Element) nl.item(i);
// initialize it and add it to collection
RuleModel model = initRule(el);
this.grammar.getRules().add(model);
}
}
}
public String getGrammarType(String xmlFilePath) {
return this.getDocument(xmlFilePath).getDocumentElement().getAttribute("type");
}
protected ShapeModel initShape(Element el) {
return new ShapeModel(this.grammar, el);
}
protected RuleModel initRule(Element el) {
return RuleCreationFactory.initRuleByType(
this.grammar, el);
}
public String getXml() {
// we create document from sratch on each save
docEle = this.createDocument();
// Save shapes
Node shapes = docEle.getElementsByTagName("shapes").item(0);
for (ShapeModel shape : this.grammar.getShapes()) {
shapes.appendChild(shapes.getOwnerDocument().importNode(
shape.getXml(), true));
}
// Save rules
Node rules = docEle.getElementsByTagName("rules").item(0);
for (RuleModel rule : this.grammar.getRules()) {
rules.appendChild(rules.getOwnerDocument().importNode(
rule.getXml(), true));
}
// now finally save document
return XmlUtils.getXml(this.getDocument());
}
public void saveXml(String fileName) {
// we create document from sratch on each save
docEle = this.createDocument();
// check extension
if (!fileName.endsWith(".xml")) {
fileName += ".xml";
}
// Save shapes
Node shapes = docEle.getElementsByTagName("shapes").item(0);
for (ShapeModel shape : this.grammar.getShapes()) {
shapes.appendChild(shapes.getOwnerDocument().importNode(
shape.getXml(), true));
}
// Save rules
Node rules = docEle.getElementsByTagName("rules").item(0);
for (RuleModel rule : this.grammar.getRules()) {
rules.appendChild(rules.getOwnerDocument().importNode(
rule.getXml(), true));
}
// now finally save document
XmlUtils.saveXml(this.getDocument(), fileName);
}
private Node find(String what, int id) {
if (docEle == null) {
docEle = this.createDocument();
}
NodeList nl = docEle.getElementsByTagName(what);
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
// get the shape element
Element el = (Element) nl.item(i);
if (Integer.parseInt(el.getAttribute("id")) == id) {
return el;
}
}
}
return null;
}
public void addShape(ShapeModel model) {
Node parent = docEle.getElementsByTagName("shapes").item(0);
parent.appendChild(parent.getOwnerDocument().importNode(model.getXml(),
true));
}
public void removeShape(ShapeModel model) {
Node shape = this.find("shape", model.getId());
if (shape != null) {
Node parent = shape.getParentNode();
parent.removeChild(shape);
// now finally save document
XmlUtils.saveXml(this.getDocument(), this.grammar.getCurrentFileName());
}
}
public void saveShape(ShapeModel model) {
Node shape = this.find("shape", model.getId());
if (shape != null) {
Node parent = shape.getParentNode();
parent.removeChild(shape);
parent.appendChild(parent.getOwnerDocument().importNode(
model.getXml(), true));
} else {
this.addShape(model);
}
// now finally save document
XmlUtils.saveXml(this.getDocument(), this.grammar.getCurrentFileName());
}
public void addRule(RuleModel model) {
Node parent = docEle.getElementsByTagName("rules").item(0);
parent.appendChild(parent.getOwnerDocument().importNode(model.getXml(),
true));
}
public void removeRule(RuleModel model) {
Node rule = this.find("rule", model.getId());
if (rule != null) {
Node parent = rule.getParentNode();
parent.removeChild(rule);
// now finally save document
XmlUtils.saveXml(this.getDocument(), this.grammar
.getCurrentFileName());
}
}
public void saveRule(RuleModel model) {
Node shape = this.find("rule", model.getId());
if (shape != null) {
Node parent = shape.getParentNode();
parent.removeChild(shape);
parent.appendChild(parent.getOwnerDocument().importNode(
model.getXml(), true));
} else {
this.addRule(model);
}
// now finally save document
XmlUtils.saveXml(this.getDocument(), this.grammar.getCurrentFileName());
}
// helpers
protected ShapeGrammarModel getGrammar() {
return this.grammar;
}
// saving methods
}