aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/hyphenation
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop/hyphenation')
-rw-r--r--src/java/org/apache/fop/hyphenation/HyphenationTree.java28
-rw-r--r--src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java101
-rw-r--r--src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java37
-rw-r--r--src/java/org/apache/fop/hyphenation/Hyphenator.java391
-rw-r--r--src/java/org/apache/fop/hyphenation/PatternParser.java115
5 files changed, 494 insertions, 178 deletions
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTree.java b/src/java/org/apache/fop/hyphenation/HyphenationTree.java
index a726d9501..d67405c93 100644
--- a/src/java/org/apache/fop/hyphenation/HyphenationTree.java
+++ b/src/java/org/apache/fop/hyphenation/HyphenationTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
package org.apache.fop.hyphenation;
import java.io.BufferedReader;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
@@ -26,9 +27,12 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
+import org.xml.sax.InputSource;
+
/**
* This tree structure stores the hyphenation patterns in an efficient
* way for fast lookup. It provides the provides the method to
@@ -39,6 +43,8 @@ import java.util.HashMap;
public class HyphenationTree extends TernaryTree
implements PatternConsumer, Serializable {
+ private static final long serialVersionUID = -7842107987915665573L;
+
/**
* value space: stores the interletter values
*/
@@ -112,12 +118,30 @@ public class HyphenationTree extends TernaryTree
/**
* Read hyphenation patterns from an XML file.
+ * @param filename the filename
+ * @throws HyphenationException In case the parsing fails
*/
public void loadPatterns(String filename) throws HyphenationException {
+ File f = new File(filename);
+ try {
+ InputSource src = new InputSource(f.toURL().toExternalForm());
+ loadPatterns(src);
+ } catch (MalformedURLException e) {
+ throw new HyphenationException("Error converting the File '" + f + "' to a URL: "
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Read hyphenation patterns from an XML file.
+ * @param source the InputSource for the file
+ * @throws HyphenationException In case the parsing fails
+ */
+ public void loadPatterns(InputSource source) throws HyphenationException {
PatternParser pp = new PatternParser(this);
ivalues = new TernaryTree();
- pp.parse(filename);
+ pp.parse(source);
// patterns/values should be now in the tree
// let's optimize a bit
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java
new file mode 100644
index 000000000..df1ae590c
--- /dev/null
+++ b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.hyphenation;
+
+import java.util.Hashtable;
+import java.util.Set;
+
+/**
+ * This is a cache for HyphenationTree instances.
+ */
+public class HyphenationTreeCache {
+
+ /** Contains the cached hyphenation trees */
+ private Hashtable hyphenTrees = new Hashtable();
+ /** Used to avoid multiple error messages for the same language if a pattern file is missing. */
+ private Set missingHyphenationTrees;
+
+ /**
+ * Looks in the cache if a hyphenation tree is available and returns it if it is found.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ * @return the HyhenationTree instance or null if it's not in the cache
+ */
+ public HyphenationTree getHyphenationTree(String lang, String country) {
+ String key = constructKey(lang, country);
+
+ // first try to find it in the cache
+ if (hyphenTrees.containsKey(key)) {
+ return (HyphenationTree)hyphenTrees.get(key);
+ } else if (hyphenTrees.containsKey(lang)) {
+ return (HyphenationTree)hyphenTrees.get(lang);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Constructs the key for the hyphenation pattern file.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ * @return the resulting key
+ */
+ public static String constructKey(String lang, String country) {
+ String key = lang;
+ // check whether the country code has been used
+ if (country != null && !country.equals("none")) {
+ key += "_" + country;
+ }
+ return key;
+ }
+
+ /**
+ * Cache a hyphenation tree under its key.
+ * @param key the key (ex. "de_CH" or "en")
+ * @param hTree the hyphenation tree
+ */
+ public void cache(String key, HyphenationTree hTree) {
+ hyphenTrees.put(key, hTree);
+ }
+
+ /**
+ * Notes a key to a hyphenation tree as missing.
+ * This is to avoid searching a second time for a hyphneation pattern file which is not
+ * available.
+ * @param key the key (ex. "de_CH" or "en")
+ */
+ public void noteMissing(String key) {
+ if (missingHyphenationTrees == null) {
+ missingHyphenationTrees = new java.util.HashSet();
+ }
+ missingHyphenationTrees.add(key);
+ }
+
+ /**
+ * Indicates whether a hyphenation file has been requested before but it wasn't available.
+ * This is to avoid searching a second time for a hyphneation pattern file which is not
+ * available.
+ * @param key the key (ex. "de_CH" or "en")
+ * @return true if the hyphenation tree is unavailable
+ */
+ public boolean isMissing(String key) {
+ return (missingHyphenationTrees != null && missingHyphenationTrees.contains(key));
+ }
+
+}
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java b/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java
new file mode 100644
index 000000000..65c8da5b8
--- /dev/null
+++ b/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.hyphenation;
+
+import javax.xml.transform.Source;
+
+/**
+ * This interface is used to resolve relative URIs pointing to hyphenation tree files.
+ */
+public interface HyphenationTreeResolver {
+
+ /**
+ * Called to resolve an URI to a Source instance. The base URI needed by the URIResolver's
+ * resolve() method is defined to be implicitely available in this case. If the URI cannot
+ * be resolved, null is returned.
+ * @param href An href attribute, which may be relative or absolute.
+ * @return A Source object, or null if the href could not resolved.
+ */
+ Source resolve(String href);
+
+}
diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java
index 4d4a1d03e..b455ec74f 100644
--- a/src/java/org/apache/fop/hyphenation/Hyphenator.java
+++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,15 +20,17 @@ package org.apache.fop.hyphenation;
import java.io.BufferedInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
-import java.util.Hashtable;
-import java.util.Set;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.xml.sax.InputSource;
/**
* This class is the main entry point to the hyphenation package.
@@ -41,16 +43,21 @@ public class Hyphenator {
/** logging instance */
protected static Log log = LogFactory.getLog(Hyphenator.class);
- /**@todo Don't use statics */
- private static Hashtable hyphenTrees = new Hashtable();
- /** Used to avoid multiple error messages for the same language if a pattern file is missing. */
- private static Set missingHyphenationTrees;
-
+ private static HyphenationTreeCache hTreeCache = null;
+
private HyphenationTree hyphenTree = null;
private int remainCharCount = 2;
private int pushCharCount = 2;
- private static boolean errorDump = false;
+ /** Enables a dump of statistics. Note: If activated content is sent to System.out! */
+ private static boolean statisticsDump = false;
+ /**
+ * Creates a new hyphenator.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ * @param leftMin the minimum number of characters before the hyphenation point
+ * @param rightMin the minimum number of characters after the hyphenation point
+ */
public Hyphenator(String lang, String country, int leftMin,
int rightMin) {
hyphenTree = getHyphenationTree(lang, country);
@@ -58,41 +65,64 @@ public class Hyphenator {
pushCharCount = rightMin;
}
+ /** @return the default (static) hyphenation tree cache */
+ public static synchronized HyphenationTreeCache getHyphenationTreeCache() {
+ if (hTreeCache == null) {
+ hTreeCache = new HyphenationTreeCache();
+ }
+ return hTreeCache;
+ }
+
+ /**
+ * Returns a hyphenation tree for a given language and country. The hyphenation trees are
+ * cached.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ * @return the hyphenation tree
+ */
public static HyphenationTree getHyphenationTree(String lang,
String country) {
- String key = lang;
- // check whether the country code has been used
- if (country != null && !country.equals("none")) {
- key += "_" + country;
- }
+ return getHyphenationTree(lang, country, null);
+ }
+
+ /**
+ * Returns a hyphenation tree for a given language and country. 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
+ * @return the hyphenation tree
+ */
+ public static HyphenationTree getHyphenationTree(String lang,
+ String country, HyphenationTreeResolver resolver) {
+ String key = HyphenationTreeCache.constructKey(lang, country);
+ HyphenationTreeCache cache = getHyphenationTreeCache();
+
// See if there was an error finding this hyphenation tree before
- if (missingHyphenationTrees != null && missingHyphenationTrees.contains(key)) {
+ if (cache.isMissing(key)) {
return null;
}
+
+ HyphenationTree hTree;
// first try to find it in the cache
- if (hyphenTrees.containsKey(key)) {
- return (HyphenationTree)hyphenTrees.get(key);
- }
- if (hyphenTrees.containsKey(lang)) {
- return (HyphenationTree)hyphenTrees.get(lang);
+ hTree = getHyphenationTreeCache().getHyphenationTree(lang, country);
+ if (hTree != null) {
+ return hTree;
}
- HyphenationTree hTree = getFopHyphenationTree(key);
+ if (resolver != null) {
+ hTree = getUserHyphenationTree(key, resolver);
+ }
if (hTree == null) {
- String hyphenDir = "/hyph";
- if (hyphenDir != null) {
- hTree = getUserHyphenationTree(key, hyphenDir);
- }
+ hTree = getFopHyphenationTree(key);
}
+
// put it into the pattern cache
if (hTree != null) {
- hyphenTrees.put(key, hTree);
+ cache.cache(key, hTree);
} else {
log.error("Couldn't find hyphenation pattern " + key);
- if (missingHyphenationTrees == null) {
- missingHyphenationTrees = new java.util.HashSet();
- }
- missingHyphenationTrees.add(key);
+ cache.noteMissing(key);
}
return hTree;
}
@@ -101,12 +131,12 @@ public class Hyphenator {
InputStream is = null;
// Try to use Context Class Loader to load the properties file.
try {
- java.lang.reflect.Method getCCL =
- Thread.class.getMethod("getContextClassLoader", new Class[0]);
+ java.lang.reflect.Method getCCL = Thread.class.getMethod(
+ "getContextClassLoader", new Class[0]);
if (getCCL != null) {
- ClassLoader contextClassLoader =
- (ClassLoader)getCCL.invoke(Thread.currentThread(),
- new Object[0]);
+ ClassLoader contextClassLoader = (ClassLoader)getCCL.invoke(
+ Thread.currentThread(),
+ new Object[0]);
is = contextClassLoader.getResourceAsStream("hyph/" + key
+ ".hyp");
}
@@ -122,6 +152,25 @@ public class Hyphenator {
return is;
}
+ private static HyphenationTree readHyphenationTree(InputStream in) {
+ HyphenationTree hTree = null;
+ try {
+ ObjectInputStream ois = new ObjectInputStream(in);
+ hTree = (HyphenationTree)ois.readObject();
+ } catch (IOException ioe) {
+ log.error("I/O error while loading precompiled hyphenation pattern file", ioe);
+ } catch (ClassNotFoundException cnfe) {
+ log.error("Error while reading hyphenation object from file", cnfe);
+ }
+ return hTree;
+ }
+
+ /**
+ * Returns a hyphenation tree. This method looks in the resources (getResourceStream) for
+ * the hyphenation patterns.
+ * @param key the language/country key
+ * @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;
@@ -130,53 +179,66 @@ public class Hyphenator {
is = getResourceStream(key);
if (is == null) {
if (key.length() == 5) {
- is = getResourceStream(key.substring(0, 2));
+ String lang = key.substring(0, 2);
+ is = getResourceStream(lang);
if (is != null) {
- //log.error("Couldn't find hyphenation pattern "
- // + key
- // + "\nusing general language pattern "
- // + key.substring(0, 2)
- // + " instead.");
+ if (log.isDebugEnabled()) {
+ log.debug("Couldn't find hyphenation pattern '"
+ + key
+ + "'. Using general language pattern '"
+ + lang
+ + "' instead.");
+ }
} else {
- if (errorDump) {
- //log.error("Couldn't find precompiled "
- // + "fop hyphenation pattern "
- // + key + ".hyp");
+ if (log.isDebugEnabled()) {
+ log.debug("Couldn't find precompiled hyphenation pattern "
+ + lang + " in resources.");
}
return null;
}
} else {
- if (errorDump) {
- //log.error("Couldn't find precompiled "
- // + "fop hyphenation pattern "
- // + key + ".hyp");
+ if (log.isDebugEnabled()) {
+ log.debug("Couldn't find precompiled hyphenation pattern "
+ + key + " in resources");
}
return null;
}
}
- ois = new ObjectInputStream(is);
- hTree = (HyphenationTree)ois.readObject();
- } catch (Exception e) {
- /**@todo proper logging please */
- e.printStackTrace();
+ hTree = readHyphenationTree(is);
} finally {
- if (ois != null) {
- try {
- ois.close();
- } catch (IOException e) {
- //log.error("can't close hyphenation object stream");
- }
- }
+ IOUtils.closeQuietly(ois);
}
return hTree;
}
/**
- * load tree from serialized file or xml file
+ * Load tree from serialized file or xml file
* using configuration settings
+ * @param key language key for the requested hyphenation file
+ * @param hyphenDir base directory to find hyphenation files in
+ * @return the requested HypenationTree or null if it is not available
*/
public static HyphenationTree getUserHyphenationTree(String key,
String hyphenDir) {
+ final File baseDir = new File(hyphenDir);
+ HyphenationTreeResolver resolver = new HyphenationTreeResolver() {
+ public Source resolve(String href) {
+ File f = new File(baseDir, href);
+ return new StreamSource(f);
+ }
+ };
+ return getUserHyphenationTree(key, resolver);
+ }
+
+ /**
+ * Load tree from serialized file or xml file
+ * using configuration settings
+ * @param key language key for the requested hyphenation file
+ * @param resolver resolver to find the hyphenation files
+ * @return the requested HypenationTree or null if it is not available
+ */
+ public static HyphenationTree getUserHyphenationTree(String key,
+ HyphenationTreeResolver resolver) {
HyphenationTree hTree = null;
// I use here the following convention. The file name specified in
// the configuration is taken as the base name. First we try
@@ -184,98 +246,194 @@ public class Hyphenator {
// we try name + ".xml", assumming a raw hyphenation pattern file.
// first try serialized object
- File hyphenFile = new File(hyphenDir, key + ".hyp");
- if (hyphenFile.exists()) {
- ObjectInputStream ois = null;
+ String name = key + ".hyp";
+ Source source = resolver.resolve(name);
+ if (source != null) {
try {
- ois = new ObjectInputStream(new BufferedInputStream(
- new FileInputStream(hyphenFile)));
- hTree = (HyphenationTree)ois.readObject();
- } catch (Exception e) {
- log.error("Error while loading the hyphenation file", e);
- } finally {
- if (ois != null) {
- try {
- ois.close();
- } catch (IOException e) {
- //ignore
- }
+ InputStream in = null;
+ if (source instanceof StreamSource) {
+ in = ((StreamSource) source).getInputStream();
+ }
+ if (in == null && source.getSystemId() != null) {
+ in = new java.net.URL(source.getSystemId()).openStream();
+ } else {
+ throw new UnsupportedOperationException("Cannot load hyphenation pattern file"
+ + " with the supplied Source object: " + source);
+ }
+ in = new BufferedInputStream(in);
+ try {
+ hTree = readHyphenationTree(in);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ return hTree;
+ } catch (IOException ioe) {
+ if (log.isDebugEnabled()) {
+ log.debug("I/O problem while trying to load " + name, ioe);
}
}
- return hTree;
- } else {
+ }
- // try the raw XML file
- hyphenFile = new File(hyphenDir, key + ".xml");
- if (hyphenFile.exists()) {
- hTree = new HyphenationTree();
- if (errorDump) {
- //log.error("reading " + hyphenDir + key
- // + ".xml");
+ // try the raw XML file
+ name = key + ".xml";
+ source = resolver.resolve(name);
+ if (source != null) {
+ hTree = new HyphenationTree();
+ try {
+ InputStream in = null;
+ if (source instanceof StreamSource) {
+ in = ((StreamSource) source).getInputStream();
}
- try {
- hTree.loadPatterns(hyphenFile.getPath());
- if (errorDump) {
- System.out.println("Stats: ");
- hTree.printStats();
- }
- return hTree;
- } catch (HyphenationException ex) {
- if (errorDump) {
- //log.error("Can't load user patterns "
- // + "from xml file " + hyphenDir
- // + key + ".xml");
+ if (in == null) {
+ if (source.getSystemId() != null) {
+ in = new java.net.URL(source.getSystemId()).openStream();
+ } else {
+ throw new UnsupportedOperationException(
+ "Cannot load hyphenation pattern file"
+ + " with the supplied Source object: " + source);
}
- return null;
}
- } else {
- if (errorDump) {
- //log.error("Tried to load "
- // + hyphenFile.toString()
- // + "\nCannot find compiled nor xml file for "
- // + "hyphenation pattern" + key);
+ if (!(in instanceof BufferedInputStream)) {
+ in = new BufferedInputStream(in);
+ }
+ try {
+ InputSource src = new InputSource(in);
+ src.setSystemId(source.getSystemId());
+ hTree.loadPatterns(src);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ if (statisticsDump) {
+ System.out.println("Stats: ");
+ hTree.printStats();
+ }
+ return hTree;
+ } catch (HyphenationException ex) {
+ log.error("Can't load user patterns from XML file " + source.getSystemId()
+ + ": " + ex.getMessage());
+ return null;
+ } catch (IOException ioe) {
+ if (log.isDebugEnabled()) {
+ log.debug("I/O problem while trying to load " + name, ioe);
}
return null;
}
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Could not load user hyphenation file for '" + key + "'.");
+ }
+ return null;
}
}
+ /**
+ * Hyphenates a word.
+ * @param lang the language
+ * @param country the optional country code (may be null or "none")
+ * @param resolver resolver to find the hyphenation files
+ * @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,
- String word, int leftMin,
- int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country);
+ HyphenationTreeResolver resolver,
+ String word,
+ int leftMin, int rightMin) {
+ HyphenationTree hTree = getHyphenationTree(lang, country, resolver);
if (hTree == null) {
- //log.error("Error building hyphenation tree for language "
- // + lang);
return null;
}
return hTree.hyphenate(word, leftMin, rightMin);
}
+ /**
+ * Hyphenates a word.
+ * @param lang the language
+ * @param country the optional country code (may be null or "none")
+ * @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,
+ String word,
+ int leftMin, int rightMin) {
+ return hyphenate(lang, country, null, word, leftMin, rightMin);
+ }
+
+ /**
+ * Hyphenates a word.
+ * @param lang the language
+ * @param country the optional country code (may be null or "none")
+ * @param resolver resolver to find the hyphenation files
+ * @param word the word to hyphenate
+ * @param offset the offset of the first character in the "word" character array
+ * @param len the length of the word
+ * @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,
+ HyphenationTreeResolver resolver,
char[] word, int offset, int len,
int leftMin, int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country);
+ HyphenationTree hTree = getHyphenationTree(lang, country, resolver);
if (hTree == null) {
- //log.error("Error building hyphenation tree for language "
- // + lang);
return null;
}
return hTree.hyphenate(word, offset, len, leftMin, rightMin);
}
+ /**
+ * Hyphenates a word.
+ * @param lang the language
+ * @param country the optional country code (may be null or "none")
+ * @param word the word to hyphenate
+ * @param offset the offset of the first character in the "word" character array
+ * @param len the length of the word
+ * @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,
+ char[] word, int offset, int len,
+ int leftMin, int rightMin) {
+ return hyphenate(lang, country, null, word, offset, len, leftMin, rightMin);
+ }
+
+ /**
+ * Sets the minimum number of characters before the hyphenation point
+ * @param min the number of characters
+ */
public void setMinRemainCharCount(int min) {
remainCharCount = min;
}
+ /**
+ * Sets the minimum number of characters after the hyphenation point
+ * @param min the number of characters
+ */
public void setMinPushCharCount(int min) {
pushCharCount = min;
}
+ /**
+ * Sets the language and country for the hyphenation process.
+ * @param lang the language
+ * @param country the country (may be null or "none")
+ */
public void setLanguage(String lang, String country) {
hyphenTree = getHyphenationTree(lang, country);
}
+ /**
+ * Hyphenates a word.
+ * @param word the word to hyphenate
+ * @param offset the offset of the first character in the "word" character array
+ * @param len the length of the word
+ * @return the hyphenation result
+ */
public Hyphenation hyphenate(char[] word, int offset, int len) {
if (hyphenTree == null) {
return null;
@@ -284,6 +442,11 @@ public class Hyphenator {
pushCharCount);
}
+ /**
+ * Hyphenates a word.
+ * @param word the word to hyphenate
+ * @return the hyphenation result
+ */
public Hyphenation hyphenate(String word) {
if (hyphenTree == null) {
return null;
diff --git a/src/java/org/apache/fop/hyphenation/PatternParser.java b/src/java/org/apache/fop/hyphenation/PatternParser.java
index bde436f82..56670fd23 100644
--- a/src/java/org/apache/fop/hyphenation/PatternParser.java
+++ b/src/java/org/apache/fop/hyphenation/PatternParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004,2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,12 @@ import org.xml.sax.Attributes;
// Java
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.util.ArrayList;
-import java.net.URL;
+
+import javax.xml.parsers.SAXParserFactory;
/**
* A SAX document handler to read and parse hyphenation patterns
@@ -72,73 +75,58 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
this.consumer = consumer;
}
+ /**
+ * Parses a hyphenation pattern file.
+ * @param filename the filename
+ * @throws HyphenationException In case of an exception while parsing
+ */
public void parse(String filename) throws HyphenationException {
- InputSource uri = fileInputSource(filename);
-
+ parse(new File(filename));
+ }
+
+ /**
+ * Parses a hyphenation pattern file.
+ * @param file the pattern file
+ * @throws HyphenationException In case of an exception while parsing
+ */
+ public void parse(File file) throws HyphenationException {
try {
- parser.parse(uri);
- } catch (SAXException e) {
- throw new HyphenationException(errMsg);
- } catch (IOException e) {
- throw new HyphenationException(e.getMessage());
- } catch (NullPointerException e) {
- throw new HyphenationException("SAX parser not available");
+ InputSource src = new InputSource(file.toURL().toExternalForm());
+ parse(src);
+ } catch (MalformedURLException e) {
+ throw new HyphenationException("Error converting the File '" + file + "' to a URL: "
+ + e.getMessage());
}
}
/**
- * creates a SAX parser, using the value of org.xml.sax.parser
- * defaulting to org.apache.xerces.parsers.SAXParser
- *
- * @return the created SAX parser
+ * Parses a hyphenation pattern file.
+ * @param source the InputSource for the file
+ * @throws HyphenationException In case of an exception while parsing
*/
- static XMLReader createParser() throws HyphenationException {
- String parserClassName = System.getProperty("org.xml.sax.parser");
- if (parserClassName == null) {
- parserClassName = "org.apache.xerces.parsers.SAXParser";
- }
- // System.out.println("using SAX parser " + parserClassName);
-
+ public void parse(InputSource source) throws HyphenationException {
try {
- return (XMLReader)Class.forName(parserClassName).newInstance();
- } catch (ClassNotFoundException e) {
- throw new HyphenationException("Could not find "
- + parserClassName);
- } catch (InstantiationException e) {
- throw new HyphenationException("Could not instantiate "
- + parserClassName);
- } catch (IllegalAccessException e) {
- throw new HyphenationException("Could not access "
- + parserClassName);
- } catch (ClassCastException e) {
- throw new HyphenationException(parserClassName
- + " is not a SAX driver");
+ parser.parse(source);
+ } catch (FileNotFoundException fnfe) {
+ throw new HyphenationException("File not found: " + fnfe.getMessage());
+ } catch (IOException ioe) {
+ throw new HyphenationException(ioe.getMessage());
+ } catch (SAXException e) {
+ throw new HyphenationException(errMsg);
}
}
-
+
/**
- * create an InputSource from a file name
- *
- * @param filename the name of the file
- * @return the InputSource created
+ * Creates a SAX parser using JAXP
+ * @return the created SAX parser
*/
- protected static InputSource fileInputSource(String filename)
- throws HyphenationException {
-
- /* this code adapted from James Clark's in XT */
- File file = new File(filename);
- String path = file.getAbsolutePath();
- String fSep = System.getProperty("file.separator");
- if (fSep != null && fSep.length() == 1) {
- path = path.replace(fSep.charAt(0), '/');
- }
- if (path.length() > 0 && path.charAt(0) != '/') {
- path = '/' + path;
- }
+ static XMLReader createParser() {
try {
- return new InputSource(new URL("file", null, path).toString());
- } catch (java.net.MalformedURLException e) {
- throw new HyphenationException("unexpected MalformedURLException");
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ return factory.newSAXParser().getXMLReader();
+ } catch (Exception e) {
+ throw new RuntimeException("Couldn't create XMLReader", e);
}
}
@@ -261,11 +249,11 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
}
//
- // DocumentHandler methods
+ // ContentHandler methods
//
/**
- * Start element.
+ * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String local, String raw,
Attributes attrs) {
@@ -293,6 +281,9 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
token.setLength(0);
}
+ /**
+ * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+ */
public void endElement(String uri, String local, String raw) {
if (token.length() > 0) {
@@ -328,7 +319,7 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
}
/**
- * Characters.
+ * @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char ch[], int start, int length) {
StringBuffer chars = new StringBuffer(length);
@@ -362,7 +353,7 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
//
/**
- * Warning.
+ * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException ex) {
errMsg = "[Warning] " + getLocationString(ex) + ": "
@@ -370,14 +361,14 @@ public class PatternParser extends DefaultHandler implements PatternConsumer {
}
/**
- * Error.
+ * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException ex) {
errMsg = "[Error] " + getLocationString(ex) + ": " + ex.getMessage();
}
/**
- * Fatal error.
+ * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException ex) throws SAXException {
errMsg = "[Fatal Error] " + getLocationString(ex) + ": "