/**************************************************************************
OmegaT - Computer Assisted Translation (CAT) tool
with fuzzy matching, translation memory, keyword search,
glossaries, and translation leveraging into updated projects.
Copyright (C) 2010-2015 Alex Buloichik
2013 Didier Briel
Home page: http://www.omegat.org/
Support center: http://groups.yahoo.com/group/OmegaT/
This file is part of OmegaT.
OmegaT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OmegaT 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************/
package org.omegat.core.machinetranslators;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import javax.swing.JCheckBoxMenuItem;
import org.omegat.core.Core;
import org.omegat.gui.exttrans.IMachineTranslation;
import org.omegat.util.CredentialsManager;
import org.omegat.util.Language;
import org.omegat.util.PatternConsts;
import org.omegat.util.Preferences;
import org.openide.awt.Mnemonics;
/**
* Base class for machine translation.
*
* @author Alex Buloichik (alex73mail@gmail.com)
* @author Didier Briel
*/
public abstract class BaseTranslate implements IMachineTranslation {
protected boolean enabled;
/**
* Machine translation implementation can use this cache for skip requests twice. Cache will not be
* cleared during OmegaT work, but it's okay - nobody will work weeks without exit.
*/
private final Map<String, String> cache = Collections.synchronizedMap(new HashMap<String, String>());
public BaseTranslate() {
// Options menu item
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem();
Mnemonics.setLocalizedText(menuItem, getName());
menuItem.addActionListener(e -> setEnabled(menuItem.isSelected()));
enabled = Preferences.isPreference(getPreferenceName());
menuItem.setState(enabled);
Core.getMainWindow().getMainMenu().getMachineTranslationMenu().add(menuItem);
// Preferences listener
Preferences.addPropertyChangeListener(getPreferenceName(), e -> {
boolean newValue = (Boolean) e.getNewValue();
menuItem.setSelected(newValue);
enabled = newValue;
});
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
Preferences.setPreference(getPreferenceName(), enabled);
}
@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) {
return getFromCache(sLang, tLang, text);
} else {
return null;
}
}
abstract protected String getPreferenceName();
abstract protected String translate(Language sLang, Language tLang, String text) throws Exception;
/**
* Attempt to clean spaces added around tags by machine translators. Do it by comparing spaces between the source
* text and the machine translated text.
* @param machineText The text returned by the machine translator
* @param sourceText The original source segment
* @return
*/
protected String cleanSpacesAroundTags(String machineText, String sourceText) {
// Spaces after
Matcher tag = PatternConsts.OMEGAT_TAG_SPACE.matcher(machineText);
while (tag.find()) {
String searchTag = tag.group();
if (sourceText.indexOf(searchTag) == -1) { // The tag didn't appear with a trailing space in the source text
String replacement = searchTag.substring(0, searchTag.length() - 1);
machineText = machineText.replace(searchTag, replacement);
}
}
// Spaces before
tag = PatternConsts.SPACE_OMEGAT_TAG.matcher(machineText);
while (tag.find()) {
String searchTag = tag.group();
if (sourceText.indexOf(searchTag) == -1) { // The tag didn't appear with a leading space in the source text
String replacement = searchTag.substring(1, searchTag.length());
machineText = machineText.replace(searchTag, replacement);
}
}
return machineText;
}
protected String getFromCache(Language sLang, Language tLang, String text) {
return cache.get(sLang + "/" + tLang + "/" + text);
}
protected String putToCache(Language sLang, Language tLang, String text, String result) {
return cache.put(sLang + "/" + tLang + "/" + text, result);
}
/**
* Retrieve a credential with the given ID. First checks temporary system properties, then falls back to
* the program's persistent preferences. Store a credential with
* {@link #setCredential(String, String, boolean)}.
*
* @param id
* ID or key of the credential to retrieve
* @return the credential value in plain text
*/
protected String getCredential(String id) {
String property = System.getProperty(id);
if (property != null) {
return property;
}
return CredentialsManager.getInstance().retrieve(id).orElse("");
}
/**
* Store a credential. Credentials are stored in temporary system properties and, if
* <code>temporary</code> is <code>false</code>, in the program's persistent preferences encoded in
* Base64. Retrieve a credential with {@link #getCredential(String)}.
*
* @param id
* ID or key of the credential to store
* @param value
* value of the credential to store
* @param temporary
* if <code>false</code>, encode with Base64 and store in persistent preferences as well
*/
protected void setCredential(String id, String value, boolean temporary) {
System.setProperty(id, value);
CredentialsManager.getInstance().store(id, temporary ? "" : value);
}
/**
* Determine whether a credential has been stored "temporarily" according to the definition in
* {@link #setCredential(String, String, boolean)}. The result will be <code>false</code> if the
* credential is not stored at all, or if it is stored permanently.
*
* @param id
* ID or key of credential
* @return <code>true</code> only if the credential is stored temporarily
* @see #setCredential(String, String, boolean)
* @see #getCredential(String)
*/
protected boolean isCredentialStoredTemporarily(String id) {
return !CredentialsManager.getInstance().isStored(id) && !System.getProperty(id, "").isEmpty();
}
}