blob: 3e8fb3f9dfa3bf1eee65e986d1b24553110ccfb5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.text.spelling;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
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 org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.text.spelling.engine.DefaultSpellChecker;
import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellCheckEngine;
import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellCheckPreferenceKeys;
import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellChecker;
import org.eclipse.jdt.internal.ui.text.spelling.engine.ISpellDictionary;
import org.eclipse.jdt.internal.ui.text.spelling.engine.PersistentSpellDictionary;
/**
* 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 engine instance */
private static ISpellCheckEngine fgEngine= 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();
if (location == null)
return Collections.EMPTY_SET;
final Locale[] locales= Locale.getAvailableLocales();
for (int index= 0; index < locales.length; index++) {
locale= locales[index];
url= new URL(location, locale.toString().toLowerCase() + ".dictionary"); //$NON-NLS-1$
try {
stream= url.openStream();
if (stream != null) {
try {
result.add(locale);
} finally {
stream.close();
}
}
} catch (IOException exception) {
// Do nothing
}
}
} catch (MalformedURLException exception) {
// Do nothing
}
return result;
}
/**
* Returns the default locale for this engine.
*
* @return The default locale
*/
public static Locale getDefaultLocale() {
return Locale.getDefault();
}
/**
* Returns the dictionary location.
*
* @throws MalformedURLException
* if the URL could not be created
* @return The dictionary location, or <code>null</code> iff the location
* is not known
*/
public static URL getDictionaryLocation() throws MalformedURLException {
final JavaPlugin plugin= JavaPlugin.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 (fgEngine == null)
fgEngine= new SpellCheckEngine();
return fgEngine;
}
/** The registered locale insenitive dictionaries */
private final Set fGlobalDictionaries= new HashSet();
/** The current locale */
private Locale fLocale= null;
/** The spell checker for fLocale */
private ISpellChecker fChecker= 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 org.eclipse.jdt.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 org.eclipse.jdt.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 org.eclipse.jdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(org.eclipse.jdt.ui.text.spelling.engine.ISpellDictionary)
*/
public synchronized final void registerDictionary(final ISpellDictionary dictionary) {
fGlobalDictionaries.add(dictionary);
if (fChecker != null)
fChecker.addDictionary(dictionary);
}
/*
* @see org.eclipse.jdt.ui.text.spelling.engine.ISpellCheckEngine#registerDictionary(java.util.Locale,org.eclipse.jdt.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 org.eclipse.jdt.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 org.eclipse.jdt.ui.text.spelling.engine.ISpellCheckEngine#unregisterDictionary(org.eclipse.jdt.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();
}
}