1 11 12 package org.eclipse.jdt.internal.ui.text.spelling; 13 14 import java.io.File ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.net.MalformedURLException ; 18 import java.net.URL ; 19 import java.util.Collections ; 20 import java.util.Enumeration ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.Locale ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import java.util.Map.Entry; 28 29 import org.eclipse.core.runtime.FileLocator; 30 31 import org.eclipse.jface.preference.IPreferenceStore; 32 import org.eclipse.jface.util.IPropertyChangeListener; 33 import org.eclipse.jface.util.PropertyChangeEvent; 34 35 import org.eclipse.jdt.ui.PreferenceConstants; 36 37 import org.eclipse.jdt.internal.ui.JavaPlugin; 38 import org.eclipse.jdt.internal.ui.text.spelling.engine.DefaultSpellChecker; 39 import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellCheckEngine; 40 import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellChecker; 41 import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellDictionary; 42 import org.eclipse.jdt.internal.ui.text.spelling.engine.LocaleSensitiveSpellDictionary; 43 import org.eclipse.jdt.internal.ui.text.spelling.engine.PersistentSpellDictionary; 44 45 50 public class SpellCheckEngine implements ISpellCheckEngine, IPropertyChangeListener { 51 52 53 public static final String DICTIONARY_LOCATION= "dictionaries/"; 55 56 private static ISpellCheckEngine fgEngine= null; 57 58 63 private static Set fgLocalesWithInstalledDictionaries; 64 65 72 private static Set getLocalesWithInstalledDictionaries(URL location) { 73 String [] fileNames; 74 try { 75 URL url= FileLocator.toFileURL(location); 76 File file= new File (url.getFile()); 77 if (!file.isDirectory()) 78 return Collections.EMPTY_SET; 79 fileNames= file.list(); 80 if (fileNames == null) 81 return Collections.EMPTY_SET; 82 } catch (IOException ex) { 83 JavaPlugin.log(ex); 84 return Collections.EMPTY_SET; 85 } 86 87 Set localesWithInstalledDictionaries= new HashSet (); 88 int fileNameCount= fileNames.length; 89 for (int i= 0; i < fileNameCount; i++) { 90 String fileName= fileNames[i]; 91 int localeEnd= fileName.indexOf(".dictionary"); if (localeEnd > 1) { 93 String localeName= fileName.substring(0, localeEnd); 94 int languageEnd=localeName.indexOf('_'); 95 if (languageEnd == -1) 96 localesWithInstalledDictionaries.add(new Locale (localeName)); 97 else if (languageEnd == 2 && localeName.length() == 5) 98 localesWithInstalledDictionaries.add(new Locale (localeName.substring(0, 2), localeName.substring(3))); 99 else if (localeName.length() > 6 && localeName.charAt(5) == '_') 100 localesWithInstalledDictionaries.add(new Locale (localeName.substring(0, 2), localeName.substring(3, 5), localeName.substring(6))); 101 } 102 } 103 104 return localesWithInstalledDictionaries; 105 } 106 107 108 114 public static Set getLocalesWithInstalledDictionaries() { 115 if (fgLocalesWithInstalledDictionaries != null) 116 return fgLocalesWithInstalledDictionaries; 117 118 Enumeration locations; 119 try { 120 locations= getDictionaryLocations(); 121 if (locations == null) 122 return fgLocalesWithInstalledDictionaries= Collections.EMPTY_SET; 123 } catch (IOException ex) { 124 JavaPlugin.log(ex); 125 return fgLocalesWithInstalledDictionaries= Collections.EMPTY_SET; 126 } 127 128 fgLocalesWithInstalledDictionaries= new HashSet (); 129 130 while (locations.hasMoreElements()) { 131 URL location= (URL ) locations.nextElement(); 132 Set locales= getLocalesWithInstalledDictionaries(location); 133 fgLocalesWithInstalledDictionaries.addAll(locales); 134 } 135 136 return fgLocalesWithInstalledDictionaries; 137 } 138 139 144 public static Locale getDefaultLocale() { 145 return Locale.getDefault(); 146 } 147 148 155 public ISpellDictionary findDictionary(Locale locale) { 156 ISpellDictionary dictionary= (ISpellDictionary)fLocaleDictionaries.get(locale); 157 if (dictionary != null) 158 return dictionary; 159 160 String language= locale.getLanguage(); 162 Iterator iter= fLocaleDictionaries.entrySet().iterator(); 163 while (iter.hasNext()) { 164 Entry entry= (Entry)iter.next(); 165 Locale dictLocale= (Locale )entry.getKey(); 166 if (dictLocale.getLanguage().equals(language)) 167 return (ISpellDictionary)entry.getValue(); 168 } 169 170 return null; 171 } 172 173 177 public static Locale findClosestLocale(Locale locale) { 178 if (locale == null || locale.toString().length() == 0) 179 return locale; 180 181 if (getLocalesWithInstalledDictionaries().contains(locale)) 182 return locale; 183 184 String language= locale.getLanguage(); 186 Iterator iter= getLocalesWithInstalledDictionaries().iterator(); 187 while (iter.hasNext()) { 188 Locale dictLocale= (Locale )iter.next(); 189 if (dictLocale.getLanguage().equals(language)) 190 return dictLocale; 191 } 192 193 Locale defaultLocale= Locale.US; 195 if (getLocalesWithInstalledDictionaries().contains(defaultLocale)) 196 return defaultLocale; 197 198 return null; 199 } 200 201 212 public static Enumeration getDictionaryLocations() throws IOException { 213 final JavaPlugin plugin= JavaPlugin.getDefault(); 214 if (plugin != null) 215 return plugin.getBundle().getResources("/" + DICTIONARY_LOCATION); return null; 217 } 218 219 224 public static final synchronized ISpellCheckEngine getInstance() { 225 226 if (fgEngine == null) 227 fgEngine= new SpellCheckEngine(); 228 229 return fgEngine; 230 } 231 232 235 public static final synchronized void shutdownInstance() { 236 if (fgEngine != null) { 237 fgEngine.shutdown(); 238 fgEngine= null; 239 } 240 } 241 242 243 private Set fGlobalDictionaries= new HashSet (); 244 245 246 private ISpellChecker fChecker= null; 247 248 249 private Map fLocaleDictionaries= new HashMap (); 250 251 252 private ISpellDictionary fUserDictionary= null; 253 254 257 private SpellCheckEngine() { 258 259 fGlobalDictionaries.add(new TaskTagDictionary()); 260 fGlobalDictionaries.add(new HtmlTagDictionary()); 261 fGlobalDictionaries.add(new JavaDocTagDictionary()); 262 263 try { 264 265 Locale locale= null; 266 final Enumeration locations= getDictionaryLocations(); 267 268 while (locations != null && locations.hasMoreElements()) { 269 URL location= (URL )locations.nextElement(); 270 271 for (final Iterator iterator= getLocalesWithInstalledDictionaries(location).iterator(); iterator.hasNext();) { 272 273 locale= (Locale )iterator.next(); 274 fLocaleDictionaries.put(locale, new LocaleSensitiveSpellDictionary(locale, location)); 275 } 276 } 277 278 } catch (IOException exception) { 279 } 281 282 JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); 283 } 284 285 288 public final synchronized ISpellChecker getSpellChecker() throws IllegalStateException { 289 if (fGlobalDictionaries == null) 290 throw new IllegalStateException ("spell checker has been shut down"); 292 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 293 Locale locale= getCurrentLocale(store); 294 if (fUserDictionary == null && "".equals(locale.toString())) return null; 296 297 if (fChecker != null && fChecker.getLocale().equals(locale)) 298 return fChecker; 299 300 resetSpellChecker(); 301 302 fChecker= new DefaultSpellChecker(store, locale); 303 resetUserDictionary(); 304 305 for (Iterator iterator= fGlobalDictionaries.iterator(); iterator.hasNext();) { 306 ISpellDictionary dictionary= (ISpellDictionary)iterator.next(); 307 fChecker.addDictionary(dictionary); 308 } 309 310 ISpellDictionary dictionary= findDictionary(fChecker.getLocale()); 311 if (dictionary != null) 312 fChecker.addDictionary(dictionary); 313 314 return fChecker; 315 } 316 317 323 private Locale getCurrentLocale(IPreferenceStore store) { 324 return convertToLocale(store.getString(PreferenceConstants.SPELLING_LOCALE)); 325 } 326 327 public static Locale convertToLocale(String locale) { 328 Locale defaultLocale= SpellCheckEngine.getDefaultLocale(); 329 if (locale.equals(defaultLocale.toString())) 330 return defaultLocale; 331 332 if (locale.length() >= 5) 333 return new Locale (locale.substring(0, 2), locale.substring(3, 5)); 334 335 return new Locale (""); } 337 338 341 public synchronized final Locale getLocale() { 342 if (fChecker == null) 343 return null; 344 345 return fChecker.getLocale(); 346 } 347 348 351 public final void propertyChange(final PropertyChangeEvent event) { 352 if (event.getProperty().equals(PreferenceConstants.SPELLING_LOCALE)) { 353 resetSpellChecker(); 354 return; 355 } 356 357 if (event.getProperty().equals(PreferenceConstants.SPELLING_USER_DICTIONARY)) { 358 resetUserDictionary(); 359 return; 360 } 361 362 if (event.getProperty().equals(PreferenceConstants.SPELLING_USER_DICTIONARY_ENCODING)) { 363 resetUserDictionary(); 364 return; 365 } 366 } 367 368 371 private synchronized void resetUserDictionary() { 372 if (fChecker == null) 373 return; 374 375 if (fUserDictionary != null) { 377 fChecker.removeDictionary(fUserDictionary); 378 fUserDictionary.unload(); 379 fUserDictionary= null; 380 } 381 382 IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); 383 final String filePath= store.getString(PreferenceConstants.SPELLING_USER_DICTIONARY); 384 if (filePath.length() > 0) { 385 try { 386 File file= new File (filePath); 387 if (!file.exists() && !file.createNewFile()) 388 return; 389 390 final URL url= new URL ("file", null, filePath); InputStream stream= url.openStream(); 392 if (stream != null) { 393 try { 394 fUserDictionary= new PersistentSpellDictionary(url); 395 fChecker.addDictionary(fUserDictionary); 396 } finally { 397 stream.close(); 398 } 399 } 400 } catch (MalformedURLException exception) { 401 } catch (IOException exception) { 403 } 405 } 406 } 407 408 411 public synchronized final void registerGlobalDictionary(final ISpellDictionary dictionary) { 412 fGlobalDictionaries.add(dictionary); 413 resetSpellChecker(); 414 } 415 416 419 public synchronized final void registerDictionary(final Locale locale, final ISpellDictionary dictionary) { 420 fLocaleDictionaries.put(locale, dictionary); 421 resetSpellChecker(); 422 } 423 424 427 public synchronized final void shutdown() { 428 429 JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); 430 431 ISpellDictionary dictionary= null; 432 for (final Iterator iterator= fGlobalDictionaries.iterator(); iterator.hasNext();) { 433 dictionary= (ISpellDictionary)iterator.next(); 434 dictionary.unload(); 435 } 436 fGlobalDictionaries= null; 437 438 for (final Iterator iterator= fLocaleDictionaries.values().iterator(); iterator.hasNext();) { 439 dictionary= (ISpellDictionary)iterator.next(); 440 dictionary.unload(); 441 } 442 fLocaleDictionaries= null; 443 444 fUserDictionary= null; 445 fChecker= null; 446 } 447 448 private synchronized void resetSpellChecker() { 449 if (fChecker != null) { 450 ISpellDictionary dictionary= (ISpellDictionary)fLocaleDictionaries.get(fChecker.getLocale()); 451 if (dictionary != null) 452 dictionary.unload(); 453 } 454 fChecker= null; 455 } 456 457 460 public synchronized final void unregisterDictionary(final ISpellDictionary dictionary) { 461 fGlobalDictionaries.remove(dictionary); 462 fLocaleDictionaries.values().remove(dictionary); 463 dictionary.unload(); 464 resetSpellChecker(); 465 } 466 } 467 | Popular Tags |