Hack 54 Don't Get Lost in Translation


world, cross the language barriers with a translator bot.
Writing a bot to translate phrases
between different languages doesn't
require a mastery of translation nor the ability to parse output from
web-based translators. This bot uses a Web Service to get its data.
The translator Web Service is not listed on XMethods but is provided
by RestlessDelusions.net.
Here is the information about the service that you need:WSDL URL
http://www.restlessdelusions.com/projects/services/translate/translate.asmx?WSDL
Operation
TranslateLanguage
Input message parts
Language list
This has the original language and the language to translate to. Each
language is given a two-letter code and is separated by a
| character. To translate from English to French,
the argument would be en|fr.
Output message name
TranslateLanguageResult
Language pairs that can be translated and their abbreviations are as
follows:en|de
English to German
en|es
English to Spanish
en|fr
English to French
en|it
English to Italian
en|pt
English to Portuguese
de|en
German to English
de|fr
German to French
es|en
Spanish to English
fr|en
French to English
fr|de
French to German
it|en
Italian to English
pt|en
Portuguese to English
8.5.1 The Code
Now, to use this Web Service, you need to change only a few parts
from the WeatherService class [Hack #53] . The changes are
simplereplace the values of key variables with the correct
values from this service and adjust the method to use two arguments.
The lines you need to change are bold in the following
example:
import java.util.*;You now have a working method for
import samples.client.DynamicInvoker;
public class TranslatorService {
static String wsdlLocation = "http://www.restlessdelusions.com/projects/
services/translate/translate.asmx?WSDL";
static String operationName= "TranslateLanguage";
static String outputName = "TranslateLanguageResult";
static String portName = null;
public static String translatePhrase(String languages, String phrase) {
String[] args =
new String[] {wsdlLocation, operationName, languages, phrase};
try {
DynamicInvoker invoker=new DynamicInvoker(wsdlLocation);
HashMap map = invoker.invokeMethod(operationName, portName, args);
return map.get(outputName).toString( );
}catch (Exception e){return null;}
}
}
using the Web Service to translate text and need to write the code
for the bot to use the service. It is convenient to add the code here
into the onMessage method from the previous Web
Services hack. You can assume that the user input will come in the
following format:
WSBot, translate en to fr Hello world!This line assumes that users know the codes for each language. You
may want to provide a help message that lists each language and its
code.To process this request, you can begin as with the previous example,
using a StringTokenizer to parse the
input.
String query = t.nextToken( );Then the next step will be to pull out the two languages:
if (query.equals("translate")) {
String response = ";
String sourceLanguage = t.nextToken( );Now, the rest of the tokens store the message to be translated.
t.nextToken( ); // Get rid of the "to".
String targetLanguage = t.nextToken( );
Unfortunately, StringTokenizer does not have a method to nicely
return the rest of the tokens, so you must use a loop to aggregate
them into a string:
String messageToTranslate = ";Now, with a little error checking, you can make the call to your
while (t.hasMoreTokens( ))
messageToTranslate = messageToTranslate + " " + t.nextToken( );
translatePhrase method:
if (!sourceLanguage.equals(") &&
!targetLanguage.equals(") &&
!messageToTranslate.equals(")){
String lang = sourceLanguage + "|" + targetLanguage;
String result = TranslatorService.translatePhrase(
lang, messageToTranslate);
response = result;
} else {
response = "I could not understand your input.";
}
sendMessage(channel, response);
}
...
8.5.2 Running the Hack
As with the previous Web Services hack, you will need to ensure that
you have all of the Axis components in your classpath when
you compile the bot:
% javac -classpath .:pircbot.jar:axis-1_1/lib/axis.jar: \ axis-1_1/lib/axis-ant.jar: \Depending on the name of your main class, you can then run the bot
axis-1_1/lib/commons-discovery.jar:axis-1_1/lib/commons-logging.jar: \
axis-1_1/lib/jaxrpc.jar:axis-1_1/lib/log4j-1.2.8.jar: \ axis-1_1/lib/saaj.jar: \
axis-1_1/lib/wsdl4j.jar *.java
like so:
% java -classpath .:pircbot.jar:axis-1_1/lib/axis.jar: \ axis-1_1/lib/axis-ant.jar: \Replace Main with the correct name for
axis-1_1/lib/commons-discovery.jar: \ axis-1_1/lib/commons-logging.jar: \
axis-1_1/lib/jaxrpc.jar:axis-1_1/lib/log4j-1.2.8.jar: \ axis-1_1/lib/saaj.jar: \
axis-1_1/lib/wsdl4j.jar Main
your main class if it is different.As soon as the bot connects to the server, it is ready to offer its
translation service to all of the channels you dispatch it to:
<Jibbler> WSBot, translate en to de I love IRCThis hack is a good demonstration of the power of Web Services.
<WSBot> Ich liebe IRC
Anybody who's tried to achieve a similar task by
parsing raw HTML from a web page will certainly appreciate the
simplicity. Jennifer Golbeck