From e18a41654822060c989d0c0149e8d5fc036649c3 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Mon, 1 Jul 2019 10:18:11 +0000 Subject: [PATCH] FOP-2867: Hyphenation file is not reloaded after a change git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1862365 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/fop/apps/FOUserAgent.java | 5 + .../java/org/apache/fop/apps/FopFactory.java | 10 ++ .../apache/fop/hyphenation/Hyphenator.java | 99 +++++-------------- .../layoutmgr/inline/LineLayoutManager.java | 2 +- .../org/apache/fop/HyphenationTestCase.java | 35 ++++++- 5 files changed, 71 insertions(+), 80 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java b/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java index 51c0d8869..3fd2c9167 100644 --- a/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java +++ b/fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java @@ -56,6 +56,7 @@ import org.apache.fop.events.LoggingEventListener; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fonts.FontManager; +import org.apache.fop.hyphenation.HyphenationTreeCache; import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.render.ImageHandlerRegistry; import org.apache.fop.render.Renderer; @@ -812,4 +813,8 @@ public class FOUserAgent { public SoftMapCache getPDFObjectCache() { return pdfObjectCache; } + + public HyphenationTreeCache getHyphenationTreeCache() { + return factory.getHyphenationTreeCache(); + } } diff --git a/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java b/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java index 2e640ce6d..e2f81b140 100644 --- a/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java +++ b/fop-core/src/main/java/org/apache/fop/apps/FopFactory.java @@ -44,6 +44,7 @@ import org.apache.fop.configuration.Configuration; import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fonts.FontManager; +import org.apache.fop.hyphenation.HyphenationTreeCache; import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.render.ImageHandlerRegistry; import org.apache.fop.render.RendererConfig; @@ -88,6 +89,8 @@ public final class FopFactory implements ImageContext { private final Map rendererConfig; + private HyphenationTreeCache hyphenationTreeCache; + private FopFactory(FopFactoryConfig config) { this.config = config; this.resolver = ResourceResolverFactory.createInternalResourceResolver(config.getBaseURI(), @@ -436,4 +439,11 @@ public final class FopFactory implements ImageContext { public ColorSpaceCache getColorSpaceCache() { return this.colorSpaceCache; } + + public HyphenationTreeCache getHyphenationTreeCache() { + if (hyphenationTreeCache == null) { + hyphenationTreeCache = new HyphenationTreeCache(); + } + return hyphenationTreeCache; + } } diff --git a/fop-core/src/main/java/org/apache/fop/hyphenation/Hyphenator.java b/fop-core/src/main/java/org/apache/fop/hyphenation/Hyphenator.java index cbd8673c4..76088fea5 100644 --- a/fop-core/src/main/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/fop-core/src/main/java/org/apache/fop/hyphenation/Hyphenator.java @@ -33,6 +33,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.fop.ResourceEventProducer; +import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.events.EventBroadcaster; @@ -47,63 +48,29 @@ public final class Hyphenator { /** logging instance */ private static final Log log = LogFactory.getLog(Hyphenator.class); - private static HyphenationTreeCache hTreeCache; - /** Enables a dump of statistics. Note: If activated content is sent to System.out! */ private static boolean statisticsDump; public static final String HYPTYPE = Hyphenator.class.toString() + "HYP"; public static final String XMLTYPE = Hyphenator.class.toString() + "XML"; - /** - * Creates a new hyphenator. - */ - private Hyphenator() { } - - /** @return the default (static) hyphenation tree cache */ - public static synchronized HyphenationTreeCache getHyphenationTreeCache() { - if (hTreeCache == null) { - hTreeCache = new HyphenationTreeCache(); - } - return hTreeCache; + private Hyphenator() { } - /** - * Clears the default hyphenation tree cache.
- * This method can be used if the underlying data files are changed at runtime. - */ - public static synchronized void clearHyphenationTreeCache() { - hTreeCache = new HyphenationTreeCache(); - } - - /** - * Returns a hyphenation tree for a given language and country, - * with fallback from (lang,country) to (lang). - * The hyphenation trees are cached. - * @param lang the language - * @param country the country (may be null or "none") - * @param resolver resolver to find the hyphenation files - * @param hyphPatNames the map with user-configured hyphenation pattern file names - * @return the hyphenation tree - */ public static HyphenationTree getHyphenationTree(String lang, String country, - InternalResourceResolver resolver, Map hyphPatNames) { - return getHyphenationTree(lang, country, resolver, hyphPatNames, null); - } - - public static HyphenationTree getHyphenationTree(String lang, String country, - InternalResourceResolver resourceResolver, Map hyphPatNames, EventBroadcaster eventBroadcaster) { + InternalResourceResolver resourceResolver, Map hyphPatNames, FOUserAgent foUserAgent) { String llccKey = HyphenationTreeCache.constructLlccKey(lang, country); - HyphenationTreeCache cache = getHyphenationTreeCache(); - // If this hyphenation tree has been registered as missing, return immediately - if (cache.isMissing(llccKey)) { + HyphenationTreeCache cache = foUserAgent.getHyphenationTreeCache(); + + // See if there was an error finding this hyphenation tree before + if (cache == null || cache.isMissing(llccKey)) { return null; } HyphenationTree hTree; // first try to find it in the cache - hTree = getHyphenationTreeCache().getHyphenationTree(lang, country); + hTree = cache.getHyphenationTree(lang, country); if (hTree != null) { return hTree; } @@ -120,13 +87,14 @@ public final class Hyphenator { } if (hTree == null && country != null && !country.equals("none")) { - return getHyphenationTree(lang, null, resourceResolver, hyphPatNames, eventBroadcaster); + return getHyphenationTree(lang, null, resourceResolver, hyphPatNames, foUserAgent); } // put it into the pattern cache if (hTree != null) { cache.cache(llccKey, hTree); } else { + EventBroadcaster eventBroadcaster = foUserAgent.getEventBroadcaster(); if (eventBroadcaster == null) { log.error("Couldn't find hyphenation pattern " + llccKey); } else { @@ -188,23 +156,15 @@ public final class Hyphenator { * @return the hyphenation tree or null if it wasn't found in the resources */ public static HyphenationTree getFopHyphenationTree(String key) { - HyphenationTree hTree = null; - ObjectInputStream ois = null; - InputStream is = null; - try { - is = getResourceStream(key); - if (is == null) { - if (log.isDebugEnabled()) { - log.debug("Couldn't find precompiled hyphenation pattern " - + key + " in resources"); - } - return null; + InputStream is = getResourceStream(key); + if (is == null) { + if (log.isDebugEnabled()) { + log.debug("Couldn't find precompiled hyphenation pattern " + + key + " in resources"); } - hTree = readHyphenationTree(is); - } finally { - IOUtils.closeQuietly(ois); + return null; } - return hTree; + return readHyphenationTree(is); } /** @@ -284,30 +244,15 @@ public final class Hyphenator { return null; } - /** - * Hyphenates a word. - * @param lang the language - * @param country the optional country code (may be null or "none") - * @param resourceResolver resolver to find the hyphenation files - * @param hyphPatNames the map with user-configured hyphenation pattern file names - * @param word the word to hyphenate - * @param leftMin the minimum number of characters before the hyphenation point - * @param rightMin the minimum number of characters after the hyphenation point - * @return the hyphenation result - */ - public static Hyphenation hyphenate(String lang, String country, - InternalResourceResolver resourceResolver, Map hyphPatNames, String word, int leftMin, - int rightMin) { - return hyphenate(lang, country, resourceResolver, hyphPatNames, word, leftMin, rightMin, null); - } - public static Hyphenation hyphenate(String lang, String country, InternalResourceResolver resourceResolver, - Map hyphPatNames, String word, int leftMin, int rightMin, - EventBroadcaster eventBroadcaster) { - HyphenationTree hTree = getHyphenationTree(lang, country, resourceResolver, hyphPatNames, eventBroadcaster); + Map hyphPatNames, + String word, + int leftMin, int rightMin, FOUserAgent foUserAgent) { + HyphenationTree hTree = getHyphenationTree(lang, country, resourceResolver, hyphPatNames, foUserAgent); if (hTree == null) { return null; } return hTree.hyphenate(word, leftMin, rightMin); } + } diff --git a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index c15c1d0be..e135b4310 100644 --- a/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -1435,7 +1435,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager sbChars.toString(), hyphenationProperties.hyphenationRemainCharacterCount.getValue(), hyphenationProperties.hyphenationPushCharacterCount.getValue(), - getFObj().getUserAgent().getEventBroadcaster()); + getFObj().getUserAgent()); // They hyph structure contains the information we need // Now start from prev: reset to that position, ask that LM to get // a Position for the first hyphenation offset. If the offset isn't in diff --git a/fop-core/src/test/java/org/apache/fop/HyphenationTestCase.java b/fop-core/src/test/java/org/apache/fop/HyphenationTestCase.java index 2cb7845b6..818e269be 100644 --- a/fop-core/src/test/java/org/apache/fop/HyphenationTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/HyphenationTestCase.java @@ -19,6 +19,7 @@ package org.apache.fop; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; @@ -26,7 +27,11 @@ import java.io.ObjectOutputStream; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import org.apache.commons.io.IOUtils; + +import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.hyphenation.Hyphenation; @@ -35,6 +40,7 @@ import org.apache.fop.hyphenation.HyphenationTree; import org.apache.fop.hyphenation.Hyphenator; public class HyphenationTestCase { + private FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); @Test public void testHyphenator() { @@ -42,7 +48,7 @@ public class HyphenationTestCase { InternalResourceResolver resourceResolver = ResourceResolverFactory.createDefaultInternalResourceResolver( f.toURI()); Hyphenation hyph = Hyphenator.hyphenate("fr.xml" + Hyphenator.XMLTYPE, null, resourceResolver, null, - "hello", 0, 0); + "hello", 0, 0, fopFactory.newFOUserAgent()); assertEquals(hyph.toString(), "-hel-lo"); } @@ -62,10 +68,35 @@ public class HyphenationTestCase { out.close(); Hyphenation hyph = Hyphenator.hyphenate("fr.hyp" + Hyphenator.HYPTYPE, null, resourceResolver, null, - "oello", 0, 0); + "oello", 0, 0, fopFactory.newFOUserAgent()); assertEquals(hyph.toString(), "oel-lo"); hyp.delete(); f.delete(); } + + @Test + public void testHyphenatorCache() throws IOException { + File f = File.createTempFile("hyp", "fop"); + f.delete(); + f.mkdir(); + File frxml = new File(f, "fr.xml"); + IOUtils.copy(new FileInputStream("test/resources/fop/fr.xml"), new FileOutputStream(frxml)); + InternalResourceResolver resourceResolver = ResourceResolverFactory.createDefaultInternalResourceResolver( + f.toURI()); + Hyphenation hyph = Hyphenator.hyphenate("fr.xml" + Hyphenator.XMLTYPE, null, resourceResolver, null, + "hello", 0, 0, fopFactory.newFOUserAgent()); + assertEquals(hyph.toString(), "-hel-lo"); + + FileOutputStream fos = new FileOutputStream(frxml); + fos.write(("").getBytes()); + fos.close(); + fopFactory = FopFactory.newInstance(new File(".").toURI()); + hyph = Hyphenator.hyphenate("fr.xml" + Hyphenator.XMLTYPE, null, resourceResolver, null, + "hello", 0, 0, fopFactory.newFOUserAgent()); + assertNull(hyph); + + frxml.delete(); + f.delete(); + } } -- 2.39.5