Spellchecker - do not produce out-of-element inspection highlight ranges
[fedora-idea.git] / plugins / spellchecker / src / com / intellij / spellchecker / SpellCheckerManager.java
blob600b1d77111a9af06861cd4f1d359f67c1ceff74
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.spellchecker;
18 import com.intellij.codeHighlighting.HighlightDisplayLevel;
19 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.components.ServiceManager;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.extensions.Extensions;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.project.ProjectManager;
26 import com.intellij.spellchecker.dictionary.Dictionary;
27 import com.intellij.spellchecker.dictionary.Loader;
28 import com.intellij.spellchecker.engine.SpellCheckerEngine;
29 import com.intellij.spellchecker.engine.SpellCheckerFactory;
30 import com.intellij.spellchecker.engine.SuggestionProvider;
31 import com.intellij.spellchecker.settings.SpellCheckerSettings;
32 import com.intellij.spellchecker.state.StateLoader;
33 import com.intellij.spellchecker.util.SPFileUtil;
34 import com.intellij.spellchecker.util.Strings;
35 import com.intellij.util.Consumer;
36 import com.sun.net.ssl.internal.ssl.SSLEngineImpl;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
40 import java.io.InputStream;
41 import java.util.*;
43 public class SpellCheckerManager {
45 private static final Logger LOG = Logger.getInstance("#com.intellij.spellchecker.SpellCheckerManager");
47 private static final int MAX_SUGGESTIONS_THRESHOLD = 5;
48 private static final int MAX_METRICS = 1;
50 private Project project;
52 private SpellCheckerEngine spellChecker;
54 private Dictionary userDictionary;
58 @NotNull
59 private final SuggestionProvider suggestionProvider = new BaseSuggestionProvider(this);
61 private final SpellCheckerSettings settings;
63 public static SpellCheckerManager getInstance(Project project) {
64 return ServiceManager.getService(project, SpellCheckerManager.class);
67 public SpellCheckerManager(Project project, SpellCheckerSettings settings) {
68 this.project = project;
69 this.settings = settings;
70 reloadConfiguration();
74 public Project getProject() {
75 return project;
78 public Dictionary getUserDictionary() {
79 return userDictionary;
82 public void reloadConfiguration() {
83 spellChecker = SpellCheckerFactory.create();
84 fillEngineDictionary();
87 private void fillEngineDictionary() {
88 spellChecker.reset();
89 final StateLoader stateLoader = new StateLoader(project);
90 final List<Loader> loaders = new ArrayList<Loader>();
91 // Load bundled dictionaries from corresponding jars
92 for (BundledDictionaryProvider provider : Extensions.getExtensions(BundledDictionaryProvider.EP_NAME)) {
93 for (String dictionary : provider.getBundledDictionaries()) {
94 if (this.settings == null || !this.settings.getBundledDisabledDictionariesPaths().contains(dictionary)) {
95 final Class<? extends BundledDictionaryProvider> loaderClass = provider.getClass();
96 final InputStream stream = loaderClass.getResourceAsStream(dictionary);
97 if (stream != null){
98 loaders.add(new StreamLoader(stream));
99 } else {
100 LOG.warn("Couldn't load dictionary '" + dictionary + "' for loader '" + loaderClass + "'");
105 if (this.settings != null && this.settings.getDictionaryFoldersPaths() != null) {
106 final Set<String> disabledDictionaries = settings.getDisabledDictionariesPaths();
107 for (String folder : this.settings.getDictionaryFoldersPaths()) {
108 SPFileUtil.processFilesRecursively(folder, new Consumer<String>() {
109 public void consume(final String s) {
110 if (!disabledDictionaries.contains(s)) {
111 loaders.add(new FileLoader(s));
118 loaders.add(stateLoader);
119 for (Loader loader : loaders) {
120 spellChecker.loadDictionary(loader);
122 userDictionary = stateLoader.getDictionary();
126 public boolean hasProblem(@NotNull String word) {
127 return !spellChecker.isCorrect(word);
130 public void acceptWordAsCorrect(@NotNull String word) {
131 final String transformed = spellChecker.getTransformation().transform(word);
132 if (transformed != null) {
133 userDictionary.addToDictionary(transformed);
134 spellChecker.addToDictionary(transformed);
138 public void update(@Nullable Collection<String> words, SpellCheckerSettings allDictionaries) {
139 reloadConfiguration();
140 restartInspections();
144 @NotNull
145 public List<String> getBundledDictionaries() {
146 final ArrayList<String> dictionaries = new ArrayList<String>();
147 for (BundledDictionaryProvider provider : Extensions.getExtensions(BundledDictionaryProvider.EP_NAME)) {
148 dictionaries.addAll(Arrays.asList(provider.getBundledDictionaries()));
150 return dictionaries;
153 @NotNull
154 public static HighlightDisplayLevel getHighlightDisplayLevel() {
155 return HighlightDisplayLevel.find(SpellCheckerSeveritiesProvider.TYPO);
158 @NotNull
159 public List<String> getSuggestions(@NotNull String text) {
160 return suggestionProvider.getSuggestions(text);
165 @NotNull
166 protected List<String> getRawSuggestions(@NotNull String word) {
167 if (!spellChecker.isCorrect(word)) {
168 List<String> suggestions = spellChecker.getSuggestions(word, MAX_SUGGESTIONS_THRESHOLD, MAX_METRICS);
169 if (suggestions.size() != 0) {
170 boolean capitalized = Strings.isCapitalized(word);
171 boolean upperCases = Strings.isUpperCase(word);
172 if (capitalized) {
173 Strings.capitalize(suggestions);
175 else if (upperCases) {
176 Strings.upperCase(suggestions);
179 List<String> result = new ArrayList<String>();
180 for (String s : suggestions) {
181 if (!result.contains(s)) {
182 result.add(s);
185 return result;
187 return Collections.emptyList();
190 @NotNull
191 public List<String> getVariants(@NotNull String prefix) {
193 return Collections.emptyList();
197 public void restartInspections() {
198 ApplicationManager.getApplication().invokeLater(new Runnable() {
199 public void run() {
200 Project[] projects = ProjectManager.getInstance().getOpenProjects();
201 for (Project project : projects) {
202 if (project.isInitialized() && project.isOpen() && !project.isDefault()) {
203 DaemonCodeAnalyzer.getInstance(project).restart();