com.vividsolutions.jtstest.testbuilder.model.HtmlWriter Maven / Gradle / Ivy
/*
* The JTS Topology Suite is a collection of Java classes that
* implement the fundamental operations required to validate a given
* geo-spatial data set to a known topological specification.
*
* Copyright (C) 2001 Vivid Solutions
*
* This library 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 library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jtstest.testbuilder.model;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.PrecisionModel;
import com.vividsolutions.jts.util.Assert;
import com.vividsolutions.jtstest.test.TestCaseList;
import com.vividsolutions.jtstest.test.Testable;
import com.vividsolutions.jtstest.testbuilder.AppStrings;
import com.vividsolutions.jtstest.testbuilder.BusyDialog;
import com.vividsolutions.jtstest.testbuilder.GeometryEditPanel;
import com.vividsolutions.jtstest.testrunner.BooleanResult;
import com.vividsolutions.jtstest.testrunner.Test;
import com.vividsolutions.jtstest.util.FileUtil;
import com.vividsolutions.jtstest.util.StringUtil;
/**
* An object that creates an .html file describing the test cases. .gif files
* are also created.
*
* @version 1.7
*/
public class HtmlWriter {
private final static int IMAGE_WIDTH = 200;
private final static int IMAGE_HEIGHT = 200;
private final static int STACK_TRACE_DEPTH = 1;
private boolean showingABwithSpatialFunction = true;
private GeometryEditPanel geometryEditPanel = new GeometryEditPanel();
private JFrame frame = new JFrame();
private File outputDirectory;
private BusyDialog busyDialog = null;
public HtmlWriter() {
geometryEditPanel.setSize(IMAGE_WIDTH, IMAGE_HEIGHT);
geometryEditPanel.setGridEnabled(false);
geometryEditPanel.setBorder(BorderFactory.createEmptyBorder());
frame.getContentPane().add(geometryEditPanel);
}
public void setShowingABwithSpatialFunction(boolean showingABwithSpatialFunction) {
this.showingABwithSpatialFunction = showingABwithSpatialFunction;
}
public void setBusyDialog(BusyDialog busyDialog) {
this.busyDialog = busyDialog;
}
private static class MapAndList {
public Map map;
public List list;
}
public void write(File outputDirectory, TestCaseList testCaseList, PrecisionModel precisionModel) throws IOException {
if (busyDialog != null) {
busyDialog.setDescription("Saving .html and .gif files");
}
Assert.isTrue(outputDirectory.isDirectory());
this.outputDirectory = outputDirectory;
MapAndList runMapAndRuns = runMapAndRuns(testCaseList);
Map runMap = runMapAndRuns.map;
List runs = runMapAndRuns.list;
createHtmlFile("contents-frame.html", indexHtml(runs, runMap, precisionModel));
createHtmlFile("index.html", testTopHtml());
int runSkey = 0;
for (Iterator i = runs.iterator(); i.hasNext(); ) {
String runDescription = (String) i.next();
runSkey++;
List testables = (List) runMap.get(runDescription);
int caseSkey = 0;
for (Iterator m = testables.iterator(); m.hasNext(); ) {
Testable testable = (Testable) m.next();
caseSkey++;
if (busyDialog != null) {
busyDialog.setDescription("Saving .html and .gif files: " + caseSkey
+ " of " + testCaseList.getList().size() + " tests");
}
createHtmlFile("Run" + runSkey + AppStrings.LABEL_TEST_CASE + caseSkey + ".html", html(testable, runSkey, caseSkey));
}
}
}
private String html(Testable testable, int runSkey, int caseSkey) throws IOException {
TestCaseEdit testCaseEdit = (TestCaseEdit) testable;
String html =
"" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.escapeHTML(testName(testCaseEdit, caseSkey)) + " " + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.escapeHTML(testName(testCaseEdit, caseSkey)) + "" + StringUtil.newLine
+ "" + StringUtil.newLine;
html += htmlForAB(testCaseEdit, runSkey, caseSkey);
html += htmlForTests(testCaseEdit, runSkey, caseSkey);
html += "" + StringUtil.newLine + "";
return html;
}
private String deleteLastTag(String html) {
if (html.lastIndexOf("<") == -1) {
return html;
}
return html.substring(0, html.lastIndexOf("<"));
}
private String deleteFirstTag(String html) {
if (html.lastIndexOf(">") == -1) {
return html;
}
return html.substring(html.indexOf(">") + 1);
}
private String htmlForTests(TestCaseEdit testCaseEdit, int runSkey, int caseSkey) throws IOException {
String html = htmlForBinaryPredicates(testCaseEdit, caseSkey);
html += htmlForSpatialFunctions(testCaseEdit, runSkey, caseSkey);
html += htmlForTopologyMethods(testCaseEdit, runSkey, caseSkey);
return html;
}
private String htmlForSpatialFunctionTest(TestCaseEdit testCaseEdit, int runSkey, int caseSkey,
String geometryOpName, String first, String second) {
String actualResultString = " ";
try {
Geometry actualResult = (Geometry) actualResult(testCaseEdit, geometryOpName,
first, second);
String filenameNoPath = "Run" + runSkey + AppStrings.LABEL_TEST_CASE + caseSkey + geometryOpName + "Actual";
if (first != null) {
filenameNoPath += first;
}
if (second != null) {
filenameNoPath += second;
}
filenameNoPath += ".gif";
actualResultString = htmlImageHtmlTextTable(filenameNoPath, "" + actualResult.toText() + "",
0);
createGifFile(filenameNoPath, testCaseEdit.getGeometry(0),
testCaseEdit.getGeometry(1), actualResult,
showingABwithSpatialFunction, IMAGE_WIDTH, IMAGE_HEIGHT);
}
catch (Exception e) {
actualResultString = "
" + StringUtil.replace(StringUtil.getStackTrace(e, STACK_TRACE_DEPTH),
"\n", "
", true) + " ";
e.printStackTrace(System.out);
}
String html
= " " + StringUtil.newLine
+ " " + geometryOpName + " " + StringUtil.newLine
+ actualResultString + StringUtil.newLine
+ " " + StringUtil.newLine;
return html;
}
private String htmlForRelateTest(TestCaseEdit testCaseEdit, int caseSkey) {
String actualValue;
try {
actualValue = insertParagraphs(testCaseEdit.getGeometry(0).relate(testCaseEdit.getGeometry(1)).toString());
}
catch (Exception e) {
actualValue = StringUtil.replace(StringUtil.getStackTrace(e, STACK_TRACE_DEPTH),
"\n", "
", true);
e.printStackTrace(System.out);
}
String html
= " " + StringUtil.newLine
+ " relate " + StringUtil.newLine
+ " " + actualValue + " " + StringUtil.newLine
+ " " + StringUtil.newLine;
return html;
}
private String insertParagraphs(String intersectionMatrix) {
StringBuffer buffer = new StringBuffer(intersectionMatrix);
buffer.insert(6, "
");
buffer.insert(3, "
");
return buffer.toString();
}
private String htmlForPredicateTest(TestCaseEdit testCaseEdit, int caseSkey,
String opName, String first, String second) {
String actualResultString;
try {
actualResultString = actualResult(testCaseEdit, opName, first, second).toString();
}
catch (Exception e) {
actualResultString = StringUtil.replace(StringUtil.getStackTrace(e, STACK_TRACE_DEPTH),
"\n", "
", true);
e.printStackTrace(System.out);
}
String html
= " " + StringUtil.newLine
+ " " + opName + " " + StringUtil.newLine
+ " " + actualResultString + " " + StringUtil.newLine
+ " " + StringUtil.newLine;
return html;
}
private Object actualResult(TestCaseEdit testCaseEdit, String opName, String first,
String second) throws Exception {
try {
Assert.isTrue((first.equalsIgnoreCase("A")) || (first.equalsIgnoreCase("B")));
Class geometryClass = Class.forName("com.vividsolutions.jts.geom.Geometry");
Geometry source = testCaseEdit.getGeometry(first.equalsIgnoreCase("A") ? 0 : 1);
Object[] target;
Class[] targetClasses;
if (second == null) {
target = new Object[]{};
targetClasses = new Class[]{};
}
else {
target = new Object[]{
testCaseEdit.getGeometry(second.equalsIgnoreCase("A") ? 0 : 1)
};
targetClasses = new Class[]{
geometryClass
};
}
Method op = geometryClass.getMethod(opName, targetClasses);
return op.invoke(source, target);
}
catch (InvocationTargetException e) {
throw (Exception) e.getTargetException();
}
}
private BooleanResult expectedPredicateResult(TestCaseEdit testCaseEdit,
String opName, String first, String second) {
if (!(testCaseEdit.getTestable() instanceof TestRunnerTestCaseAdapter)) {
return null;
}
TestRunnerTestCaseAdapter adapter = (TestRunnerTestCaseAdapter) testCaseEdit.getTestable();
com.vividsolutions.jtstest.testrunner.TestCase trTestCase = adapter.getTestRunnerTestCase();
for (Iterator i = trTestCase.getTests().iterator(); i.hasNext(); ) {
Test test = (Test) i.next();
if (test.getOperation().equalsIgnoreCase(opName)
&& test.getGeometryIndex().equalsIgnoreCase(first)
&& (test.getArgumentCount() == 0
|| ((test.getArgument(0) != null && test.getArgument(0).equalsIgnoreCase(second))
|| (test.getArgument(0) == null && second.equalsIgnoreCase("null"))))) {
return (BooleanResult) test.getExpectedResult();
}
}
return null;
}
private String htmlForAB(TestCaseEdit testCaseEdit, int runSkey, int caseSkey) throws IOException {
String wktHtml
= ""
+ (testCaseEdit.getGeometry(0) == null ? " " : testCaseEdit.getGeometry(0).toText())
+ ""
+ ""
+ ""
+ (testCaseEdit.getGeometry(1) == null ? " " : testCaseEdit.getGeometry(1).toText())
+ "";
String html = StringUtil.newLine
+ "
" + StringUtil.newLine
+ " " + StringUtil.newLine
+ htmlImageHtmlTextTable("Run" + runSkey + AppStrings.LABEL_TEST_CASE + caseSkey + ".gif", wktHtml, 0)
+ " " + StringUtil.newLine
+ "
" + StringUtil.newLine;
createGifFile("Run" + runSkey + AppStrings.LABEL_TEST_CASE + caseSkey + ".gif", testCaseEdit.getGeometry(0),
testCaseEdit.getGeometry(1), null, true, IMAGE_WIDTH, IMAGE_HEIGHT, true);
return html;
}
private String htmlImageTextTable(String imageFilename, String text, int border) {
return htmlImageHtmlTextTable(imageFilename, StringUtil.escapeHTML(text), border);
}
private String htmlImageHtmlTextTable(String imageFilename, String html, int border) {
return
" " + StringUtil.newLine
+ " " + StringUtil.newLine
+ " " + StringUtil.newLine
+ " " + StringUtil.newLine
+ html + StringUtil.newLine
+ " " + StringUtil.newLine;
}
private String testName(Testable testable, int caseSkey) {
String name = testable.getName();
if ((name == null || name.length() == 0) && testable instanceof TestCaseEdit) {
name = ((TestCaseEdit) testable).getDescription();
}
String testTag = AppStrings.LABEL_TEST_CASE + " ";
if (name == null || name.length() == 0) {
name = testTag + caseSkey;
}
else {
name = testTag + caseSkey + ": " + name;
}
return name;
}
private String runName(String runDescription, int runSkey) {
return "Run " + runSkey + ": " + runDescription;
}
private String htmlTitle(PrecisionModel precisionModel) {
String html = "Precision Model: scale=" + precisionModel.getScale()
+ StringUtil.newLine;
html = "" + html + "";
return html;
}
private void createGifFile(String filenameNoPath, Geometry a, Geometry b,
Geometry spatialFunction, boolean showingAB,
int imageWidth, int imageHeight) throws FileNotFoundException, IOException {
createGifFile(filenameNoPath, a, b, spatialFunction, showingAB, imageWidth, imageHeight, false);
}
/*
private void createGifFile(String filenameNoPath, Geometry a, Geometry b,
Geometry spatialFunction, boolean showingAB,
int imageWidth, int imageHeight, boolean zoomToFullExtent) throws FileNotFoundException,
IOException {
GeometryBuilder builderA = a != null ? GeometryBuilder.create(a) : null;
GeometryBuilder builderB = b != null ? GeometryBuilder.create(b) : null;
GeometryBuilder builderSpatialFunction = spatialFunction != null ? GeometryBuilder.create(spatialFunction) : null;
createGifFile(filenameNoPath, builderA, builderB, builderSpatialFunction,
showingAB, imageWidth, imageHeight, zoomToFullExtent);
}
*/
private void createGifFile(String filenameNoPath, Geometry a,
Geometry b,
Geometry result,
boolean showingAB,
int imageWidth, int imageHeight, boolean zoomToFullExtent) throws FileNotFoundException,
IOException {
TestBuilderModel tbModel = new TestBuilderModel();
TestCaseEdit tc = new TestCaseEdit(new Geometry[]{ a, b });
tc.setResult(result);
tbModel.getGeometryEditModel().setTestCase(tc);
geometryEditPanel.setModel(tbModel);
if (zoomToFullExtent) {
geometryEditPanel.zoomToFullExtent();
}
geometryEditPanel.setShowingResult(result != null);
geometryEditPanel.setShowingGeometryA(a != null && showingAB);
geometryEditPanel.setShowingGeometryB(b != null && showingAB);
String filenameWithPath = outputDirectory.getPath() + "\\" + filenameNoPath;
Image image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_4BYTE_ABGR);
geometryEditPanel.paint(image.getGraphics());
/*
// disabled - should be replaced with PNG output
FileOutputStream outputStream = new FileOutputStream(filenameWithPath,
false);
GifEncoder gifEncoder = new GifEncoder(image, outputStream);
gifEncoder.setDimensions(imageWidth, imageHeight);
gifEncoder.encode();
outputStream.flush();
outputStream.close();
*/
}
private void createHtmlFile(String filename, String html) throws IOException {
String pathname = outputDirectory.getPath() + "\\" + filename;
FileUtil.setContents(pathname, html);
}
private MapAndList runMapAndRuns(TestCaseList testCaseList) {
Map runMap = new TreeMap();
List runs = new ArrayList();
for (Iterator i = testCaseList.getList().iterator(); i.hasNext(); ) {
TestCaseEdit testCaseEdit = (TestCaseEdit) i.next();
Testable testable = testCaseEdit.getTestable();
if (testable instanceof TestRunnerTestCaseAdapter) {
com.vividsolutions.jtstest.testrunner.TestCase testRunnerTestCase = ((TestRunnerTestCaseAdapter) testable).getTestRunnerTestCase();
String runDescription = testRunnerTestCase.getTestRun().getTestFile().getName();
runDescription = runDescription.indexOf(".") > -1 ? runDescription.substring(0, runDescription.indexOf(".")) : runDescription;
addToListMapAndList(runDescription, testCaseEdit, runMap, runs);
}
else {
addToListMapAndList("Other", testCaseEdit, runMap, runs);
}
}
MapAndList runMapAndRuns = new MapAndList();
runMapAndRuns.map = runMap;
runMapAndRuns.list = runs;
return runMapAndRuns;
}
private void addToListMapAndList(String key, Object valueItem, Map stringToList, List keyList) {
if (stringToList.containsKey(key)) {
List value = (List) stringToList.get(key);
value.add(valueItem);
}
else {
List value = new ArrayList();
value.add(valueItem);
stringToList.put(key, value);
keyList.add(key);
}
}
private String indexHtml(List runs, Map runMap, PrecisionModel precisionModel) {
String html
= "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "JTS Test Suite Index " + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "JTS Validation Suite
" + StringUtil.newLine
+ htmlTitle(precisionModel)
+ "" + StringUtil.newLine
+ "
" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine;
return html;
}
private String testTopHtml() {
return
"" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "JTS Validation Suite" + StringUtil.newLine
+ " " + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "Frame Alert
" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "" + StringUtil.newLine
+ "This site is designed to be viewed using frames. " + StringUtil.newLine
+ "If you see this message, you are using a non-frame-capable web client." + StringUtil.newLine
+ "" + StringUtil.newLine;
}
private String htmlForBinaryPredicates(TestCaseEdit testCaseEdit, int caseSkey) {
String html = "";
if (testCaseEdit.getGeometry(1) != null) {
html += htmlForRelateTest(testCaseEdit, caseSkey);
html += htmlForPredicateTest(testCaseEdit, caseSkey, "equals", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "disjoint", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "intersects", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "touches", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "crosses", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "within", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "contains", "A", "B");
html += htmlForPredicateTest(testCaseEdit, caseSkey, "overlaps", "A", "B");
html = "
Binary Predicates
" + StringUtil.newLine
+ "" + StringUtil.newLine
+ html
+ "
" + StringUtil.newLine;
}
return html;
}
private String htmlForSpatialFunctions(TestCaseEdit testCaseEdit, int runSkey, int caseSkey) {
if (testCaseEdit.getExpectedConvexHull() == null
&& testCaseEdit.getExpectedIntersection() == null
&& testCaseEdit.getExpectedUnion() == null
&& testCaseEdit.getExpectedDifference() == null
&& testCaseEdit.getExpectedSymDifference() == null) {
return "";
}
String html = "";
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "convexHull", "A", null);
if (testCaseEdit.getGeometry(1) != null) {
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "intersection", "A", "B");
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "union", "A", "B");
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "difference", "A", "B");
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "symDifference", "A", "B");
}
html = "Spatial Analysis Methods
" + StringUtil.newLine
+ "" + StringUtil.newLine
+ html
+ "
" + StringUtil.newLine;
return html;
}
private String htmlForTopologyMethods(TestCaseEdit testCaseEdit, int runSkey, int caseSkey) {
boolean isSimpleSpecified = expectedPredicateResult(testCaseEdit, "isSimple", "A", null) != null;
boolean getBoundarySpecified = testCaseEdit.getExpectedBoundary() != null;
boolean isValidSpecified = expectedPredicateResult(testCaseEdit, "isValid", "A", null) != null;
if (! isSimpleSpecified && ! getBoundarySpecified && ! isValidSpecified) {
return "";
}
String html = "";
if (isSimpleSpecified) {
html += htmlForPredicateTest(testCaseEdit, caseSkey, "isSimple", "A", null);
}
if (isValidSpecified) {
html += htmlForPredicateTest(testCaseEdit, caseSkey, "isValid", "A", null);
}
if (getBoundarySpecified) {
html += htmlForSpatialFunctionTest(testCaseEdit, runSkey, caseSkey, "getBoundary", "A", null);
}
html = "Topology Methods (on A)
" + StringUtil.newLine
+ "" + StringUtil.newLine
+ html
+ "
" + StringUtil.newLine;
return html;
}
}