Browse Source

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
tags/fop-2_4
Simon Steiner 4 years ago
parent
commit
e18a416548

+ 5
- 0
fop-core/src/main/java/org/apache/fop/apps/FOUserAgent.java View File

import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fo.FOEventHandler; import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fonts.FontManager; import org.apache.fop.fonts.FontManager;
import org.apache.fop.hyphenation.HyphenationTreeCache;
import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry; import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.Renderer; import org.apache.fop.render.Renderer;
public SoftMapCache getPDFObjectCache() { public SoftMapCache getPDFObjectCache() {
return pdfObjectCache; return pdfObjectCache;
} }

public HyphenationTreeCache getHyphenationTreeCache() {
return factory.getHyphenationTreeCache();
}
} }

+ 10
- 0
fop-core/src/main/java/org/apache/fop/apps/FopFactory.java View File

import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry; import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fonts.FontManager; import org.apache.fop.fonts.FontManager;
import org.apache.fop.hyphenation.HyphenationTreeCache;
import org.apache.fop.layoutmgr.LayoutManagerMaker; import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry; import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.RendererConfig; import org.apache.fop.render.RendererConfig;


private final Map<String, RendererConfig> rendererConfig; private final Map<String, RendererConfig> rendererConfig;


private HyphenationTreeCache hyphenationTreeCache;

private FopFactory(FopFactoryConfig config) { private FopFactory(FopFactoryConfig config) {
this.config = config; this.config = config;
this.resolver = ResourceResolverFactory.createInternalResourceResolver(config.getBaseURI(), this.resolver = ResourceResolverFactory.createInternalResourceResolver(config.getBaseURI(),
public ColorSpaceCache getColorSpaceCache() { public ColorSpaceCache getColorSpaceCache() {
return this.colorSpaceCache; return this.colorSpaceCache;
} }

public HyphenationTreeCache getHyphenationTreeCache() {
if (hyphenationTreeCache == null) {
hyphenationTreeCache = new HyphenationTreeCache();
}
return hyphenationTreeCache;
}
} }

+ 22
- 77
fop-core/src/main/java/org/apache/fop/hyphenation/Hyphenator.java View File

import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;


import org.apache.fop.ResourceEventProducer; import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.events.EventBroadcaster; import org.apache.fop.events.EventBroadcaster;


/** logging instance */ /** logging instance */
private static final Log log = LogFactory.getLog(Hyphenator.class); 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! */ /** Enables a dump of statistics. Note: If activated content is sent to System.out! */
private static boolean statisticsDump; private static boolean statisticsDump;


public static final String HYPTYPE = Hyphenator.class.toString() + "HYP"; public static final String HYPTYPE = Hyphenator.class.toString() + "HYP";
public static final String XMLTYPE = Hyphenator.class.toString() + "XML"; 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.<br>
* 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, 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); 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; return null;
} }


HyphenationTree hTree; HyphenationTree hTree;
// first try to find it in the cache // first try to find it in the cache
hTree = getHyphenationTreeCache().getHyphenationTree(lang, country);
hTree = cache.getHyphenationTree(lang, country);
if (hTree != null) { if (hTree != null) {
return hTree; return hTree;
} }
} }


if (hTree == null && country != null && !country.equals("none")) { 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 // put it into the pattern cache
if (hTree != null) { if (hTree != null) {
cache.cache(llccKey, hTree); cache.cache(llccKey, hTree);
} else { } else {
EventBroadcaster eventBroadcaster = foUserAgent.getEventBroadcaster();
if (eventBroadcaster == null) { if (eventBroadcaster == null) {
log.error("Couldn't find hyphenation pattern " + llccKey); log.error("Couldn't find hyphenation pattern " + llccKey);
} else { } else {
* @return the hyphenation tree or null if it wasn't found in the resources * @return the hyphenation tree or null if it wasn't found in the resources
*/ */
public static HyphenationTree getFopHyphenationTree(String key) { 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);
} }


/** /**
return null; 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, 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) { if (hTree == null) {
return null; return null;
} }
return hTree.hyphenate(word, leftMin, rightMin); return hTree.hyphenate(word, leftMin, rightMin);
} }

} }

+ 1
- 1
fop-core/src/main/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java View File

sbChars.toString(), sbChars.toString(),
hyphenationProperties.hyphenationRemainCharacterCount.getValue(), hyphenationProperties.hyphenationRemainCharacterCount.getValue(),
hyphenationProperties.hyphenationPushCharacterCount.getValue(), hyphenationProperties.hyphenationPushCharacterCount.getValue(),
getFObj().getUserAgent().getEventBroadcaster());
getFObj().getUserAgent());
// They hyph structure contains the information we need // They hyph structure contains the information we need
// Now start from prev: reset to that position, ask that LM to get // 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 // a Position for the first hyphenation offset. If the offset isn't in

+ 33
- 2
fop-core/src/test/java/org/apache/fop/HyphenationTestCase.java View File

package org.apache.fop; package org.apache.fop;


import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import org.junit.Test; import org.junit.Test;


import static org.junit.Assert.assertEquals; 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.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory; import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.hyphenation.Hyphenation; import org.apache.fop.hyphenation.Hyphenation;
import org.apache.fop.hyphenation.Hyphenator; import org.apache.fop.hyphenation.Hyphenator;


public class HyphenationTestCase { public class HyphenationTestCase {
private FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());


@Test @Test
public void testHyphenator() { public void testHyphenator() {
InternalResourceResolver resourceResolver = ResourceResolverFactory.createDefaultInternalResourceResolver( InternalResourceResolver resourceResolver = ResourceResolverFactory.createDefaultInternalResourceResolver(
f.toURI()); f.toURI());
Hyphenation hyph = Hyphenator.hyphenate("fr.xml" + Hyphenator.XMLTYPE, null, resourceResolver, null, Hyphenation hyph = Hyphenator.hyphenate("fr.xml" + Hyphenator.XMLTYPE, null, resourceResolver, null,
"hello", 0, 0);
"hello", 0, 0, fopFactory.newFOUserAgent());
assertEquals(hyph.toString(), "-hel-lo"); assertEquals(hyph.toString(), "-hel-lo");
} }


out.close(); out.close();


Hyphenation hyph = Hyphenator.hyphenate("fr.hyp" + Hyphenator.HYPTYPE, null, resourceResolver, null, Hyphenation hyph = Hyphenator.hyphenate("fr.hyp" + Hyphenator.HYPTYPE, null, resourceResolver, null,
"oello", 0, 0);
"oello", 0, 0, fopFactory.newFOUserAgent());
assertEquals(hyph.toString(), "oel-lo"); assertEquals(hyph.toString(), "oel-lo");


hyp.delete(); hyp.delete();
f.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(("<hyphenation-info></hyphenation-info>").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();
}
} }

Loading…
Cancel
Save