package Services;
import Controllers.Obstruction;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
public class XMLObstructionService {
// need String because Obstruction class doesn't store obstruction name
public void exportObstruction(Obstruction obstruction, String passedFilename)
throws ParserConfigurationException, TransformerException,
SAXException, IOException {
if (passedFilename.equals("")) {
// creates file name that will be used to store exported obstructions
String filename = this.getDatedFileName() + "_obstruction_exports.xml";
File file = new File(filename);
// checks to see if an obstruction exporting file already exists for
// today
if (file.exists() == true) {
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// parses the xml document in
Document xmlDoc = db.parse(file);
// gets the root element in the parsed file
Element root = xmlDoc.getDocumentElement();
root.normalize();
// Build XML elements and Text Nodes
Element main = xmlDoc.createElement("obstruction");
Element obname = xmlDoc.createElement("obstruction_name");
Element obwidth = xmlDoc.createElement("obstruction_width");
Element obheight = xmlDoc.createElement("obstruction_height");
Element oblength = xmlDoc.createElement("obstruction_length");
Text obnametext = xmlDoc.createTextNode(obstruction.getName());
Text obwidthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getWidth()));
Text obheighttext = xmlDoc.createTextNode(Double
.toString(obstruction.getHeight()));
Text oblengthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getLength()));
obname.appendChild(obnametext);
obwidth.appendChild(obwidthtext);
obheight.appendChild(obheighttext);
oblength.appendChild(oblengthtext);
main.appendChild(obname);
main.appendChild(obwidth);
main.appendChild(obheight);
main.appendChild(oblength);
root.appendChild(main);
// used to output the xml structure into a file
TransformerFactory transformerfac = TransformerFactory
.newInstance();
Transformer transformer = transformerfac.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(xmlDoc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
} else {
// else called if the document doesn't already exist
// creates a new document
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document xmlDoc = db.newDocument();
// Build XML elements and Text Nodes
Element root = xmlDoc.createElement("obstructions");
Element main = xmlDoc.createElement("obstruction");
Element obname = xmlDoc.createElement("obstruction_name");
Element obwidth = xmlDoc.createElement("obstruction_width");
Element obheight = xmlDoc.createElement("obstruction_height");
Element oblength = xmlDoc.createElement("obstruction_length");
Text obnametext = xmlDoc.createTextNode(obstruction.getName());
Text obwidthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getWidth()));
Text obheighttext = xmlDoc.createTextNode(Double
.toString(obstruction.getHeight()));
Text oblengthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getLength()));
obname.appendChild(obnametext);
obwidth.appendChild(obwidthtext);
obheight.appendChild(obheighttext);
oblength.appendChild(oblengthtext);
main.appendChild(obname);
main.appendChild(obwidth);
main.appendChild(obheight);
main.appendChild(oblength);
root.appendChild(main);
xmlDoc.appendChild(root);
// used to output the xml structure into a file
TransformerFactory transformerfac = TransformerFactory
.newInstance();
Transformer transformer = transformerfac.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(xmlDoc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
}
} else { // append the obstruction to the passedFilename.
File file = new File(passedFilename);
if (file.exists() == true) {
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// parses the xml document in
Document xmlDoc = db.parse(file);
// gets the root element in the parsed file
Element root = xmlDoc.getDocumentElement();
root.normalize();
// Build XML elements and Text Nodes
Element main = xmlDoc.createElement("obstruction");
Element obname = xmlDoc.createElement("obstruction_name");
Element obwidth = xmlDoc.createElement("obstruction_width");
Element obheight = xmlDoc.createElement("obstruction_height");
Element oblength = xmlDoc.createElement("obstruction_length");
Text obnametext = xmlDoc.createTextNode(obstruction.getName());
Text obwidthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getWidth()));
Text obheighttext = xmlDoc.createTextNode(Double
.toString(obstruction.getHeight()));
Text oblengthtext = xmlDoc.createTextNode(Double
.toString(obstruction.getLength()));
obname.appendChild(obnametext);
obwidth.appendChild(obwidthtext);
obheight.appendChild(obheighttext);
oblength.appendChild(oblengthtext);
main.appendChild(obname);
main.appendChild(obwidth);
main.appendChild(obheight);
main.appendChild(oblength);
root.appendChild(main);
// used to output the xml structure into a file
TransformerFactory transformerfac = TransformerFactory
.newInstance();
Transformer transformer = transformerfac.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(xmlDoc);
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
}
}
}
/* returns todays date in string form - used for date-specific import/export files*/
public String getDatedFileName() {
// gets date in correct format
SimpleDateFormat sdfdate = new SimpleDateFormat("dd-MM-yyyy");
Date date = new Date();
String today = sdfdate.format(date);
return today;
}
// Imports obstructions from a given file
public ArrayList<Obstruction> importObstructions(String filename)
throws ParserConfigurationException, SAXException, IOException {
// validate the file being imported from
// parse an XML document into a DOM tree
DocumentBuilder parser = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document document = parser.parse(new File(filename));
// create a SchemaFactory capable of understanding WXS schemas
SchemaFactory factory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// load a WXS schema, represented by a Schema instance
StreamSource schemaFile = new StreamSource(new File("obstruction_XSD.xsd"));
Schema schema = factory.newSchema(schemaFile);
// create a Validator instance, which can be used to validate an
// instance document
Validator validator = (Validator) schema.newValidator();
// validate the DOM tree
validator.validate(new DOMSource(document));
// ArrayLists used in method
ArrayList<Obstruction> obstructions = new ArrayList<Obstruction>();
ArrayList<String> parseNames = new ArrayList<String>();
ArrayList<String> parseWidth = new ArrayList<String>();
ArrayList<String> parseHeight = new ArrayList<String>();
ArrayList<String> parseLength = new ArrayList<String>();
// Parsing XML file in
File file = new File(filename);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
// creating nodes for each obstruction
NodeList nodeList = doc.getElementsByTagName("obstruction");
// adds each nodes value to an array which is used to populate the
// obstructions ArrayList later on
for (int j = 0; j < nodeList.getLength(); j++) {
Node node = nodeList.item(j);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element) node;
// getting name of obstruction
NodeList nmeElementList = elem
.getElementsByTagName("obstruction_name");
Element nameElement = (Element) nmeElementList.item(0);
NodeList name = nameElement.getChildNodes();
parseNames.add(((Node) name.item(0)).getNodeValue());
// getting width of obstruction
NodeList widthElementList = elem
.getElementsByTagName("obstruction_width");
Element widthElement = (Element) widthElementList.item(0);
NodeList width = widthElement.getChildNodes();
parseWidth.add(((Node) width.item(0)).getNodeValue());
// getting height of obstruction
NodeList heightElementList = elem
.getElementsByTagName("obstruction_height");
Element heightElement = (Element) heightElementList.item(0);
NodeList height = heightElement.getChildNodes();
parseHeight.add(((Node) height.item(0)).getNodeValue());
// getting length of obstruction
NodeList lengthElementList = elem
.getElementsByTagName("obstruction_length");
Element lengthElement = (Element) lengthElementList.item(0);
NodeList length = lengthElement.getChildNodes();
parseLength.add(((Node) length.item(0)).getNodeValue());
}
}
// creates obstructions based on the information that was read from the
// file - dummy values were used for the values that weren't read in
// from the file but are needed for the Obstruction constructor.
for (int i = 0; i < nodeList.getLength(); i++) {
String name = parseNames.get(i);
Double width = Double.parseDouble(parseWidth.get(i));
Double height = Double.parseDouble(parseHeight.get(i));
Double length = Double.parseDouble(parseLength.get(i));
Double dummy1 = 0.0;
Double dummy2 = 0.0;
obstructions.add(new Obstruction(name, width, height, length,
dummy1, dummy2));
}
return obstructions;
}
}