XmlExportVisitor.java
package com.example.graphics.visitor;
import com.example.graphics.model.Circle;
import com.example.graphics.model.Line;
import com.example.graphics.model.Rectangle;
import com.example.graphics.model.Triangle;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.StringWriter;
/**
* Visitor implementation that exports shapes to XML format.
* This is an implementation of the Visitor pattern.
*/
public class XmlExportVisitor implements ShapeVisitor {
private Document document;
private Element rootElement;
/**
* Constructor initializes the XML document
*/
public XmlExportVisitor() {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Root elements
document = docBuilder.newDocument();
rootElement = document.createElement("shapes");
document.appendChild(rootElement);
} catch (ParserConfigurationException e) {
throw new RuntimeException("Error initializing XML document", e);
}
}
@Override
public void visit(Circle circle) {
Element circleElement = document.createElement("circle");
circleElement.setAttribute("x", String.valueOf(circle.getX()));
circleElement.setAttribute("y", String.valueOf(circle.getY()));
circleElement.setAttribute("radius", String.valueOf(circle.getRadius()));
rootElement.appendChild(circleElement);
}
@Override
public void visit(Rectangle rectangle) {
Element rectElement = document.createElement("rectangle");
rectElement.setAttribute("x", String.valueOf(rectangle.getX()));
rectElement.setAttribute("y", String.valueOf(rectangle.getY()));
rectElement.setAttribute("width", String.valueOf(rectangle.getWidth()));
rectElement.setAttribute("height", String.valueOf(rectangle.getHeight()));
rootElement.appendChild(rectElement);
}
@Override
public void visit(Line line) {
Element lineElement = document.createElement("line");
lineElement.setAttribute("x1", String.valueOf(line.getX1()));
lineElement.setAttribute("y1", String.valueOf(line.getY1()));
lineElement.setAttribute("x2", String.valueOf(line.getX2()));
lineElement.setAttribute("y2", String.valueOf(line.getY2()));
rootElement.appendChild(lineElement);
}
@Override
public void visit(Triangle triangle) {
Element triangleElement = document.createElement("triangle");
triangleElement.setAttribute("x1", String.valueOf(triangle.getX1()));
triangleElement.setAttribute("y1", String.valueOf(triangle.getY1()));
triangleElement.setAttribute("x2", String.valueOf(triangle.getX2()));
triangleElement.setAttribute("y2", String.valueOf(triangle.getY2()));
triangleElement.setAttribute("x3", String.valueOf(triangle.getX3()));
triangleElement.setAttribute("y3", String.valueOf(triangle.getY3()));
rootElement.appendChild(triangleElement);
}
/**
* Get the XML representation of all visited shapes
* @return an XML string representing all shapes
*/
public String getXmlOutput() {
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));
return writer.toString();
} catch (TransformerException e) {
throw new RuntimeException("Error transforming XML document", e);
}
}
/**
* Clear all shapes and reset the visitor
*/
public void clear() {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Root elements
document = docBuilder.newDocument();
rootElement = document.createElement("shapes");
document.appendChild(rootElement);
} catch (ParserConfigurationException e) {
throw new RuntimeException("Error resetting XML document", e);
}
}
}