Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: base class BaseCachedTranslate #9

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
package org.omegat.connectors.machinetranslators.azure;

import org.omegat.core.Core;
import org.omegat.core.CoreEvents;
import org.omegat.core.events.IProjectEventListener;
import org.omegat.core.machinetranslators.BaseCachedTranslate;
import org.omegat.gui.exttrans.IMachineTranslation;
import org.omegat.gui.exttrans.MTConfigDialog;
import org.omegat.util.CredentialsManager;
Expand All @@ -38,23 +37,15 @@
import org.omegat.util.Preferences;
import org.omegat.util.StringUtil;

import java.awt.*;
import java.awt.Dimension;
import java.awt.Window;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.OptionalLong;
import java.util.ResourceBundle;

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;

import com.github.benmanes.caffeine.jcache.configuration.CaffeineConfiguration;

/**
* Support for Microsoft Translator API machine translation.
*
Expand All @@ -66,9 +57,7 @@
* @see <a href="https://www.microsoft.com/en-us/translator/translatorapi.aspx">Translator API</a>
* @see <a href="https://docs.microsofttranslator.com/text-translate.html">Translate Method reference</a>
*/
public class MicrosoftTranslatorAzure implements IMachineTranslation {

protected boolean enabled;
public class MicrosoftTranslatorAzure extends BaseCachedTranslate implements IMachineTranslation {

protected static final String ALLOW_MICROSOFT_TRANSLATOR_AZURE = "allow_microsoft_translator_azure";

Expand All @@ -81,16 +70,11 @@ public class MicrosoftTranslatorAzure implements IMachineTranslation {

private MicrosoftTranslatorBase translator = null;

/**
* Machine translation implementation can use this cache for skip requests
* twice. Cache will be cleared when the project changes.
*/
private final Cache<String, String> cache;

/**
* Constructor of the connector.
*/
public MicrosoftTranslatorAzure() {
super();
if (Core.getMainWindow() != null) {
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem();
menuItem.setText(getName());
Expand All @@ -105,48 +89,14 @@ public MicrosoftTranslatorAzure() {
enabled = newValue;
});
}

cache = getCacheLayer(getName());
setCacheClearPolicy();
}

/**
* Creat cache object.
* <p>
* MT connectors can override cache size and invalidate the policy.
* @param name name of cache which should be unique among MT connectors.
* @return Cache object
*/
protected Cache<String, String> getCacheLayer(String name) {
CachingProvider provider = Caching.getCachingProvider();
CacheManager manager = provider.getCacheManager();
Cache<String, String> cache1 = manager.getCache(name);
if (cache1 != null) {
return cache1;
}
CaffeineConfiguration<String, String> config = new CaffeineConfiguration<>();
config.setExpiryPolicyFactory(() -> new CreatedExpiryPolicy(Duration.ONE_DAY));
config.setMaximumSize(OptionalLong.of(1_000));
return manager.createCache(name, config);
}

/**
* Register cache clear policy.
*/
protected void setCacheClearPolicy() {
CoreEvents.registerProjectChangeListener(eventType -> {
if (eventType.equals(IProjectEventListener.PROJECT_CHANGE_TYPE.CLOSE)) {
cache.clear();
}
});
}

/**
* Utility function to get a localized message.
* @param key bundle key.
* @return a localized string.
*/
public static String getString(String key) {
static String getString(String key) {
return BUNDLE.getString(key);
}

Expand Down Expand Up @@ -194,47 +144,8 @@ public String getName() {
}

@Override
public boolean isEnabled() {
return enabled;
}

@Override
public void setEnabled(boolean b) {
enabled = b;
Preferences.setPreference(ALLOW_MICROSOFT_TRANSLATOR_AZURE, b);
}

@Override
public String getTranslation(Language sLang, Language tLang, String text) throws Exception {
if (enabled) {
return translate(sLang, tLang, text);
} else {
return null;
}
}

@Override
public String getCachedTranslation(Language sLang, Language tLang, String text) {
if (enabled) {
String prev;
if (text.length() > 10000) {
prev = getFromCache(sLang, tLang, text.substring(0, 9997) + "...");
} else {
prev = getFromCache(sLang, tLang, text);
}
if (prev != null) {
return prev;
}
try {
String translation = translate(sLang, tLang, text);
if (translation != null) {
putToCache(sLang, tLang, text, translation);
}
return translation;
} catch (Exception ignored) {
}
}
return null;
protected String getPreferenceName() {
return ALLOW_MICROSOFT_TRANSLATOR_AZURE;
}

/**
Expand Down Expand Up @@ -287,7 +198,8 @@ protected String getKey() throws Exception {
return key;
}

protected synchronized String translate(Language sLang, Language tLang, String text) throws Exception {
@Override
protected String translate(Language sLang, Language tLang, String text) throws Exception {
if (isV2() && (translator == null || translator instanceof AzureTranslatorV3)) {
translator = new MicrosoftTranslatorV2(this);
} else if (translator == null || translator instanceof MicrosoftTranslatorV2) {
Expand All @@ -296,14 +208,6 @@ protected synchronized String translate(Language sLang, Language tLang, String t
return translator.translate(sLang, tLang, text);
}

protected String getFromCache(Language sLang, Language tLang, String text) {
return cache.get(sLang + "/" + tLang + "/" + text);
}

protected void putToCache(Language sLang, Language tLang, String text, String result) {
cache.put(sLang.toString() + "/" + tLang.toString() + "/" + text, result);
}

@Override
public boolean isConfigurable() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,58 @@

package org.omegat.connectors.machinetranslators.azure;

import org.omegat.util.Preferences;
import org.omegat.util.PreferencesImpl;
import org.omegat.util.PreferencesXML;
import org.omegat.util.RuntimePreferences;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import wiremock.org.apache.commons.io.FileUtils;

public class TestAzureTranslatorV3 {

private File tmpDir;

/**
* Prepare a temporary directory.
* @throws IOException when I/O error.
*/
@BeforeEach
public final void setUp() throws IOException {
tmpDir = Files.createTempDirectory("omegat").toFile();
Assertions.assertTrue(tmpDir.isDirectory());
File prefsFile = new File(tmpDir, Preferences.FILE_PREFERENCES);
Preferences.IPreferences prefs = new PreferencesImpl(new PreferencesXML(null, prefsFile));
prefs.setPreference(MicrosoftTranslatorAzure.ALLOW_MICROSOFT_TRANSLATOR_AZURE, true);
init(prefsFile.getAbsolutePath());
}

/**
* Clean up a temporary directory.
* @throws IOException when I/O error.
*/
@AfterEach
public final void tearDown() throws IOException {
FileUtils.deleteDirectory(tmpDir);
}

/**
* Initialize preferences for test.
* @param configDir to create omegat.prefs.
*/
public static synchronized void init(String configDir) {
RuntimePreferences.setConfigDir(configDir);
Preferences.init();
}

@Test
public void testCreateJsonRequest() throws JsonProcessingException {
MicrosoftTranslatorAzure azure = new TestMicrosoftTranslatorAzure.MicrosoftTranslatorAzureMock();
Expand Down
Loading