diff options
Diffstat (limited to 'test/java/org/apache')
14 files changed, 643 insertions, 94 deletions
diff --git a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java new file mode 100644 index 000000000..9261e6d84 --- /dev/null +++ b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.image.loader.batik; + +import java.io.File; + +import junit.framework.TestCase; + +import org.apache.xmlgraphics.image.loader.Image; +import org.apache.xmlgraphics.image.loader.ImageFlavor; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.impl.ImageRendered; +import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; +import org.apache.xmlgraphics.image.writer.ImageWriterUtil; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; + +/** + * Tests for bundled ImageLoader implementations. + */ +public class ImageLoaderTestCase extends TestCase { + + private static final File DEBUG_TARGET_DIR = null; //new File("D:/"); + + private FopFactory fopFactory; + + public ImageLoaderTestCase(String name) { + super(name); + fopFactory = FopFactory.newInstance(); + fopFactory.setSourceResolution(72); + fopFactory.setTargetResolution(300); + } + + public void testSVG() throws Exception { + String uri = "test/resources/images/img-w-size.svg"; + + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + + ImageManager manager = fopFactory.getImageManager(); + ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); + assertNotNull("ImageInfo must not be null", info); + + Image img = manager.getImage(info, ImageFlavor.XML_DOM, + userAgent.getImageSessionContext()); + assertNotNull("Image must not be null", img); + assertEquals(ImageFlavor.XML_DOM, img.getFlavor()); + ImageXMLDOM imgDom = (ImageXMLDOM)img; + assertNotNull(imgDom.getDocument()); + assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace()); + info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image + assertEquals(16000, info.getSize().getWidthMpt()); + assertEquals(16000, info.getSize().getHeightMpt()); + + img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, + userAgent.getImageSessionContext()); + assertNotNull("Image must not be null", img); + assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); + ImageRendered imgRed = (ImageRendered)img; + assertNotNull(imgRed.getRenderedImage()); + if (DEBUG_TARGET_DIR != null) { + ImageWriterUtil.saveAsPNG(imgRed.getRenderedImage(), + (int)userAgent.getTargetResolution(), + new File(DEBUG_TARGET_DIR, "out.svg.png")); + } + assertEquals(67, imgRed.getRenderedImage().getWidth()); + assertEquals(67, imgRed.getRenderedImage().getHeight()); + info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image + assertEquals(16000, info.getSize().getWidthMpt()); + assertEquals(16000, info.getSize().getHeightMpt()); + } + + public void testWMF() throws Exception { + String uri = "test/resources/images/testChart.wmf"; + + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + + ImageManager manager = fopFactory.getImageManager(); + ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); + assertNotNull("ImageInfo must not be null", info); + + Image img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE, + userAgent.getImageSessionContext()); + assertNotNull("Image must not be null", img); + assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor()); + ImageRendered imgRed = (ImageRendered)img; + assertNotNull(imgRed.getRenderedImage()); + if (DEBUG_TARGET_DIR != null) { + ImageWriterUtil.saveAsPNG(imgRed.getRenderedImage(), + (int)userAgent.getTargetResolution(), + new File(DEBUG_TARGET_DIR, "out.wmf.png")); + } + assertEquals(3300, imgRed.getRenderedImage().getWidth()); + assertEquals(2550, imgRed.getRenderedImage().getHeight()); + info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image + assertEquals(792000, info.getSize().getWidthMpt()); + assertEquals(612000, info.getSize().getHeightMpt()); + } + +} diff --git a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java new file mode 100644 index 000000000..b14dd1fb8 --- /dev/null +++ b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.image.loader.batik; + +import java.io.IOException; + +import junit.framework.TestCase; + +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageInfo; +import org.apache.xmlgraphics.image.loader.ImageManager; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.image.loader.batik.ImageWMF; + +/** + * Tests for bundled image preloader implementations. + */ +public class ImagePreloaderTestCase extends TestCase { + + private FopFactory fopFactory; + + public ImagePreloaderTestCase(String name) { + super(name); + fopFactory = FopFactory.newInstance(); + fopFactory.setSourceResolution(72); + fopFactory.setTargetResolution(300); + } + + public void testSVG() throws Exception { + String uri = "test/resources/images/img-w-size.svg"; + + checkSVGFile(uri); + } + + public void testSVGZ() throws Exception { + String uri = "test/resources/images/img-w-size.svgz"; + + checkSVGFile(uri); + } + + private void checkSVGFile(String uri) throws ImageException, IOException { + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + + ImageManager manager = fopFactory.getImageManager(); + ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); + assertNotNull("ImageInfo must not be null", info); + assertEquals(MimeConstants.MIME_SVG, info.getMimeType()); + assertEquals(uri, info.getOriginalURI()); + assertEquals(16, info.getSize().getWidthPx()); + assertEquals(16, info.getSize().getHeightPx()); + assertEquals(userAgent.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); + assertEquals(16000, info.getSize().getWidthMpt()); + assertEquals(16000, info.getSize().getHeightMpt()); + } + + public void testSVGNoSize() throws Exception { + String uri = "test/resources/images/img.svg"; + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + + ImageManager manager = fopFactory.getImageManager(); + ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); + assertNotNull("ImageInfo must not be null", info); + assertEquals(MimeConstants.MIME_SVG, info.getMimeType()); + assertEquals(uri, info.getOriginalURI()); + assertEquals(100, info.getSize().getWidthPx()); //100 = default viewport size + assertEquals(100, info.getSize().getHeightPx()); + assertEquals(userAgent.getSourceResolution(), info.getSize().getDpiHorizontal(), 0.1); + assertEquals(100000, info.getSize().getWidthMpt()); + assertEquals(100000, info.getSize().getHeightMpt()); + } + + public void testWMF() throws Exception { + String uri = "test/resources/images/testChart.wmf"; + + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + + ImageManager manager = fopFactory.getImageManager(); + ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext()); + assertNotNull("ImageInfo must not be null", info); + assertEquals(ImageWMF.MIME_WMF, info.getMimeType()); + assertEquals(uri, info.getOriginalURI()); + assertEquals(27940, info.getSize().getWidthPx()); + assertEquals(21590, info.getSize().getHeightPx()); + assertEquals(2540, info.getSize().getDpiHorizontal(), 0.1); + assertEquals(792000, info.getSize().getWidthMpt()); + assertEquals(612000, info.getSize().getHeightMpt()); + } + +} diff --git a/test/java/org/apache/fop/memory/MemoryEater.java b/test/java/org/apache/fop/memory/MemoryEater.java index 555ddf19c..1bea0f123 100644 --- a/test/java/org/apache/fop/memory/MemoryEater.java +++ b/test/java/org/apache/fop/memory/MemoryEater.java @@ -36,6 +36,7 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.output.NullOutputStream; +import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; @@ -63,7 +64,9 @@ public class MemoryEater { transformer.setParameter("repeats", new Integer(replicatorRepeats)); OutputStream out = new NullOutputStream(); //write to /dev/nul - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); + FOUserAgent userAgent = fopFactory.newFOUserAgent(); + userAgent.setBaseURL(foFile.getParentFile().toURL().toExternalForm()); + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out); Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); diff --git a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java index 54ea5b571..881a8abd2 100644 --- a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java +++ b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java @@ -89,20 +89,6 @@ public class PDFAConformanceTestCase extends BasePDFTestCase { } /** - * Test exception when PDF/A-1 is enabled and an EPS is used. - * @throws Exception if the test fails - */ - public void testEPSUsage() throws Exception { - File foFile = new File(foBaseDir, "with-eps.fo"); - try { - convertFO(foFile, getUserAgent(), dumpPDF); - fail("Expected PDFConformanceException. PDF/A-1 does not allow PostScript XObjects."); - } catch (PDFConformanceException e) { - //Good! - } - } - - /** * Test exception when PDF/A-1 is enabled and images. * @throws Exception if the test fails */ diff --git a/test/java/org/apache/fop/threading/FOPTestbed.java b/test/java/org/apache/fop/threading/FOPTestbed.java index e5cdaaf74..875c04617 100644 --- a/test/java/org/apache/fop/threading/FOPTestbed.java +++ b/test/java/org/apache/fop/threading/FOPTestbed.java @@ -19,12 +19,12 @@ package org.apache.fop.threading; -import java.util.List; -import java.util.Iterator; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.text.DecimalFormat; +import java.util.Iterator; +import java.util.List; import javax.xml.transform.Source; import javax.xml.transform.Templates; @@ -40,35 +40,45 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.container.ContainerUtil; import org.apache.avalon.framework.logger.AbstractLogEnabled; -import org.apache.avalon.framework.logger.Logger; import org.apache.commons.io.IOUtils; +/** + * Testbed for multi-threading tests. The class can run a configurable set of task a number of + * times in a configurable number of threads to easily reproduce multi-threading issues. + */ public class FOPTestbed extends AbstractLogEnabled implements Configurable, Initializable { private int repeat; - private List tasks = new java.util.ArrayList(); + private List taskList = new java.util.ArrayList(); private int threads; private File outputDir; private Configuration fopCfg; + private FOProcessor foprocessor; private int counter = 0; + /** {@inheritDoc} */ public void configure(Configuration configuration) throws ConfigurationException { this.threads = configuration.getChild("threads").getValueAsInteger(10); this.outputDir = new File(configuration.getChild("output-dir").getValue()); Configuration tasks = configuration.getChild("tasks"); this.repeat = tasks.getAttributeAsInteger("repeat", 1); Configuration[] entries = tasks.getChildren("task"); - for (int i=0; i<entries.length; i++) { - this.tasks.add(new TaskDef(entries[i])); + for (int i = 0; i < entries.length; i++) { + this.taskList.add(new TaskDef(entries[i])); } this.fopCfg = configuration.getChild("foprocessor"); } + /** {@inheritDoc} */ public void initialize() throws Exception { + this.foprocessor = createFOProcessor(); } + /** + * Starts the stress test. + */ public void doStressTest() { getLogger().info("Starting stress test..."); long start = System.currentTimeMillis(); @@ -99,6 +109,7 @@ public class FOPTestbed extends AbstractLogEnabled try { Thread.sleep(100); } catch (InterruptedException ie) { + //ignore } } getLogger().info("Stress test duration: " + (System.currentTimeMillis() - start) + "ms"); @@ -109,10 +120,10 @@ public class FOPTestbed extends AbstractLogEnabled public void run() { try { for (int r = 0; r < repeat; r++) { - Iterator i = tasks.iterator(); + Iterator i = taskList.iterator(); while (i.hasNext()) { TaskDef def = (TaskDef)i.next(); - final Task task = new Task(def, counter++); + final Task task = new Task(def, counter++, foprocessor); ContainerUtil.enableLogging(task, getLogger()); task.execute(); } @@ -124,7 +135,10 @@ public class FOPTestbed extends AbstractLogEnabled } - + /** + * Creates a new FOProcessor. + * @return the newly created instance + */ public FOProcessor createFOProcessor() { try { Class clazz = Class.forName(this.fopCfg.getAttribute("class", @@ -197,18 +211,19 @@ public class FOPTestbed extends AbstractLogEnabled private TaskDef def; private int num; + private FOProcessor fop; - public Task(TaskDef def, int num) { + public Task(TaskDef def, int num, FOProcessor fop) { this.def = def; this.num = num; + this.fop = fop; } public void execute() throws Exception { getLogger().info("Processing: " + def); - FOProcessor fop = (FOProcessor)createFOProcessor(); DecimalFormat df = new DecimalFormat("00000"); - File outfile = new File(outputDir, df.format(num) + ".pdf"); + File outfile = new File(outputDir, df.format(num) + fop.getTargetFileExtension()); OutputStream out = new java.io.FileOutputStream(outfile); try { InputStream in; diff --git a/test/java/org/apache/fop/threading/FOProcessor.java b/test/java/org/apache/fop/threading/FOProcessor.java index 8149ab04a..a6b3dd7ec 100644 --- a/test/java/org/apache/fop/threading/FOProcessor.java +++ b/test/java/org/apache/fop/threading/FOProcessor.java @@ -24,11 +24,24 @@ import java.io.OutputStream; import javax.xml.transform.Templates; +/** + * Represents an FO processor. + */ public interface FOProcessor { - String ROLE = FOProcessor.class.getName(); - + /** + * Process a file. + * @param in the InputStream for the FO or XML file + * @param templates a JAXP Templates object for an XSLT transformation or null + * @param out the OutputStream for the target file + * @throws Exception if an error occurs + */ void process(InputStream in, Templates templates, OutputStream out) - throws org.apache.fop.apps.FOPException, java.io.IOException; + throws Exception; + /** + * Returns the target file extension for the configured output format. + * @return the target file extension (for example ".pdf") + */ + String getTargetFileExtension(); }
\ No newline at end of file diff --git a/test/java/org/apache/fop/threading/FOProcessorImpl.java b/test/java/org/apache/fop/threading/FOProcessorImpl.java index b5b2ff57d..e913e9a79 100644 --- a/test/java/org/apache/fop/threading/FOProcessorImpl.java +++ b/test/java/org/apache/fop/threading/FOProcessorImpl.java @@ -28,69 +28,53 @@ import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamSource; import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; -import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; -import org.apache.avalon.framework.activity.Initializable; +/** + * Default implementation of the FOProcessor interface using FOP. + */ public class FOProcessorImpl extends AbstractLogEnabled implements FOProcessor, Configurable, Initializable { private FopFactory fopFactory = FopFactory.newInstance(); private TransformerFactory factory = TransformerFactory.newInstance(); - private String baseDir; - private String fontBaseDir; private String userconfig; - private boolean strokeSVGText; + private String mime; + private String fileExtension; + /** {@inheritDoc} */ public void configure(Configuration configuration) throws ConfigurationException { - this.baseDir = configuration.getChild("basedir").getValue(null); - this.fontBaseDir = configuration.getChild("fontbasedir").getValue(null); this.userconfig = configuration.getChild("userconfig").getValue(null); - this.strokeSVGText = configuration.getChild("strokesvgtext").getValueAsBoolean(true); + this.mime = configuration.getChild("mime").getValue(MimeConstants.MIME_PDF); + this.fileExtension = configuration.getChild("extension").getValue(".pdf"); } - + /** {@inheritDoc} */ public void initialize() throws Exception { - /* - org.apache.fop.messaging.MessageHandler.setScreenLogger(getLogger()); - if (userconfig != null) { - getLogger().info("Using user config: "+userconfig); - InputStream in = org.apache.fop.tools.URLBuilder.buildURL(userconfig).openStream(); - try { - new org.apache.fop.apps.Options(in); - } finally { - in.close(); - } - } - if (this.baseDir != null) { - getLogger().info("Setting base dir: "+baseDir); - org.apache.fop.configuration.Configuration.put("baseDir", this.baseDir); + if (this.userconfig != null) { + getLogger().debug("Setting user config: " + userconfig); + fopFactory.setUserConfig(this.userconfig); } - if (this.fontBaseDir != null) { - getLogger().info("Setting font base dir: "+fontBaseDir); - org.apache.fop.configuration.Configuration.put("fontBaseDir", this.fontBaseDir); - } - String value = (this.strokeSVGText?"true":"false"); - org.apache.fop.configuration.Configuration.put("strokeSVGText", value); - */ } - + /** {@inheritDoc} */ public void process(InputStream in, Templates templates, OutputStream out) throws org.apache.fop.apps.FOPException, java.io.IOException { FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); + Fop fop = fopFactory.newFop(this.mime, foUserAgent, out); try { Transformer transformer; @@ -107,4 +91,9 @@ public class FOProcessorImpl extends AbstractLogEnabled } } + /** {@inheritDoc} */ + public String getTargetFileExtension() { + return this.fileExtension; + } + }
\ No newline at end of file diff --git a/test/java/org/apache/fop/threading/Main.java b/test/java/org/apache/fop/threading/Main.java index ae3bf2ab1..e7f011ada 100644 --- a/test/java/org/apache/fop/threading/Main.java +++ b/test/java/org/apache/fop/threading/Main.java @@ -19,7 +19,9 @@ package org.apache.fop.threading; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; import org.apache.avalon.framework.ExceptionUtil; import org.apache.avalon.framework.configuration.Configuration; @@ -27,8 +29,21 @@ import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.avalon.framework.container.ContainerUtil; import org.apache.avalon.framework.logger.ConsoleLogger; +/** + * Starter class for the multi-threading testbed. + */ public class Main { + private static void prompt() throws IOException { + BufferedReader in = new BufferedReader(new java.io.InputStreamReader(System.in)); + System.out.print("Press return to continue..."); + in.readLine(); + } + + /** + * Main method. + * @param args the command-line arguments + */ public static void main(String[] args) { try { //Read configuration @@ -36,6 +51,11 @@ public class Main { DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); Configuration cfg = builder.buildFromFile(cfgFile); + boolean doPrompt = cfg.getAttributeAsBoolean("prompt", false); + if (doPrompt) { + prompt(); + } + //Setup testbed FOPTestbed testbed = new FOPTestbed(); ContainerUtil.enableLogging(testbed, new ConsoleLogger(ConsoleLogger.LEVEL_INFO)); diff --git a/test/java/org/apache/fop/threading/sample.cfg.xml b/test/java/org/apache/fop/threading/sample.cfg.xml index cb4831ef5..0be7dc539 100644 --- a/test/java/org/apache/fop/threading/sample.cfg.xml +++ b/test/java/org/apache/fop/threading/sample.cfg.xml @@ -1,12 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> -<config> +<config prompt="false"> <threads>2</threads> <output-dir>C:/Dev/FOP/temp/out</output-dir> - <foprocessor> - <!--basedir>C:/Dev/FOP/temp</basedir> - <fontbasedir>C:/Dev/FOP/temp/fonts</fontbasedir> + <foprocessor class="org.apache.fop.threading.FOProcessorImpl"> + <!-- <userconfig>C:/Dev/FOP/temp/userconfig.xml</userconfig> - <strokesvgtext>true</strokesvgtext--> + --> + <mime>application/pdf</mime> + <extension>.pdf</extension> </foprocessor> <tasks repeat="2"> <task fo="C:/Dev/FOP/temp/helloworld.fo"/> diff --git a/test/java/org/apache/fop/util/dijkstra/City.java b/test/java/org/apache/fop/util/dijkstra/City.java new file mode 100644 index 000000000..4562c36c7 --- /dev/null +++ b/test/java/org/apache/fop/util/dijkstra/City.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util.dijkstra; + +/** + * Represents a city. + */ +public class City implements Vertex { + + private String name; + + /** + * Main constructor + * @param name the city's name + */ + public City(String name) { + this.name = name; + } + + /** {@inheritDoc} */ + public boolean equals(Object obj) { + return this.name.equals(((City)obj).name); + } + + /** {@inheritDoc} */ + public int hashCode() { + return this.name.hashCode(); + } + + /** {@inheritDoc} */ + public int compareTo(Object obj) { + return this.name.compareTo(((City)obj).name); + } + + /** {@inheritDoc} */ + public String toString() { + return this.name; + } + +}
\ No newline at end of file diff --git a/test/java/org/apache/fop/util/dijkstra/DijkstraTestCase.java b/test/java/org/apache/fop/util/dijkstra/DijkstraTestCase.java new file mode 100644 index 000000000..fb56f1f53 --- /dev/null +++ b/test/java/org/apache/fop/util/dijkstra/DijkstraTestCase.java @@ -0,0 +1,139 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util.dijkstra; + +import java.util.Iterator; +import java.util.LinkedList; + +import junit.framework.TestCase; + +/** + * Tests the Dijkstra algorithm implementation. We're comparing best solutions with focus on + * time or distance getting from St. Gallen to Lucerne on Switzerland's railroads. + */ +public class DijkstraTestCase extends TestCase { + + private static final boolean DEBUG = false; + + private static final City ROMANSHORN = new City("Romanshorn"); + private static final City ST_GALLEN = new City("St. Gallen"); + private static final City WINTERTHUR = new City("Winterthur"); + private static final City ZURICH = new City("Zurich"); + private static final City ZUG = new City("Zug"); + private static final City RAPPERSWIL = new City("Rapperswil"); + private static final City ARTH_GOLDAU = new City("Arth-Goldau"); + private static final City LUCERNE = new City("Lucerne"); + + private static final City NOWHERE = new City("nowhere"); + + private DijkstraAlgorithm algo; + private DefaultEdgeDirectory edges; + private Mode mode; + + /** {@inheritDoc} */ + protected void setUp() throws Exception { + super.setUp(); + + edges = new DefaultEdgeDirectory(); + algo = new DijkstraAlgorithm(edges); + mode = new Mode(); + + //St.Gallen - Winterthur - Zurich - Zug - Lucerne: 161 km, 2h 01min + edges.addEdge(new TrainRoute(mode, ST_GALLEN, WINTERTHUR, 61, 39)); + edges.addEdge(new TrainRoute(mode, WINTERTHUR, ZURICH, 31, 31)); + edges.addEdge(new TrainRoute(mode, ZURICH, ZUG, 39, 31)); + edges.addEdge(new TrainRoute(mode, ZUG, LUCERNE, 30, 20)); + + //St.Gallen - Rapperswil - Arth-Goldau - Lucerne: 158km, 2h 18min + edges.addEdge(new TrainRoute(mode, ST_GALLEN, RAPPERSWIL, 72, 57)); + edges.addEdge(new TrainRoute(mode, RAPPERSWIL, ARTH_GOLDAU, 55, 48)); + edges.addEdge(new TrainRoute(mode, ARTH_GOLDAU, LUCERNE, 31, 33)); + + //A detour to make it interesting (St.Gallen - Romanshorn - Winterthur): 89km, 1h 23min + edges.addEdge(new TrainRoute(mode, ST_GALLEN, ROMANSHORN, 30, 32)); + edges.addEdge(new TrainRoute(mode, ROMANSHORN, WINTERTHUR, 59, 51)); + } + + public void testAlgorithmWithDistance() throws Exception { + mode.useDistance(); + City origin = ST_GALLEN; + City destination = LUCERNE; + String route = executeAlgorithm(origin, destination); + + int distance = algo.getLowestPenalty(destination); + + if (DEBUG) { + System.out.println(route + " " + distance + " km"); + } + + assertEquals(158, distance); + assertEquals("St. Gallen - Rapperswil - Arth-Goldau - Lucerne", route); + } + + public void testAlgorithmWithDuration() throws Exception { + mode.useDuration(); + City origin = ST_GALLEN; + City destination = LUCERNE; + String route = executeAlgorithm(origin, destination); + + int duration = algo.getLowestPenalty(destination); + + if (DEBUG) { + System.out.println(route + " " + duration + " minutes"); + } + + assertEquals(121, duration); + assertEquals("St. Gallen - Winterthur - Zurich - Zug - Lucerne", route); + } + + public void testAlgorithmWithNonExistentRoute() throws Exception { + City origin = ST_GALLEN; + City destination = NOWHERE; + algo.execute(origin, destination); + Vertex pred = algo.getPredecessor(destination); + assertNull(pred); + } + + private String executeAlgorithm(City origin, City destination) { + algo.execute(origin, destination); + Vertex prev = destination; + Vertex pred = algo.getPredecessor(destination); + if (pred == null) { + fail("No route found!"); + } + LinkedList stops = new LinkedList(); + stops.addLast(destination); + while ((pred = algo.getPredecessor(prev)) != null) { + stops.addFirst(pred); + prev = pred; + } + StringBuffer sb = new StringBuffer(); + Iterator iter = stops.iterator(); + while (iter.hasNext()) { + if (sb.length() > 0) { + sb.append(" - "); + } + sb.append(iter.next()); + } + String route = sb.toString(); + return route; + } + +} diff --git a/test/java/org/apache/fop/util/dijkstra/Mode.java b/test/java/org/apache/fop/util/dijkstra/Mode.java new file mode 100644 index 000000000..4e75e57af --- /dev/null +++ b/test/java/org/apache/fop/util/dijkstra/Mode.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util.dijkstra; + +/** + * Class to allow easy switching between duration and distance mode. + */ +public class Mode { + + private boolean duration = true; + + /** + * Switch to duration mode. + */ + public void useDuration() { + this.duration = true; + } + + /** + * Switch to distance mode. + */ + public void useDistance() { + this.duration = false; + } + + /** + * Indicates whether to use duration mode or distance mode. + * @return true if duration mode is active, otherwise it's the distance mode. + */ + public boolean isDuration() { + return this.duration; + } + +} diff --git a/test/java/org/apache/fop/util/dijkstra/TrainRoute.java b/test/java/org/apache/fop/util/dijkstra/TrainRoute.java new file mode 100644 index 000000000..16ad0dc3a --- /dev/null +++ b/test/java/org/apache/fop/util/dijkstra/TrainRoute.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* $Id$ */ + +package org.apache.fop.util.dijkstra; + +/** + * Represents a train route with both distance and duration. + */ +public class TrainRoute implements Edge { + + private Mode mode; + private Vertex start; + private Vertex end; + private int distance; + private int minutes; + + /** + * Main constructor. + * @param origin the start city + * @param dest the destination city + * @param distance the distance between the two cities + * @param minutes the duration for the route + */ + public TrainRoute(Mode mode, City origin, City dest, int distance, int minutes) { + this.mode = mode; + this.start = origin; + this.end = dest; + this.distance = distance; + this.minutes = minutes; + } + + /** {@inheritDoc} */ + public int getPenalty() { + if (mode.isDuration()) { + return this.minutes; + } else { + return this.distance; + } + } + + /** {@inheritDoc} */ + public Vertex getEnd() { + return this.end; + } + + /** {@inheritDoc} */ + public Vertex getStart() { + return this.start; + } + +} diff --git a/test/java/org/apache/fop/visual/BatchDiffer.java b/test/java/org/apache/fop/visual/BatchDiffer.java index aa3f5504f..9d354e7ce 100644 --- a/test/java/org/apache/fop/visual/BatchDiffer.java +++ b/test/java/org/apache/fop/visual/BatchDiffer.java @@ -20,31 +20,28 @@ package org.apache.fop.visual; import java.awt.image.BufferedImage; -import java.awt.image.RenderedImage; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.Collection; import java.util.Iterator; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.stream.StreamSource; +import org.xml.sax.SAXException; + import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; import org.apache.avalon.framework.container.ContainerUtil; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.image.writer.ImageWriterUtil; + import org.apache.fop.layoutengine.LayoutEngineTestSuite; -import org.apache.xmlgraphics.image.writer.ImageWriter; -import org.apache.xmlgraphics.image.writer.ImageWriterRegistry; -import org.xml.sax.SAXException; /** * This class is used to visually diff bitmap images created through various sources. @@ -110,22 +107,6 @@ public class BatchDiffer { } /** - * Saves a BufferedImage as a PNG file. - * @param bitmap the bitmap to encode - * @param outputFile the target file - * @throws IOException in case of an I/O problem - */ - public static void saveAsPNG(RenderedImage bitmap, File outputFile) throws IOException { - OutputStream out = new FileOutputStream(outputFile); - try { - ImageWriter writer = ImageWriterRegistry.getInstance().getWriterFor("image/png"); - writer.writeImage(bitmap, out); - } finally { - IOUtils.closeQuietly(out); - } - } - - /** * Runs the batch. * @param cfgFile configuration file to use * @throws ConfigurationException In case of a problem with the configuration @@ -216,14 +197,14 @@ public class BatchDiffer { //Save combined bitmap as PNG file File outputFile = new File(targetDir, f.getName() + "._combined.png"); - saveAsPNG(combined, outputFile); + ImageWriterUtil.saveAsPNG(combined, outputFile); if (createDiffs) { for (int k = 1; k < bitmaps.length; k++) { BufferedImage diff = BitmapComparator.buildDiffImage( bitmaps[0], bitmaps[k]); outputFile = new File(targetDir, f.getName() + "._diff" + k + ".png"); - saveAsPNG(diff, outputFile); + ImageWriterUtil.saveAsPNG(diff, outputFile); } } //Release memory as soon as possible. These images are huge! |