1 11 12 package org.eclipse.jdt.internal.ui.text.spelling.engine; 13 14 import java.util.Collections ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.Locale ; 18 import java.util.Set ; 19 20 import org.eclipse.core.runtime.Assert; 21 22 import org.eclipse.jface.preference.IPreferenceStore; 23 24 import org.eclipse.jdt.ui.PreferenceConstants; 25 26 import org.eclipse.jdt.internal.ui.text.spelling.SpellingEngine; 27 28 33 public class DefaultSpellChecker implements ISpellChecker { 34 35 36 public static final String [] URL_PREFIXES= new String [] { "http://", "https://", "www.", "ftp://", "ftps://", "news://", "mailto://" }; 38 44 protected static boolean isDigits(final String word) { 45 46 for (int index= 0; index < word.length(); index++) { 47 48 if (Character.isDigit(word.charAt(index))) 49 return true; 50 } 51 return false; 52 } 53 54 65 protected static boolean isMixedCase(final String word, final boolean sentence) { 66 67 final int length= word.length(); 68 boolean upper= Character.isUpperCase(word.charAt(0)); 69 70 if (sentence && upper && (length > 1)) 71 upper= Character.isUpperCase(word.charAt(1)); 72 73 if (upper) { 74 75 for (int index= length - 1; index > 0; index--) { 76 if (Character.isLowerCase(word.charAt(index))) 77 return true; 78 } 79 } else { 80 81 for (int index= length - 1; index > 0; index--) { 82 if (Character.isUpperCase(word.charAt(index))) 83 return true; 84 } 85 } 86 return false; 87 } 88 89 97 protected static boolean isUpperCase(final String word) { 98 99 for (int index= word.length() - 1; index >= 0; index--) { 100 101 if (Character.isLowerCase(word.charAt(index))) 102 return false; 103 } 104 return true; 105 } 106 107 115 protected static boolean isUrl(final String word) { 116 117 for (int index= 0; index < URL_PREFIXES.length; index++) { 118 119 if (word.startsWith(URL_PREFIXES[index])) 120 return true; 121 } 122 return false; 123 } 124 125 129 private final Set fDictionaries= Collections.synchronizedSet(new HashSet ()); 130 131 134 private final Set fIgnored= Collections.synchronizedSet(new HashSet ()); 135 136 140 private final Set fListeners= Collections.synchronizedSet(new HashSet ()); 141 142 146 private final IPreferenceStore fPreferences; 147 148 152 private Locale fLocale; 153 154 160 public DefaultSpellChecker(IPreferenceStore store, Locale locale) { 161 Assert.isLegal(store != null); 162 Assert.isLegal(locale != null); 163 164 fPreferences= store; 165 fLocale= locale; 166 } 167 168 171 public final void addDictionary(final ISpellDictionary dictionary) { 172 fDictionaries.add(dictionary); 174 } 175 176 179 public final void addListener(final ISpellEventListener listener) { 180 fListeners.add(listener); 182 } 183 184 187 public boolean acceptsWords() { 188 Set copy; 192 synchronized (fDictionaries) { 193 copy= new HashSet (fDictionaries); 194 } 195 196 ISpellDictionary dictionary= null; 197 for (final Iterator iterator= copy.iterator(); iterator.hasNext();) { 198 199 dictionary= (ISpellDictionary)iterator.next(); 200 if (dictionary.acceptsWords()) 201 return true; 202 } 203 return false; 204 } 205 206 209 public void addWord(final String word) { 210 Set copy; 212 synchronized (fDictionaries) { 213 copy= new HashSet (fDictionaries); 214 } 215 216 final String addable= word.toLowerCase(); 217 for (final Iterator iterator= copy.iterator(); iterator.hasNext();) { 218 ISpellDictionary dictionary= (ISpellDictionary)iterator.next(); 219 if (dictionary.acceptsWords()) 220 dictionary.addWord(addable); 221 } 222 223 } 224 225 228 public final void checkWord(final String word) { 229 fIgnored.remove(word.toLowerCase()); 231 } 232 233 236 public void execute(final ISpellCheckIterator iterator) { 237 238 final boolean ignoreDigits= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_DIGITS); 239 final boolean ignoreMixed= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_MIXED); 240 final boolean ignoreSentence= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_SENTENCE); 241 final boolean ignoreUpper= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_UPPER); 242 final boolean ignoreURLS= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_URLS); 243 final boolean ignoreNonLetters= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_NON_LETTERS); 244 final boolean ignoreSingleLetters= fPreferences.getBoolean(PreferenceConstants.SPELLING_IGNORE_SINGLE_LETTERS); 245 final int problemsThreshold= PreferenceConstants.getPreferenceStore().getInt(SpellingEngine.SPELLING_PROBLEMS_THRESHOLD); 246 247 iterator.setIgnoreSingleLetters(ignoreSingleLetters); 248 249 Iterator iter= fDictionaries.iterator(); 250 while (iter.hasNext()) 251 ((ISpellDictionary)iter.next()).setStripNonLetters(ignoreNonLetters); 252 253 String word= null; 254 boolean starts= false; 255 int problemCount= 0; 256 257 while (problemCount <= problemsThreshold && iterator.hasNext()) { 258 259 word= (String )iterator.next(); 260 if (word != null) { 261 262 if (!fIgnored.contains(word)) { 264 265 starts= iterator.startsSentence(); 266 if (!isCorrect(word)) { 267 268 boolean isMixed= isMixedCase(word, true); 269 boolean isUpper= isUpperCase(word); 270 boolean isDigits= isDigits(word); 271 boolean isURL= isUrl(word); 272 273 if ( !ignoreMixed && isMixed || !ignoreUpper && isUpper || !ignoreDigits && isDigits || !ignoreURLS && isURL || !(isMixed || isUpper || isDigits || isURL)) { 274 fireEvent(new SpellEvent(this, word, iterator.getBegin(), iterator.getEnd(), starts, false)); 275 problemCount++; 276 } 277 278 } else { 279 280 if (!ignoreSentence && starts && Character.isLowerCase(word.charAt(0))) { 281 fireEvent(new SpellEvent(this, word, iterator.getBegin(), iterator.getEnd(), true, true)); 282 problemCount++; 283 } 284 } 285 } 286 } 287 } 288 } 289 290 296 protected final void fireEvent(final ISpellEvent event) { 297 Set copy; 299 synchronized (fListeners) { 300 copy= new HashSet (fListeners); 301 } 302 for (final Iterator iterator= copy.iterator(); iterator.hasNext();) { 303 ((ISpellEventListener)iterator.next()).handle(event); 304 } 305 } 306 307 310 public Set getProposals(final String word, final boolean sentence) { 311 312 Set copy; 316 synchronized (fDictionaries) { 317 copy= new HashSet (fDictionaries); 318 } 319 320 ISpellDictionary dictionary= null; 321 final HashSet proposals= new HashSet (); 322 323 for (final Iterator iterator= copy.iterator(); iterator.hasNext();) { 324 325 dictionary= (ISpellDictionary)iterator.next(); 326 proposals.addAll(dictionary.getProposals(word, sentence)); 327 } 328 return proposals; 329 } 330 331 334 public final void ignoreWord(final String word) { 335 fIgnored.add(word.toLowerCase()); 337 } 338 339 342 public final boolean isCorrect(final String word) { 343 Set copy; 345 synchronized (fDictionaries) { 346 copy= new HashSet (fDictionaries); 347 } 348 349 if (fIgnored.contains(word.toLowerCase())) 350 return true; 351 352 ISpellDictionary dictionary= null; 353 for (final Iterator iterator= copy.iterator(); iterator.hasNext();) { 354 355 dictionary= (ISpellDictionary)iterator.next(); 356 if (dictionary.isCorrect(word)) 357 return true; 358 } 359 return false; 360 } 361 362 365 public final void removeDictionary(final ISpellDictionary dictionary) { 366 fDictionaries.remove(dictionary); 368 } 369 370 373 public final void removeListener(final ISpellEventListener listener) { 374 fListeners.remove(listener); 376 } 377 378 382 public Locale getLocale() { 383 return fLocale; 384 } 385 } 386 | Popular Tags |