D-Bus examples

From Apertium
Revision as of 12:35, 19 December 2007 by Wynand.winterbach (talk | contribs) (Added Java example)
Jump to navigation Jump to search

Here are some code snippets for various programming languages (complete with completely unnecessary comments) showing how you can interface with Apertium by means of D-Bus. You'll need to install the D-Bus service for Apertium.

Python

#!/usr/bin/python
# coding=utf-8
# -*- encoding: utf-8 -*-

import dbus, sys, codecs;

sys.stdin = codecs.getwriter('utf-8')(sys.stdin);
sys.stdout = codecs.getwriter('utf-8')(sys.stdout);

mode_name = 'en-af'; # The name of the installed mode
dbus_mode_name = '/' + '_'.join(pair_name.split('-')); # Some mandatory mangling

bus = dbus.SessionBus(); # Create a new session bus

translator = dbus.Interface(bus.get_object('org.apertium.mode', dbus_mode_name), 'org.apertium.Mode'); # Get the translator

input = sys.stdin.read(); # Read the data

print translator.translate({}, input); # Print the translation

Java

Installing the Java D-Bus bindings

First you will need to download the D-Bus bindings for Java; the latest version can be found on the D-Bus project site. The bindings use libmatthew by the same author; the latest version can be downloaded from his site.

  1. Compile and install libmatthew.
  2. Compile and install the Java D-Bus bindings (ignore errors about invalid JAR paths - if it compiles and installs, everything will work.)

The Java binding build process should install the following binaries on your machine:

  1. CreateInterface
  2. DBusCall
  3. DBusDaemon
  4. DBusViewer
  5. ListDBus

You can make sure that everything works by executing:

DBusCall org.apertium.info / org.apertium.Info modes

If you get a message such as

ParseException: Bus address is blank

it means that the environment variable $DBUS_SESSION_BUS_ADDRESS isn't set. You can get around it by using dbus-launch --exit-with-session to execute the program:

dbus-launch --exit-with-session DBusCall org.apertium.info / org.apertium.Info modes.

You should get output that looks something like this:

[[en-af, af-en]]

Using D-Bus from Java

Now that everything is working, it's time to create a Java program which uses an Apertium D-Bus object.

Since both D-Bus and Java use statically typed systems, Java needs to have the D-Bus interface descriptions of the objects it will use available at compile time. The 'CreateInterface' program in the Java D-Bus distribution creates Java interfaces by introspecting D-Bus objects.

We will create a Java interface corresponding to the info.apertium.Info interface and we will store it under the file org/apertium/Info.java. To do this, execute:

CreateInterface org.apertium.info / > org/apertium/Info.java

(and remember to use dbus-launch --exit-with-session if this does not work).

The contents out the newly created file should look something like:

/* File: org/apertium/Info.java */
package org.apertium;
import java.util.List;
import org.freedesktop.dbus.DBusInterface;
public interface Info extends DBusInterface
{

  public String directory();
  public List<List<String>> get_pipeline(String mode);
  public List<String> get_filters(String _type);
  public List<String> modes();
  public String mode_directory();

}

The next step is to create our minimal Java program. Create a file called TestDBus with the following contents:

import org.freedesktop.DBus;
import org.freedesktop.dbus.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;

import org.apertium.Info; // The interface we use to access org.apertium.info/

class TestDBus {

        public static void main(String[] args) throws org.freedesktop.dbus.exceptions.DBusException {
                DBusConnection bus = null;
                Info info = null;

                bus = DBusConnection.getConnection(DBusConnection.SESSION);
                info = bus.getRemoteObject("org.apertium.info", "/", Info.class);

                for (String s : info.modes()) {
                        System.out.println(s);
                }

                bus.disconnect();
        }
}

To compile this program, we need to include the current path on the class path as well as the jar files needed by the Java D-Bus binding. To compile, execute (you should modify the directories to suit your installation):

javac -cp .:/usr/local/share/java/dbus.jar:/usr/local/share/java/unix.jar:\
/usr/local/share/java/debug-disable.jar  TestDBus.java

To run the program, you need to specify the class paths specified above, as well as the JNI code (which installs to /usr/local/lib/jni by default (if you are using TCP instead of UNIX domain sockets for transport, then this won't be needed). You can run the program using:

dbus-launch --exit-with-session java -cp .:/usr/local/share/java/dbus.jar:\/usr/local/share/java/unix.jar:
/usr/local/share/java/debug-disable.jar -Djava.library.path=/usr/local/lib/jni TestDBus

(and if it does not work, prefix the command with dbus-launch --exit-with-session).

Of course, if you are writing an application, you would hide all of these flags in a wrapper script.