LibJF/libjf-translate-v1/src/main/java/io/gitlab/jfronny/libjf/translate/impl/libretranslate/LibreTranslateService.java

115 lines
5.2 KiB
Java

package io.gitlab.jfronny.libjf.translate.impl.libretranslate;
import com.google.common.reflect.TypeToken;
import io.gitlab.jfronny.libjf.HttpUtils;
import io.gitlab.jfronny.libjf.translate.api.TranslateException;
import io.gitlab.jfronny.libjf.translate.api.TranslateService;
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateDetectResult;
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateLanguage;
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateRequest;
import io.gitlab.jfronny.libjf.translate.impl.libretranslate.model.LibreTranslateResult;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LibreTranslateService implements TranslateService<LibreTranslateLanguage> {
private static final Type languageListType = new TypeToken<List<LibreTranslateLanguage.ApiResult>>(){}.getType();
private static final Type translateDetectResultListType = new TypeToken<List<LibreTranslateDetectResult>>(){}.getType();
private static final LibreTranslateLanguage autoDetect = new LibreTranslateLanguage("auto", "AUTO_DETECT");
private static final Map<String, LibreTranslateService> knownInstances = new HashMap<>();
public static LibreTranslateService get(String host) throws TranslateException {
LibreTranslateService lts;
if (knownInstances.containsKey(host)) {
lts = knownInstances.get(host);
if (lts == null) throw new TranslateException("Translate service previously failed to initialize. Not trying again");
return lts;
}
try {
lts = new LibreTranslateService(host);
} catch (TranslateException e) {
knownInstances.put(host, null);
throw new TranslateException("Could not instantiate translate service", e);
}
knownInstances.put(host, lts);
return lts;
}
private final String host;
private final List<LibreTranslateLanguage> knownLanguages;
private final Map<String, LibreTranslateLanguage> languageById = new HashMap<>();
private LibreTranslateService(String host) throws TranslateException {
if (host.endsWith("/")) host = host.substring(0, host.length() - 1);
this.host = host;
try {
ArrayList<LibreTranslateLanguage> langs = new ArrayList<>();
langs.add(autoDetect);
for (LibreTranslateLanguage.ApiResult lang : HttpUtils.get(host + "/languages").<ArrayList<LibreTranslateLanguage.ApiResult>>sendJson(languageListType)) {
LibreTranslateLanguage langR = lang.toLanguage();
langs.add(langR);
languageById.put(lang.code, langR);
}
this.knownLanguages = List.copyOf(langs);
} catch (IOException | URISyntaxException e) {
throw new TranslateException("Could not get known languages for LibreTranslate backend", e);
}
}
@Override
public String translate(String textToTranslate, LibreTranslateLanguage translateFrom, LibreTranslateLanguage translateTo) throws TranslateException {
if (textToTranslate == null) throw new TranslateException("textToTranslate must not be null");
if (translateFrom == null) translateFrom = autoDetect;
if (translateTo == null) throw new TranslateException("translateTo must not be null");
LibreTranslateRequest.Translate request = new LibreTranslateRequest.Translate();
request.q = textToTranslate;
request.source = translateFrom.getIdentifier();
request.target = translateTo.getIdentifier();
LibreTranslateResult result = null;
try {
result = HttpUtils.post(host + "/translate").bodyJson(request).sendJson(LibreTranslateResult.class);
} catch (IOException | URISyntaxException e) {
throw new TranslateException("Could not translate text", e);
}
return result.translatedText;
}
@Override
public LibreTranslateLanguage detect(String text) throws TranslateException {
LibreTranslateRequest request = new LibreTranslateRequest();
request.q = text;
List<LibreTranslateDetectResult> result;
try {
result = HttpUtils.post(host + "/detect").bodyJson(request).sendJson(translateDetectResultListType);
} catch (IOException | URISyntaxException e) {
throw new TranslateException("Could not detect language", e);
}
LibreTranslateDetectResult resCurr = null;
for (LibreTranslateDetectResult res : result) {
if (resCurr == null || res.confidence > resCurr.confidence)
resCurr = res;
}
if (resCurr == null) throw new TranslateException("Could not identify any valid language");
return parseLang(resCurr.language);
}
@Override
public LibreTranslateLanguage parseLang(String lang) {
return languageById.get(lang);
}
@Override
public List<LibreTranslateLanguage> getAvailableLanguages() {
return knownLanguages;
}
@Override
public String getName() {
return "LibreTranslate";
}
}