/*
* #%~
* Test Framework for Overture
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.test.util;
import java.io.File;
import java.util.List;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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 org.overture.test.framework.Properties;
import org.overture.test.framework.results.IMessage;
import org.overture.test.framework.results.Message;
import org.overture.test.framework.results.Result;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XmlResultReaderWriter<R>
{
public interface IResultStore<T>
{
void encodeResult(T result, Document doc, Element resultElement);
T decodeResult(Node node);
}
private File file;
private Result<R> result = null;
private String type;
private IResultStore<R> resultStore;
public XmlResultReaderWriter()
{
}
public XmlResultReaderWriter(File file, IResultStore<R> store)
{
this.file = file;
this.resultStore = store;
}
// public XmlResultReaderWriter(String path)
// {
// this(new File(path));
// }
public void setResult(String type, Result<R> result, IResultStore<R> store)
{
this.type = type;
this.result = result;
this.resultStore = store;
}
public void saveInXml() throws ParserConfigurationException,
TransformerException
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("testResult");
doc.appendChild(rootElement);
rootElement.setAttribute("type", type);
createWarningsAndErrors(doc, rootElement);
String oldLineSeparator = System.getProperty("line.separator");
if (Properties.forceUnixLineEndings)
{
// Output using LF line endings (UNIX-style),
// but only for this file.
oldLineSeparator = System.getProperty("line.separator");
System.setProperty("line.separator", "\n");
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
if (Properties.forceUnixLineEndings)
{
// Restore line endings
System.setProperty("line.separator", oldLineSeparator);
}
}
private void createWarningsAndErrors(Document doc, Element rootElement)
{
List<IMessage> warnings = getResult().warnings;
List<IMessage> errors = getResult().errors;
if (warnings != null)
{
for (IMessage warning : warnings)
{
Element message = doc.createElement("message");
message.setAttribute("messageType", "warning");
message.setAttribute("resource", warning.getResource());
message.setAttribute("number", new Integer(warning.getNumber()).toString());
message.setAttribute("message", warning.getMessage());
message.setAttribute("column", new Integer(warning.getCol()).toString());
message.setAttribute("line", new Integer(warning.getLine()).toString());
rootElement.appendChild(message);
}
}
if (errors != null)
{
for (IMessage warning : errors)
{
Element message = doc.createElement("message");
message.setAttribute("messageType", "error");
message.setAttribute("resource", warning.getResource());
message.setAttribute("number", new Integer(warning.getNumber()).toString());
message.setAttribute("message", warning.getMessage());
message.setAttribute("column", new Integer(warning.getCol()).toString());
message.setAttribute("line", new Integer(warning.getLine()).toString());
rootElement.appendChild(message);
}
}
Element resultElement = doc.createElement("result");
resultStore.encodeResult(result.result, doc, resultElement);
rootElement.appendChild(resultElement);
}
public boolean loadFromXml()
{
// File resultFile = new File(file.getAbsoluteFile()+ ".result");
List<IMessage> warnings = new Vector<IMessage>();
List<IMessage> errors = new Vector<IMessage>();
R readResult = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try
{
db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeLst = doc.getElementsByTagName("message");
for (int i = 0; i < nodeLst.getLength(); i++)
{
Node node = nodeLst.item(i);
String nodeType = node.getAttributes().getNamedItem("messageType").getNodeValue();
if (nodeType.equals("error"))
{
convertNodeToMessage(errors, node);
} else if (nodeType.equals("warning"))
{
convertNodeToMessage(warnings, node);
}
}
for (int i = 0; i < doc.getDocumentElement().getChildNodes().getLength(); i++)
{
Node node = doc.getDocumentElement().getChildNodes().item(i);
if (node.getNodeName() != null
&& node.getNodeName().equals("result"))
{
node.normalize();
readResult = resultStore.decodeResult(node);
}
// System.out.println(node);
}
// doc.getDocumentElement().getChildNodes().getElementsByTagName("result")
String type = doc.getDocumentElement().getAttributes().getNamedItem("type").getNodeValue();
setResult(type, new Result<R>(readResult, warnings, errors));
} catch (Exception e)
{
return false;
}
return true;
}
private void convertNodeToMessage(List<IMessage> set, Node node)
{
NamedNodeMap nnm = node.getAttributes();
String resource = nnm.getNamedItem("resource").getNodeValue();
IMessage m = new Message(resource, Integer.parseInt(nnm.getNamedItem("number").getNodeValue()), Integer.parseInt(nnm.getNamedItem("line").getNodeValue()), Integer.parseInt(nnm.getNamedItem("column").getNodeValue()), nnm.getNamedItem("message").getNodeValue());
set.add(m);
}
public Result<R> getResult()
{
return result;
}
public void setResult(String type, Result<R> result)
{
this.result = result;
this.type = type;
}
public List<IMessage> getWarnings()
{
if (result != null)
{
return result.warnings;
}
return null;
}
public List<IMessage> getErrors()
{
if (result != null)
{
return result.errors;
}
return null;
}
}