org.languagetool.rules.RemoteRuleConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of languagetool-core Show documentation
Show all versions of languagetool-core Show documentation
LanguageTool is an Open Source proofreading software for English, French, German, Polish, Romanian, and more than 20 other languages. It finds many errors that a simple spell checker cannot detect like mixing up there/their and it detects some grammar problems.
/*
* LanguageTool, a natural language style checker
* * Copyright (C) 2018 Fabian Richter
* *
* * 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.rules;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.languagetool.Language;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Stream;
@SuppressWarnings("PublicField")
@JsonIgnoreProperties(ignoreUnknown = true)
public class RemoteRuleConfig {
private static final int DEFAULT_PORT = 443;
private static final long DEFAULT_BASE_TIMEOUT = 1000;
private static final float DEFAULT_TIMEOUT_PER_CHAR = 0;
private static final long DEFAULT_DOWN = 5000L;
private static final float DEFAULT_FAILURE_RATE_THRESHOLD = 50f;
private static final String DEFAULT_SLIDING_WINDOW_TYPE = CircuitBreakerConfig.SlidingWindowType.TIME_BASED.name();
private static final int DEFAULT_SLIDING_WINDOW_SIZE = 60;
private static final int DEFAULT_MINIMUM_NUMBER_OF_CALLS = 10;
private static final LoadingCache> configCache = CacheBuilder.newBuilder()
.expireAfterWrite(15, TimeUnit.MINUTES)
.build(new CacheLoader>() {
@Override
public List load(File path) throws Exception {
try (FileInputStream in = new FileInputStream(path)) {
return parse(in);
}
}
});
public String ruleId;
public String url;
public Integer port = DEFAULT_PORT;
public long baseTimeoutMilliseconds = DEFAULT_BASE_TIMEOUT;
public float timeoutPerCharacterMilliseconds = DEFAULT_TIMEOUT_PER_CHAR;
public long downMilliseconds = DEFAULT_DOWN;
public float failureRateThreshold = DEFAULT_FAILURE_RATE_THRESHOLD;
public String slidingWindowType = DEFAULT_SLIDING_WINDOW_TYPE;
public int slidingWindowSize = DEFAULT_SLIDING_WINDOW_SIZE;
public int minimumNumberOfCalls = DEFAULT_MINIMUM_NUMBER_OF_CALLS;
public Map options = new HashMap<>();
public String language;
public String type;
public RemoteRuleConfig() {
}
public RemoteRuleConfig(RemoteRuleConfig copy) {
this.ruleId = copy.ruleId;
this.url = copy.url;
this.port = copy.port;
this.baseTimeoutMilliseconds = copy.baseTimeoutMilliseconds;
this.timeoutPerCharacterMilliseconds = copy.timeoutPerCharacterMilliseconds;
this.downMilliseconds = copy.downMilliseconds;
this.failureRateThreshold = copy.failureRateThreshold;
this.slidingWindowType = copy.slidingWindowType;
this.slidingWindowSize = copy.slidingWindowSize;
this.minimumNumberOfCalls = copy.minimumNumberOfCalls;
this.options = new HashMap<>(copy.options);
this.language = copy.language;
this.type = copy.type;
}
public static RemoteRuleConfig getRelevantConfig(String rule, List configs) {
return configs.stream().filter(config -> config.getRuleId().equals(rule)).findFirst().orElse(null);
}
public static Predicate isRelevantConfig(String type, Language language) {
return (r) -> type.equals(r.type) &&
(r.language == null || language.getShortCodeWithCountryAndVariant().matches(r.language));
}
public static List parse(InputStream json) throws IOException {
ObjectMapper mapper = new ObjectMapper(new JsonFactory().enable(JsonParser.Feature.ALLOW_COMMENTS));
return mapper.readValue(json, new TypeReference>() {});
}
public static List load(File configFile) throws ExecutionException {
return configCache.get(configFile);
}
public float getFailureRateThreshold() {
return failureRateThreshold;
}
public String getSlidingWindowType() {
return slidingWindowType;
}
public int getSlidingWindowSize() {
return slidingWindowSize;
}
public String getRuleId() {
return ruleId;
}
public String getUrl() {
return url;
}
public int getPort() {
return port != null ? port : DEFAULT_PORT;
}
public long getDownMilliseconds() {
return downMilliseconds;
}
public long getBaseTimeoutMilliseconds() {
return baseTimeoutMilliseconds;
}
public float getTimeoutPerCharacterMilliseconds() {
return timeoutPerCharacterMilliseconds;
}
public int getMinimumNumberOfCalls() {
return minimumNumberOfCalls;
}
/**
* miscellaneous options for remote rules
* allows implementing additional behavior in subclasses
* some options defined in {@link RemoteRule}:
* fixOffsets: boolean - adjust offsets of matches because of discrepancies in string length for some unicode characters between Java and Python
* filterMatches: boolean - enable anti-patterns from remote-rule-filters.xml
* suppressMisspelledMatch: regex - filter out matches with matching rule IDs that have misspelled suggestions
* suppressMisspelledSuggestions: regex - filter out misspelled suggestions from matches with matching rule IDs
* */
public Map getOptions() {
return options;
}
/**
* Regex to match language codes for which this rule should be applied
*/
public String getLanguage() {
return language;
}
/**
* Identifier for the implementation of RemoteRule that this configuration is meant for
*/
public String getType() {
return type;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RemoteRuleConfig that = (RemoteRuleConfig) o;
return new EqualsBuilder().append(baseTimeoutMilliseconds, that.baseTimeoutMilliseconds).append(timeoutPerCharacterMilliseconds, that.timeoutPerCharacterMilliseconds).append(downMilliseconds, that.downMilliseconds).append(failureRateThreshold, that.failureRateThreshold).append(slidingWindowSize, that.slidingWindowSize).append(minimumNumberOfCalls, that.minimumNumberOfCalls).append(ruleId, that.ruleId).append(url, that.url).append(port, that.port).append(slidingWindowType, that.slidingWindowType).append(options, that.options).append(language, that.language).append(type, that.type).isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37).append(ruleId).append(url).append(port).append(baseTimeoutMilliseconds).append(timeoutPerCharacterMilliseconds).append(downMilliseconds).append(failureRateThreshold).append(slidingWindowType).append(slidingWindowSize).append(minimumNumberOfCalls).append(options).append(language).append(type).toHashCode();
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("ruleId", ruleId)
.append("url", url)
.append("port", port)
.append("baseTimeoutMilliseconds", baseTimeoutMilliseconds)
.append("timeoutPerCharacterMilliseconds", timeoutPerCharacterMilliseconds)
.append("downMilliseconds", downMilliseconds)
.append("failureRateThreshold", failureRateThreshold)
.append("slidingWindowType", slidingWindowType)
.append("slidingWindowSize", slidingWindowSize)
.append("minimumNumberOfCalls", minimumNumberOfCalls)
.append("options", options)
.append("language", language)
.append("type", type)
.toString();
}
}