1 17 18 19 20 package org.apache.fop.hyphenation; 21 22 import java.io.BufferedInputStream ; 23 import java.io.File ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.ObjectInputStream ; 27 28 import javax.xml.transform.Source ; 29 import javax.xml.transform.stream.StreamSource ; 30 31 import org.apache.commons.io.IOUtils; 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.xml.sax.InputSource ; 35 36 42 public class Hyphenator { 43 44 45 protected static Log log = LogFactory.getLog(Hyphenator.class); 46 47 private static HyphenationTreeCache hTreeCache = null; 48 49 private HyphenationTree hyphenTree = null; 50 private int remainCharCount = 2; 51 private int pushCharCount = 2; 52 53 private static boolean statisticsDump = false; 54 55 62 public Hyphenator(String lang, String country, int leftMin, 63 int rightMin) { 64 hyphenTree = getHyphenationTree(lang, country); 65 remainCharCount = leftMin; 66 pushCharCount = rightMin; 67 } 68 69 70 public static synchronized HyphenationTreeCache getHyphenationTreeCache() { 71 if (hTreeCache == null) { 72 hTreeCache = new HyphenationTreeCache(); 73 } 74 return hTreeCache; 75 } 76 77 84 public static HyphenationTree getHyphenationTree(String lang, 85 String country) { 86 return getHyphenationTree(lang, country, null); 87 } 88 89 97 public static HyphenationTree getHyphenationTree(String lang, 98 String country, HyphenationTreeResolver resolver) { 99 String key = HyphenationTreeCache.constructKey(lang, country); 100 HyphenationTreeCache cache = getHyphenationTreeCache(); 101 102 if (cache.isMissing(key)) { 104 return null; 105 } 106 107 HyphenationTree hTree; 108 hTree = getHyphenationTreeCache().getHyphenationTree(lang, country); 110 if (hTree != null) { 111 return hTree; 112 } 113 114 if (resolver != null) { 115 hTree = getUserHyphenationTree(key, resolver); 116 } 117 if (hTree == null) { 118 hTree = getFopHyphenationTree(key); 119 } 120 121 if (hTree != null) { 123 cache.cache(key, hTree); 124 } else { 125 log.error("Couldn't find hyphenation pattern " + key); 126 cache.noteMissing(key); 127 } 128 return hTree; 129 } 130 131 private static InputStream getResourceStream(String key) { 132 InputStream is = null; 133 try { 135 java.lang.reflect.Method getCCL = Thread .class.getMethod( 136 "getContextClassLoader", new Class [0]); 137 if (getCCL != null) { 138 ClassLoader contextClassLoader = (ClassLoader )getCCL.invoke( 139 Thread.currentThread(), 140 new Object [0]); 141 is = contextClassLoader.getResourceAsStream("hyph/" + key 142 + ".hyp"); 143 } 144 } catch (Exception e) { 145 } 147 148 if (is == null) { 149 is = Hyphenator.class.getResourceAsStream("/hyph/" + key 150 + ".hyp"); 151 } 152 153 return is; 154 } 155 156 private static HyphenationTree readHyphenationTree(InputStream in) { 157 HyphenationTree hTree = null; 158 try { 159 ObjectInputStream ois = new ObjectInputStream (in); 160 hTree = (HyphenationTree)ois.readObject(); 161 } catch (IOException ioe) { 162 log.error("I/O error while loading precompiled hyphenation pattern file", ioe); 163 } catch (ClassNotFoundException cnfe) { 164 log.error("Error while reading hyphenation object from file", cnfe); 165 } 166 return hTree; 167 } 168 169 175 public static HyphenationTree getFopHyphenationTree(String key) { 176 HyphenationTree hTree = null; 177 ObjectInputStream ois = null; 178 InputStream is = null; 179 try { 180 is = getResourceStream(key); 181 if (is == null) { 182 if (key.length() == 5) { 183 String lang = key.substring(0, 2); 184 is = getResourceStream(lang); 185 if (is != null) { 186 if (log.isDebugEnabled()) { 187 log.debug("Couldn't find hyphenation pattern '" 188 + key 189 + "'. Using general language pattern '" 190 + lang 191 + "' instead."); 192 } 193 } else { 194 if (log.isDebugEnabled()) { 195 log.debug("Couldn't find precompiled hyphenation pattern " 196 + lang + " in resources."); 197 } 198 return null; 199 } 200 } else { 201 if (log.isDebugEnabled()) { 202 log.debug("Couldn't find precompiled hyphenation pattern " 203 + key + " in resources"); 204 } 205 return null; 206 } 207 } 208 hTree = readHyphenationTree(is); 209 } finally { 210 IOUtils.closeQuietly(ois); 211 } 212 return hTree; 213 } 214 215 222 public static HyphenationTree getUserHyphenationTree(String key, 223 String hyphenDir) { 224 final File baseDir = new File (hyphenDir); 225 HyphenationTreeResolver resolver = new HyphenationTreeResolver() { 226 public Source resolve(String href) { 227 File f = new File (baseDir, href); 228 return new StreamSource (f); 229 } 230 }; 231 return getUserHyphenationTree(key, resolver); 232 } 233 234 241 public static HyphenationTree getUserHyphenationTree(String key, 242 HyphenationTreeResolver resolver) { 243 HyphenationTree hTree = null; 244 249 String name = key + ".hyp"; 251 Source source = resolver.resolve(name); 252 if (source != null) { 253 try { 254 InputStream in = null; 255 if (source instanceof StreamSource ) { 256 in = ((StreamSource ) source).getInputStream(); 257 } 258 if (in == null && source.getSystemId() != null) { 259 in = new java.net.URL (source.getSystemId()).openStream(); 260 } else { 261 throw new UnsupportedOperationException ("Cannot load hyphenation pattern file" 262 + " with the supplied Source object: " + source); 263 } 264 in = new BufferedInputStream (in); 265 try { 266 hTree = readHyphenationTree(in); 267 } finally { 268 IOUtils.closeQuietly(in); 269 } 270 return hTree; 271 } catch (IOException ioe) { 272 if (log.isDebugEnabled()) { 273 log.debug("I/O problem while trying to load " + name, ioe); 274 } 275 } 276 } 277 278 name = key + ".xml"; 280 source = resolver.resolve(name); 281 if (source != null) { 282 hTree = new HyphenationTree(); 283 try { 284 InputStream in = null; 285 if (source instanceof StreamSource ) { 286 in = ((StreamSource ) source).getInputStream(); 287 } 288 if (in == null) { 289 if (source.getSystemId() != null) { 290 in = new java.net.URL (source.getSystemId()).openStream(); 291 } else { 292 throw new UnsupportedOperationException ( 293 "Cannot load hyphenation pattern file" 294 + " with the supplied Source object: " + source); 295 } 296 } 297 if (!(in instanceof BufferedInputStream )) { 298 in = new BufferedInputStream (in); 299 } 300 try { 301 InputSource src = new InputSource (in); 302 src.setSystemId(source.getSystemId()); 303 hTree.loadPatterns(src); 304 } finally { 305 IOUtils.closeQuietly(in); 306 } 307 if (statisticsDump) { 308 System.out.println("Stats: "); 309 hTree.printStats(); 310 } 311 return hTree; 312 } catch (HyphenationException ex) { 313 log.error("Can't load user patterns from XML file " + source.getSystemId() 314 + ": " + ex.getMessage()); 315 return null; 316 } catch (IOException ioe) { 317 if (log.isDebugEnabled()) { 318 log.debug("I/O problem while trying to load " + name, ioe); 319 } 320 return null; 321 } 322 } else { 323 if (log.isDebugEnabled()) { 324 log.debug("Could not load user hyphenation file for '" + key + "'."); 325 } 326 return null; 327 } 328 } 329 330 340 public static Hyphenation hyphenate(String lang, String country, 341 HyphenationTreeResolver resolver, 342 String word, 343 int leftMin, int rightMin) { 344 HyphenationTree hTree = getHyphenationTree(lang, country, resolver); 345 if (hTree == null) { 346 return null; 347 } 348 return hTree.hyphenate(word, leftMin, rightMin); 349 } 350 351 360 public static Hyphenation hyphenate(String lang, String country, 361 String word, 362 int leftMin, int rightMin) { 363 return hyphenate(lang, country, null, word, leftMin, rightMin); 364 } 365 366 378 public static Hyphenation hyphenate(String lang, String country, 379 HyphenationTreeResolver resolver, 380 char[] word, int offset, int len, 381 int leftMin, int rightMin) { 382 HyphenationTree hTree = getHyphenationTree(lang, country, resolver); 383 if (hTree == null) { 384 return null; 385 } 386 return hTree.hyphenate(word, offset, len, leftMin, rightMin); 387 } 388 389 400 public static Hyphenation hyphenate(String lang, String country, 401 char[] word, int offset, int len, 402 int leftMin, int rightMin) { 403 return hyphenate(lang, country, null, word, offset, len, leftMin, rightMin); 404 } 405 406 410 public void setMinRemainCharCount(int min) { 411 remainCharCount = min; 412 } 413 414 418 public void setMinPushCharCount(int min) { 419 pushCharCount = min; 420 } 421 422 427 public void setLanguage(String lang, String country) { 428 hyphenTree = getHyphenationTree(lang, country); 429 } 430 431 438 public Hyphenation hyphenate(char[] word, int offset, int len) { 439 if (hyphenTree == null) { 440 return null; 441 } 442 return hyphenTree.hyphenate(word, offset, len, remainCharCount, 443 pushCharCount); 444 } 445 446 451 public Hyphenation hyphenate(String word) { 452 if (hyphenTree == null) { 453 return null; 454 } 455 return hyphenTree.hyphenate(word, remainCharCount, pushCharCount); 456 } 457 458 } 459 | Popular Tags |