package com.kodcu.spell.dictionary;
import com.kodcu.component.EditorPane;
import com.kodcu.config.SpellcheckConfigBean;
import com.kodcu.controller.ApplicationController;
import com.kodcu.service.ThreadService;
import com.kodcu.spell.filter.SpellFilterProvider;
import morfologik.speller.Speller;
import morfologik.stemming.Dictionary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* Created by usta on 07.12.2015.
*/
@Component
public class DictionaryService {
private Logger logger = LoggerFactory.getLogger(DictionaryService.class);
private final ApplicationController controller;
private final SpellFilterProvider spellFilterProvider;
private final ThreadService threadService;
private final SpellcheckConfigBean spellcheckConfigBean;
private Map<Path, LanguageSpeller> languageSpellerMap = new ConcurrentHashMap<>();
private Map<String, List<String>> suggestionMap = new ConcurrentHashMap<>();
@Autowired
public DictionaryService(ApplicationController controller, SpellFilterProvider spellFilterProvider, ThreadService threadService, SpellcheckConfigBean spellcheckConfigBean) {
this.controller = controller;
this.spellFilterProvider = spellFilterProvider;
this.threadService = threadService;
this.spellcheckConfigBean = spellcheckConfigBean;
}
private LanguageSpeller getLanguageSpeller(Path defaultLanguage) {
try {
Dictionary dictionary = Dictionary.read(defaultLanguage);
Speller speller = new Speller(dictionary);
final LanguageSpeller languageSpeller = new LanguageSpeller();
languageSpeller.setDictionary(dictionary);
languageSpeller.setSpeller(speller);
languageSpeller.setEncoding(dictionary.metadata.getEncoding());
languageSpellerMap.putIfAbsent(defaultLanguage, languageSpeller);
return languageSpellerMap.get(defaultLanguage);
} catch (NullPointerException e) {
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
public void processTokens(EditorPane editorPane, String jsonToken, String mode) {
final Path language = Optional.ofNullable(editorPane.getSpellLanguage()).orElseGet(spellcheckConfigBean::getDefaultLanguage);
if (Objects.isNull(language)) {
return;
}
final LanguageSpeller languageSpeller = getLanguageSpeller(language);
if (Objects.isNull(languageSpeller)) {
return;
}
final List<Token> tokenList = languageSpeller.getTokenList(jsonToken);
final List<Token> tokens = tokenList.stream()
.flatMap(token -> token.fromLines((token.getValue())).stream())
.filter(spellFilterProvider.filterByMode(mode))
.filter(t -> languageSpeller.isMisspelled(t.getValue()))
.peek(t -> {
final List<String> suggestions = languageSpeller.findSuggestions(t.getValue());
t.setEmptySuggestion(suggestions.isEmpty());
suggestionMap.put(t.getValue(), suggestions);
})
.collect(Collectors.toList());
if (tokens.isEmpty()) {
return;
}
threadService.runActionLater(() -> {
for (Token token : tokens) {
editorPane.addTypo(token);
}
});
}
public Map<String, List<String>> getSuggestionMap() {
return suggestionMap;
}
}