/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.text.spelling; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Set; import net.sourceforge.phpdt.internal.ui.PHPUIMessages; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.DefaultSpellChecker; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckEngine; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellCheckPreferenceKeys; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellChecker; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.ISpellDictionary; import net.sourceforge.phpdt.internal.ui.text.spelling.engine.PersistentSpellDictionary; import net.sourceforge.phpeclipse.ui.WebUI; //import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; /** * Spell check engine for Java source spell checking. * * @since 3.0 */ public class SpellCheckEngine implements ISpellCheckEngine, IPropertyChangeListener { /** The dictionary location */ public static final String DICTIONARY_LOCATION = "dictionaries/"; //$NON-NLS-1$ /** The singleton spell checker instance */ private static ISpellChecker fChecker = null; /** The singleton engine instance */ private static ISpellCheckEngine fEngine = null; /** * Returns the available locales for this spell check engine. * * @return The available locales for this engine */ public static Set getAvailableLocales() { URL url = null; Locale locale = null; InputStream stream = null; final Set result = new HashSet(); try { final URL location = getDictionaryLocation(); final Locale[] locales = Locale.getAvailableLocales(); for (int index = 0; index < locales.length; index++) { locale = locales[index]; url = new URL( location, locale.toString().toLowerCase() + "." + PHPUIMessages.getString("Spelling.dictionary.file.extension")); //$NON-NLS-1$ //$NON-NLS-2$ try { stream = url.openStream(); if (stream != null) { try { result.add(locale); } finally { stream.close(); } } } catch (IOException exception) { // Do nothing } } } catch (MalformedURLException exception) { // Do nothing } result.add(getDefaultLocale()); return result; } /** * Returns the default locale for this engine. * * @return The default locale */ public static Locale getDefaultLocale() { return Locale.US; } /** * Returns the dictionary location. * * @throws MalformedURLException * if the URL could not be created * @return The dictionary location, or null iff the location * is not known */ public static URL getDictionaryLocation() throws MalformedURLException { final WebUI plugin = WebUI.getDefault(); if (plugin != null) return plugin.getBundle().getEntry("/" + DICTIONARY_LOCATION); //$NON-NLS-1$ return null; } /** * Returns the singleton instance of the spell check engine. * * @return The singleton instance of the spell check engine */ public static final synchronized ISpellCheckEngine getInstance() { if (fEngine == null) fEngine = new SpellCheckEngine(); return fEngine; } /** The registered locale insenitive dictionaries */ private final Set fGlobalDictionaries = new HashSet(); /** The current locale */ private Locale fLocale = null; /** The registered locale sensitive dictionaries */ private final Map fLocaleDictionaries = new HashMap(); /** The preference store where to listen */ private IPreferenceStore fPreferences = null; /** The user dictionary */ private ISpellDictionary fUserDictionary = null; /** * Creates a new spell check manager. */ private SpellCheckEngine() { fGlobalDictionaries.add(new TaskTagDictionary()); fGlobalDictionaries.add(new HtmlTagDictionary()); fGlobalDictionaries.add(new JavaDocTagDictionary()); try { Locale locale = null; final URL location = getDictionaryLocation(); for (final Iterator iterator = getAvailableLocales().iterator(); iterator .hasNext();) { locale = (Locale) iterator.next(); fLocaleDictionaries.put(locale, new SpellReconcileDictionary( locale, location)); } } catch (MalformedURLException exception) { // Do nothing } } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#createSpellChecker(java.util.Locale,org.eclipse.jface.preference.IPreferenceStore) */ public final synchronized ISpellChecker createSpellChecker( final Locale locale, final IPreferenceStore store) { if (fLocale != null && fLocale.equals(locale)) return fChecker; if (fChecker == null) { fChecker = new DefaultSpellChecker(store); store.addPropertyChangeListener(this); fPreferences = store; ISpellDictionary dictionary = null; for (Iterator iterator = fGlobalDictionaries.iterator(); iterator .hasNext();) { dictionary = (ISpellDictionary) iterator.next(); fChecker.addDictionary(dictionary); } } ISpellDictionary dictionary = null; if (fLocale != null) { dictionary = (ISpellDictionary) fLocaleDictionaries.get(fLocale); if (dictionary != null) { fChecker.removeDictionary(dictionary); dictionary.unload(); } } fLocale = locale; dictionary = (ISpellDictionary) fLocaleDictionaries.get(locale); if (dictionary == null) { if (!getDefaultLocale().equals(locale)) { if (fPreferences != null) fPreferences.removePropertyChangeListener(this); fChecker = null; fLocale = null; } } else fChecker.addDictionary(dictionary); if (fPreferences != null) propertyChange(new PropertyChangeEvent( this, ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY, null, fPreferences .getString(ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY))); return fChecker; } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#getLocale() */ public final Locale getLocale() { return fLocale; } /* * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public final void propertyChange(final PropertyChangeEvent event) { if (fChecker != null && event.getProperty().equals( ISpellCheckPreferenceKeys.SPELLING_USER_DICTIONARY)) { if (fUserDictionary != null) { fChecker.removeDictionary(fUserDictionary); fUserDictionary = null; } final String file = (String) event.getNewValue(); if (file.length() > 0) { try { final URL url = new URL("file", null, file); //$NON-NLS-1$ InputStream stream = url.openStream(); if (stream != null) { try { fUserDictionary = new PersistentSpellDictionary(url); fChecker.addDictionary(fUserDictionary); } finally { stream.close(); } } } catch (MalformedURLException exception) { // Do nothing } catch (IOException exception) { // Do nothing } } } } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary) */ public synchronized final void registerDictionary( final ISpellDictionary dictionary) { fGlobalDictionaries.add(dictionary); if (fChecker != null) fChecker.addDictionary(dictionary); } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(java.util.Locale,net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary) */ public synchronized final void registerDictionary(final Locale locale, final ISpellDictionary dictionary) { fLocaleDictionaries.put(locale, dictionary); if (fChecker != null && fLocale != null && fLocale.equals(locale)) fChecker.addDictionary(dictionary); } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#unload() */ public synchronized final void unload() { ISpellDictionary dictionary = null; for (final Iterator iterator = fGlobalDictionaries.iterator(); iterator .hasNext();) { dictionary = (ISpellDictionary) iterator.next(); dictionary.unload(); } for (final Iterator iterator = fLocaleDictionaries.values().iterator(); iterator .hasNext();) { dictionary = (ISpellDictionary) iterator.next(); dictionary.unload(); } if (fPreferences != null) fPreferences.removePropertyChangeListener(this); fUserDictionary = null; fChecker = null; } /* * @see net.sourceforge.phpdt.ui.text.spelling.engine.ISpellCheckEngine#unregisterDictionary(net.sourceforge.phpdt.ui.text.spelling.engine.ISpellDictionary) */ public synchronized final void unregisterDictionary( final ISpellDictionary dictionary) { fGlobalDictionaries.remove(dictionary); fLocaleDictionaries.values().remove(dictionary); if (fChecker != null) fChecker.removeDictionary(dictionary); dictionary.unload(); } }