Skip to content

How to make Machine Translation connector plugin

What is MT connector

OmegaT can be extended with plugin. One of the popular categories of plugin is a Machine Translation (MT) connector. There are many translation web services, thanks to the innovation of AI technologies. OmegaT bundles some MT connectors that support popular services, such as Google, DeepL and IBM Watson. There are also genuine and third party plugins for services;

Getting started the project

OmegaT project provides a plugin project skeleton repository. You can start your project from a skeleton project. Please go to the URL https://github.com/omegat-org/plugin-skeleton and click "Use this template" button to start your project in GitHub. When you use codeberg.org forge site, there is also a skeleton at https://codeberg.org/miurahr/omegat-plugin-skeleton

The skeleton project uses Gradle for a build system. You can select Groovy DSL or Kotlin DSL for the configuration. When you choose a Groovy DSL, please rename build.gradle.disabled to build.gradle and remove build.gradle.kts.

You should also modify a file - Project.name in settings.gradle - Properties: description, title, website and category - Plugin Main class name in build.gradle(.kts).

Implementation should be placed at - Source code: src/main// - Test code: src/test// and src/test/resources/*

OmegaT MT API

There is a main API that is org.omegat.gui.exttrans.IMachineTranslation. All MT connectors should implement the API.

String getTranslation(Language sLang, Language tLang, String text) throws Exception

It is a main method to override in your plugin project. The method receives a source text, translation from sLang to tLang language, and return translation text.

String getCachedTranslation(Language sLang, Language tLang, String text);

It is another method that you should override. If your plugin has a caching mechanism, and there is entry for the text, return translation without accessing MT engine. Otherwise, return null.

NOTE: You should not call the engine in the method, because OmegaT will call it even when the target segment has already translated, but configured as MT only untranslated segment is on or automatically translate is off.

getName()

Human and machine-readable name of MT engine. OmegaT uses it for the index of results, and as a property value, and logging purpose.

isEnabled()/setEnabled(boolean b)

return and set an enabled status.

boolean isConfigurable() / void showConfigurationUI(Window parent)

When the plugin return true for the method, isConfigurable() OmegaT will call showConfigurationUI when user clicks a configuration UI button on Tools > Preferences > MachineTranslation.

Convenience abstract class for plugins

There are two convenience class for plugins. You are recommended to use org.omegat.core. machinetranslators.BaseCachedTranslate. It implements many necessary things, and you can concentrate into a logic to access your MT engine API. There are only three methods you should override.

getName()

Name of the engine as same as IMachineTranslate.

protected abstract String getPreferenceName()

A preference key used in a user's configuration file. It will be like a "allow__translate".

protected abstract String translate(Language sLang, Language tLang, String text) throws Exception

Main method to return translation from source text.

Common way to register your plugin

You can register your plugin through a Core method like as follows;

public class ExamplePlugin {
    public static void loadPlugins() {
        Core.registerMachineTranslationClass(ExamplePlugin.class);
    }

    public static void unloadPlugins() {
    }

    public ExamplePlugin() {
        // You can initialize internal resources here.
        // Because the class will be instantiated in a dynamic way through
        // Core.registerMachineTranslationClass API, only a default constructor 
        // can be used, and unable to expect static initialization of the class.
    }
}

Utility functions

You can use several utility functions to implement a feature.

JSON and XML Parser

OmegaT 6.0 and later bundles Jackson JSON parser. You can use Jackson to create query JSON data and parse a response. You can check details at Jackson document page; https://github.com/FasterXML/jackson-docs

NOTE: There was org.omegat.util.JsonParser#parse utility method, but it is deprecated in OmegaT 5.8 and later.

OmegaT 6.1 and later bundles Jackson XML parser. You can use Jackson to create query XML data and parse a response XML.

NOTE: org.omegat.util.xml.XMLReader is deprecated in OmegaT 6.1 and later

HttpConnectionUtils

You can use org.omegat.util.HttpConnectionUtils to access your MT engine. You may interested get, post and postJSON methods.

Writing tests

Unit test

When you write a connector, you will also want to write unit tests to check a parser of responses from MT engine. At first, you will need to prepare examples of responses in XML or JSON file, and store it as test data. It is better to test not only for a response of success case, but also for a response with error or an empty content.

Connection test

You may want to use WireMock for test for http query and response. You can learn about usage of the library to see a bundled connector test.

You can see an MT connector source code in the OmegaT project, machinetranslators/aperitium/src/test/java/org/omegat/machinetranslators.aperitium/ApertiumTranslateTest

You can also see a plugin project Azure-translate-plugin to learn how to write a test. TestMicrosoftTranslatorAzure.java implement a case to test http request and response.

Publish

If you are willing to merge your connector into OmegaT genuine bundles, it is challenging for maintainers to test it with actual MT engines, because we need to learn a target service, pay costs and conformance to its license. You are recommended to publish your plugin and share its download link in OmegaT users mail list.