org.languagetool.gui.Configuration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of languagetool-gui-commons Show documentation
Show all versions of languagetool-gui-commons Show documentation
GUI classes for both stand-alone and LibreOffice/OpenOffice extension use
/* LanguageTool, a natural language style checker
* Copyright (C) 2005 Daniel Naber (http://www.danielnaber.de)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package org.languagetool.gui;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.languagetool.JLanguageTool;
import org.languagetool.Language;
import org.languagetool.Languages;
import org.languagetool.rules.ITSIssueType;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
/**
* Configuration like list of disabled rule IDs, server mode etc.
* Configuration is loaded from and stored to a properties file.
*
* @author Daniel Naber
*/
public class Configuration {
static final int DEFAULT_SERVER_PORT = 8081; // should be HTTPServerConfig.DEFAULT_PORT but we don't have that dependency
static final int FONT_STYLE_INVALID = -1;
static final int FONT_SIZE_INVALID = -1;
private static final String CONFIG_FILE = ".languagetool.cfg";
private static final String DISABLED_RULES_KEY = "disabledRules";
private static final String ENABLED_RULES_KEY = "enabledRules";
private static final String DISABLED_CATEGORIES_KEY = "disabledCategories";
private static final String LANGUAGE_KEY = "language";
private static final String MOTHER_TONGUE_KEY = "motherTongue";
private static final String NGRAM_DIR_KEY = "ngramDir";
private static final String AUTO_DETECT_KEY = "autoDetect";
private static final String TAGGER_SHOWS_DISAMBIG_LOG_KEY = "taggerShowsDisambigLog";
private static final String SERVER_RUN_KEY = "serverMode";
private static final String SERVER_PORT_KEY = "serverPort";
private static final String USE_GUI_KEY = "useGUIConfig";
private static final String FONT_NAME_KEY = "font.name";
private static final String FONT_STYLE_KEY = "font.style";
private static final String FONT_SIZE_KEY = "font.size";
private static final String LF_NAME_KEY = "lookAndFeelName";
private static final String ERROR_COLORS_KEY = "errorColors";
private static final String DELIMITER = ",";
private static final String EXTERNAL_RULE_DIRECTORY = "extRulesDirectory";
private final Map configForOtherLanguages = new HashMap<>();
private final Map errorColors = new HashMap<>();
private File configFile;
private Set disabledRuleIds = new HashSet<>();
private Set enabledRuleIds = new HashSet<>();
private Set disabledCategoryNames = new HashSet<>();
private Language language;
private Language motherTongue;
private File ngramDirectory;
private boolean runServer;
private boolean autoDetect;
private boolean taggerShowsDisambigLog;
private boolean guiConfig;
private String fontName;
private int fontStyle = FONT_STYLE_INVALID;
private int fontSize = FONT_SIZE_INVALID;
private int serverPort = DEFAULT_SERVER_PORT;
private String externalRuleDirectory;
private String lookAndFeelName;
/**
* Uses the configuration file from the default location.
* @param lang The language for the configuration, used to distinguish
* rules that are enabled or disabled per language.
*/
public Configuration(final Language lang) throws IOException {
this(new File(System.getProperty("user.home")), CONFIG_FILE, lang);
}
public Configuration(final File baseDir, final Language lang) throws IOException {
this(baseDir, CONFIG_FILE, lang);
}
public Configuration(final File baseDir, final String filename, final Language lang)
throws IOException {
if (!baseDir.isDirectory()) {
throw new IllegalArgumentException("Not a directory: " + baseDir);
}
configFile = new File(baseDir, filename);
loadConfiguration(lang);
}
Configuration() {
}
/**
* Returns a copy of the given configuration.
* @param configuration the object to copy.
* @since 2.6
*/
Configuration copy(Configuration configuration) {
Configuration copy = new Configuration();
copy.restoreState(configuration);
return copy;
}
/**
* Restore the state of this object from configuration.
* @param configuration the object from which we will read the state
* @since 2.6
*/
void restoreState(Configuration configuration) {
this.configFile = configuration.configFile;
this.language = configuration.language;
this.motherTongue = configuration.motherTongue;
this.ngramDirectory = configuration.ngramDirectory;
this.runServer = configuration.runServer;
this.autoDetect = configuration.autoDetect;
this.taggerShowsDisambigLog = configuration.taggerShowsDisambigLog;
this.guiConfig = configuration.guiConfig;
this.fontName = configuration.fontName;
this.fontStyle = configuration.fontStyle;
this.fontSize = configuration.fontSize;
this.serverPort = configuration.serverPort;
this.lookAndFeelName = configuration.lookAndFeelName;
this.externalRuleDirectory = configuration.externalRuleDirectory;
this.disabledRuleIds.clear();
this.disabledRuleIds.addAll(configuration.disabledRuleIds);
this.enabledRuleIds.clear();
this.enabledRuleIds.addAll(configuration.enabledRuleIds);
this.disabledCategoryNames.clear();
this.disabledCategoryNames.addAll(configuration.disabledCategoryNames);
this.configForOtherLanguages.clear();
for (String key : configuration.configForOtherLanguages.keySet()) {
this.configForOtherLanguages.put(key, configuration.configForOtherLanguages.get(key));
}
}
public Set getDisabledRuleIds() {
return disabledRuleIds;
}
public Set getEnabledRuleIds() {
return enabledRuleIds;
}
public Set getDisabledCategoryNames() {
return disabledCategoryNames;
}
public void setDisabledRuleIds(final Set ruleIDs) {
disabledRuleIds = ruleIDs;
enabledRuleIds.removeAll(ruleIDs);
}
public void setEnabledRuleIds(final Set ruleIDs) {
enabledRuleIds = ruleIDs;
}
public void setDisabledCategoryNames(final Set categoryNames) {
disabledCategoryNames = categoryNames;
}
public Language getLanguage() {
return language;
}
public void setLanguage(final Language language) {
this.language = language;
}
public Language getMotherTongue() {
return motherTongue;
}
public void setMotherTongue(final Language motherTongue) {
this.motherTongue = motherTongue;
}
public boolean getAutoDetect() {
return autoDetect;
}
public void setAutoDetect(final boolean autoDetect) {
this.autoDetect = autoDetect;
}
/**
* Determines whether the tagger window will also print the disambiguation
* log.
*
* @return true if the tagger window will print the disambiguation log,
* false otherwise
* @since 3.3
*/
public boolean getTaggerShowsDisambigLog() {
return taggerShowsDisambigLog;
}
/**
* Enables or disables the disambiguation log on the tagger window,
* depending on the value of the parameter taggerShowsDisambigLog.
*
* @param taggerShowsDisambigLog If true, the tagger window will print the
* disambiguation log
* @since 3.3
*/
public void setTaggerShowsDisambigLog(final boolean taggerShowsDisambigLog) {
this.taggerShowsDisambigLog = taggerShowsDisambigLog;
}
public boolean getRunServer() {
return runServer;
}
public void setRunServer(final boolean runServer) {
this.runServer = runServer;
}
public int getServerPort() {
return serverPort;
}
public void setUseGUIConfig(final boolean useGUIConfig) {
this.guiConfig = useGUIConfig;
}
public boolean getUseGUIConfig() {
return guiConfig;
}
public void setServerPort(final int serverPort) {
this.serverPort = serverPort;
}
public String getExternalRuleDirectory() {
return externalRuleDirectory;
}
public void setExternalRuleDirectory(final String path) {
externalRuleDirectory = path;
}
/**
* Returns the name of the GUI's editing textarea font.
* @return the name of the font.
* @since 2.6
* @see Font#getFamily()
*/
public String getFontName() {
return fontName;
}
/**
* Sets the name of the GUI's editing textarea font.
* @param fontName the name of the font.
* @since 2.6
* @see Font#getFamily()
*/
public void setFontName(String fontName) {
this.fontName = fontName;
}
/**
* Returns the style of the GUI's editing textarea font.
* @return the style of the font.
* @since 2.6
* @see Font#getStyle()
*/
public int getFontStyle() {
return fontStyle;
}
/**
* Sets the style of the GUI's editing textarea font.
* @param fontStyle the style of the font.
* @since 2.6
* @see Font#getStyle()
*/
public void setFontStyle(int fontStyle) {
this.fontStyle = fontStyle;
}
/**
* Returns the size of the GUI's editing textarea font.
* @return the size of the font.
* @since 2.6
* @see Font#getSize()
*/
public int getFontSize() {
return fontSize;
}
/**
* Sets the size of the GUI's editing textarea font.
* @param fontSize the size of the font.
* @since 2.6
* @see Font#getSize()
*/
public void setFontSize(int fontSize) {
this.fontSize = fontSize;
}
/**
* Returns the name of the GUI's LaF.
* @return the name of the LaF.
* @since 2.6
* @see javax.swing.UIManager.LookAndFeelInfo#getName()
*/
public String getLookAndFeelName() {
return this.lookAndFeelName;
}
/**
* Sets the name of the GUI's LaF.
* @param lookAndFeelName the name of the LaF.
* @since 2.6 @see
* @see javax.swing.UIManager.LookAndFeelInfo#getName()
*/
public void setLookAndFeelName(String lookAndFeelName) {
this.lookAndFeelName = lookAndFeelName;
}
/**
* Directory with ngram data or null.
* @since 3.0
*/
@Nullable
public File getNgramDirectory() {
return ngramDirectory;
}
/**
* Sets the directory with ngram data (may be null).
* @since 3.0
*/
public void setNgramDirectory(File dir) {
this.ngramDirectory = dir;
}
/**
* @since 2.8
*/
public Map getErrorColors() {
return errorColors;
}
private void loadConfiguration(final Language lang) throws IOException {
final String qualifier = getQualifier(lang);
try (FileInputStream fis = new FileInputStream(configFile)) {
final Properties props = new Properties();
props.load(fis);
disabledRuleIds.addAll(getListFromProperties(props, DISABLED_RULES_KEY + qualifier));
enabledRuleIds.addAll(getListFromProperties(props, ENABLED_RULES_KEY + qualifier));
disabledCategoryNames.addAll(getListFromProperties(props, DISABLED_CATEGORIES_KEY + qualifier));
final String languageStr = (String) props.get(LANGUAGE_KEY);
if (languageStr != null) {
language = Languages.getLanguageForShortName(languageStr);
}
final String motherTongueStr = (String) props.get(MOTHER_TONGUE_KEY);
if (motherTongueStr != null && !motherTongueStr.equals("xx")) {
motherTongue = Languages.getLanguageForShortName(motherTongueStr);
}
final String ngramDir = (String) props.get(NGRAM_DIR_KEY);
if (ngramDir != null) {
ngramDirectory = new File(ngramDir);
}
autoDetect = "true".equals(props.get(AUTO_DETECT_KEY));
taggerShowsDisambigLog = "true".equals(props.get(TAGGER_SHOWS_DISAMBIG_LOG_KEY));
guiConfig = "true".equals(props.get(USE_GUI_KEY));
runServer = "true".equals(props.get(SERVER_RUN_KEY));
fontName = (String) props.get(FONT_NAME_KEY);
if (props.get(FONT_STYLE_KEY) != null) {
try {
fontStyle = Integer.parseInt((String) props.get(FONT_STYLE_KEY));
} catch (NumberFormatException e) {
// Ignore
}
}
if (props.get(FONT_SIZE_KEY) != null) {
try {
fontSize = Integer.parseInt((String) props.get(FONT_SIZE_KEY));
} catch (NumberFormatException e) {
// Ignore
}
}
lookAndFeelName = (String) props.get(LF_NAME_KEY);
final String serverPortString = (String) props.get(SERVER_PORT_KEY);
if (serverPortString != null) {
serverPort = Integer.parseInt(serverPortString);
}
final String extRules = (String) props.get(EXTERNAL_RULE_DIRECTORY);
if (extRules != null) {
externalRuleDirectory = extRules;
}
String colorsString = (String) props.get(ERROR_COLORS_KEY);
parseErrorColors(colorsString);
//store config for other languages
loadConfigForOtherLanguages(lang, props);
} catch (FileNotFoundException e) {
// file not found: okay, leave disabledRuleIds empty
}
}
private void parseErrorColors(String colorsString) {
if (StringUtils.isNotEmpty(colorsString)) {
String[] typeToColorList = colorsString.split(",\\s*");
for (String typeToColor : typeToColorList) {
String[] typeAndColor = typeToColor.split(":");
if (typeAndColor.length != 2) {
throw new RuntimeException("Could not parse type and color, colon expected: '" + typeToColor + "'");
}
ITSIssueType type = ITSIssueType.getIssueType(typeAndColor[0]);
String hexColor = typeAndColor[1];
errorColors.put(type, Color.decode(hexColor));
}
}
}
private String getQualifier(final Language lang) {
String qualifier = "";
if (lang != null) {
qualifier = "." + lang.getShortNameWithCountryAndVariant();
}
return qualifier;
}
private void loadConfigForOtherLanguages(final Language lang, final Properties prop) {
for (Language otherLang : Languages.get()) {
if (!otherLang.equals(lang)) {
final String languageSuffix = "." + otherLang.getShortNameWithCountryAndVariant();
storeConfigKeyFromProp(prop, DISABLED_RULES_KEY + languageSuffix);
storeConfigKeyFromProp(prop, ENABLED_RULES_KEY + languageSuffix);
storeConfigKeyFromProp(prop, DISABLED_CATEGORIES_KEY + languageSuffix);
}
}
}
private void storeConfigKeyFromProp(final Properties prop, final String key) {
if (prop.containsKey(key)) {
configForOtherLanguages.put(key, prop.getProperty(key));
}
}
private Collection extends String> getListFromProperties(final Properties props, final String key) {
final String value = (String) props.get(key);
final List list = new ArrayList<>();
if (value != null && !value.isEmpty()) {
final String[] names = value.split(DELIMITER);
list.addAll(Arrays.asList(names));
}
return list;
}
public void saveConfiguration(final Language lang) throws IOException {
final Properties props = new Properties();
final String qualifier = getQualifier(lang);
addListToProperties(props, DISABLED_RULES_KEY + qualifier, disabledRuleIds);
addListToProperties(props, ENABLED_RULES_KEY + qualifier, enabledRuleIds);
addListToProperties(props, DISABLED_CATEGORIES_KEY + qualifier, disabledCategoryNames);
if (language != null && !language.isExternal()) { // external languages won't be known at startup, so don't save them
props.setProperty(LANGUAGE_KEY, language.getShortNameWithCountryAndVariant());
}
if (motherTongue != null) {
props.setProperty(MOTHER_TONGUE_KEY, motherTongue.getShortName());
}
if (ngramDirectory != null) {
props.setProperty(NGRAM_DIR_KEY, ngramDirectory.getAbsolutePath());
}
props.setProperty(AUTO_DETECT_KEY, Boolean.toString(autoDetect));
props.setProperty(TAGGER_SHOWS_DISAMBIG_LOG_KEY, Boolean.toString(taggerShowsDisambigLog));
props.setProperty(USE_GUI_KEY, Boolean.toString(guiConfig));
props.setProperty(SERVER_RUN_KEY, Boolean.toString(runServer));
props.setProperty(SERVER_PORT_KEY, Integer.toString(serverPort));
if (fontName != null) {
props.setProperty(FONT_NAME_KEY, fontName);
}
if (fontStyle != FONT_STYLE_INVALID) {
props.setProperty(FONT_STYLE_KEY, Integer.toString(fontStyle));
}
if (fontSize != FONT_SIZE_INVALID) {
props.setProperty(FONT_SIZE_KEY, Integer.toString(fontSize));
}
if (this.lookAndFeelName != null) {
props.setProperty(LF_NAME_KEY, lookAndFeelName);
}
if (externalRuleDirectory != null) {
props.setProperty(EXTERNAL_RULE_DIRECTORY, externalRuleDirectory);
}
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : errorColors.entrySet()) {
String rgb = Integer.toHexString(entry.getValue().getRGB());
rgb = rgb.substring(2, rgb.length());
sb.append(entry.getKey()).append(":").append("#").append(rgb).append(", ");
}
props.setProperty(ERROR_COLORS_KEY, sb.toString());
for (final String key : configForOtherLanguages.keySet()) {
props.setProperty(key, configForOtherLanguages.get(key));
}
try (FileOutputStream fos = new FileOutputStream(configFile)) {
props.store(fos, "LanguageTool configuration (" + JLanguageTool.VERSION + "/" + JLanguageTool.BUILD_DATE + ")");
}
}
private void addListToProperties(final Properties props, final String key, final Set list) {
if (list == null) {
props.setProperty(key, "");
} else {
props.setProperty(key, String.join(DELIMITER, list));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy