/**
* JBoss, Home of Professional Open Source
* Copyright ${year}, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.arquillian.rusheye.oneoff;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.arquillian.rusheye.suite.ComparisonResult;
/**
* @author <a href="mailto:ptisnovs@redhat.com">Pavel Tisnovsky</a>
* @version $Revision$
*/
public class XmlWriter {
private static final String XML_FILE_NAME = "results.xml";
private BufferedWriter writer = null;
public XmlWriter(File outputDirectory) throws IOException {
this.writer = createXmlFile(outputDirectory);
printXmlHeader();
}
private BufferedWriter createXmlFile(File outputDirectory) throws IOException {
return outputDirectory == null ? null : new BufferedWriter(new FileWriter(new File(outputDirectory,
XML_FILE_NAME)));
}
public void printXmlHeader() throws IOException {
if (this.writer != null) {
this.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
this.println("<visual-suite-result>");
}
}
public void printXmlFooter() throws IOException {
if (this.writer != null) {
this.println("</visual-suite-result>");
}
}
public void close() throws IOException {
if (this.writer != null) {
this.writer.close();
}
}
private void print(String format, Object... o) throws IOException {
this.writer.write(String.format(format, o));
}
private void println(String format, Object... o) throws IOException {
print(format, o);
this.writer.write("\n");
}
public void printResultForOneImage(OneOffConfiguration configuration, String imageFileName,
BufferedImage[] sourceImages, ComparisonResult comparisonResult) throws IOException {
String dirName = imageFileName.substring(0, imageFileName.lastIndexOf('.'));
printComparisonResult(comparisonResult, dirName);
printPerception(comparisonResult);
this.println(" </pattern>");
this.println(" </test>");
createAndFillResultDirectory(configuration, sourceImages, comparisonResult, dirName);
}
private void printComparisonResult(ComparisonResult comparisonResult, String dirName) throws IOException {
boolean equalImages = comparisonResult.isEqualsImages();
String result = equalImages ? "same" : "different";
this.println(" <test id=\"%s\">", dirName);
this.println(" <pattern id=\"%s\" result=\"%s\">", dirName, result);
if (equalImages) {
this.println(" <output/>");
} else {
this.println(" <output>%s</output>", dirName);
}
}
private void printPerception(ComparisonResult cr) throws IOException {
this.println(" <perception>");
this.println(" <area width=\"%d\" height=\"%d\" />", cr.getArea().getWidth(), cr.getArea()
.getHeight());
this.println(" <rectangle>");
this.println(" <vertex x=\"%d\" y=\"%d\" />", cr.getRectangles().get(0).getMin().x, cr
.getRectangles().get(0).getMin().y);
this.println(" <vertex x=\"%d\" y=\"%d\" />", cr.getRectangles().get(0).getMax().x, cr
.getRectangles().get(0).getMax().y);
this.println(" </rectangle>");
this.println(" <totalPixels>%d</totalPixels>", cr.getTotalPixels());
this.println(" <maskedPixels>%d</maskedPixels>", cr.getMaskedPixels());
this.println(" <perceptibleDifferentPixels>%d</perceptibleDifferentPixels>",
cr.getPerceptibleDiffs());
this.println(" <globalDifferentPixels>%d</globalDifferentPixels>", cr.getDifferentPixels());
this.println(" <unperceptibleDifferentPixels>%d</unperceptibleDifferentPixels>",
cr.getSmallDifferences());
this.println(" <samePixels>%d</samePixels>", cr.getEqualPixels());
this.println(" </perception>");
}
private void createAndFillResultDirectory(OneOffConfiguration configuration, BufferedImage[] sourceImages,
ComparisonResult comparisonResult, String dirName) throws IOException {
File newDir = new File(configuration.getHtmlOutputDirectory(), dirName);
Log.logProcess("creating directory %s", newDir.getAbsolutePath());
newDir.mkdir();
if (!comparisonResult.isEqualsImages()) {
Log.logProcess("writing source and diff images to directory %s", dirName);
// ImageUtils.writeImage(sourceImages[0], newDir, "source1.png");
// ImageUtils.writeImage(sourceImages[1], newDir, "source2.png");
// ImageUtils.writeImage(comparisonResult.getDiffImage(), newDir, "diff.png");
} else {
Log.logProcess("writing source image to directory %s", dirName);
// ImageUtils.writeImage(sourceImages[0], newDir, "source1.png");
}
createHtmlFile(newDir, comparisonResult);
}
private void createHtmlFile(File newDir, ComparisonResult cr) throws IOException {
String templateName = cr.isEqualsImages() ? "template_same_images.html" : "template_different_images.html";
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(newDir, "result.html")));
BufferedReader template = new BufferedReader(new FileReader(templateName));
String line;
while ((line = template.readLine()) != null) {
writer.write(replacePlaceholders(cr, newDir, line));
}
template.close();
writer.close();
}
private String replacePlaceholders(ComparisonResult cr, File newDir, String line) {
StringBuffer out = new StringBuffer();
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
matcher.appendReplacement(out, getPlaceholderValue(cr, matcher.group(1)));
}
matcher.appendTail(out);
return out.toString() + "\n";
}
private String getPlaceholderValue(ComparisonResult cr, String group) {
Method method;
try {
// call appropriate getter
method = cr.getClass().getDeclaredMethod("get" + group, (Class<?>[]) null);
return "" + method.invoke(cr, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
return group;
}
}