Thursday, December 23, 2010


Check out magicktiler, a Java tool and embeddable library for converting images into formats suitable for publishing as zoomable Web images. It supports a variety of tiling schemes (TMS, Zoomify, Google Maps, ..). You can find some detailed information in the slides I used for my talk at the Toronto JUG.

It has a CLI, a Scala-Swing based GUI and can be used as a Java lib:
public static void main(String... args) {
    try {
        File input = new File("/path/to/your/image.jpg");
        File output = new File("/tileset/output/path");
        MagickTiler tiler = new GoogleMapsTiler();
        // optional settings (these are the default values)
        tiler.setWorkingDirectory(new File("."));
        // create the tiles
        TilesetInfo info = tiler.convert(input, output);
    } catch (TilingException te) {

Tuesday, September 14, 2010

API compatibility

Today I was stumbling across in interesting page about what changes are allowed to an existing API without breaking compatibility to existing clients which I think is worth a read: .

What surprised me was that adding/deleting checked exceptions to a method is not breaking binary compatibility. That means that clients compiled against the old API won't have problems to call the modified method.

Anyway, as soon as the exception is thrown the legacy client might behave unpredictable because of subsequent exceptions e.g. ClassNotFound or UndeclaredThrowable or things like that.

Thursday, August 12, 2010


I have been playing around with Cassandra lately using its Java (Thrift) client API. In order to map different classes (entities) to a list of ColumnOrSuperColumns, I have created a generic entity transformer.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.Mutation;

public abstract class CassandraEntityTransformer<T> {
  public static final String CHARSET = "UTF-8";

  public abstract List<ColumnOrSuperColumn> getColumns(T entity) throws Exception;
  public abstract T getEntity(List<ColumnOrSuperColumn> columns) throws Exception;

  public List<Mutation> listMutations(T oldEntity, T newEntity) throws Exception {
     List<Mutation> mutations = new ArrayList<Mutation>();
     List<ColumnOrSuperColumn> oldColumns = getColumns(oldEntity);
     List<ColumnOrSuperColumn> newColumns = getColumns(newEntity);

        throw new IllegalArgumentException("incompatible entities");

     for(int i=0; i<newColumns.size(); i++) {
                oldColumns.get(i).getColumn().getValue())) {
               new Mutation().setColumn_or_supercolumn(newColumns.get(i)));
     return mutations;

  protected ColumnOrSuperColumn createColumn(Column column) {
     ColumnOrSuperColumn c = new ColumnOrSuperColumn();
     return c;
Subclasses of this class are responsible for providing the columns of concrete entities, like for the token entity in the following example. I found this quite handy, especially as getMutations works out of the box for all entities.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;

public class CassandraTokenTransformer extends CassandraEntityTransformer<Token> {
   private static final String VALUE_COLUMN_NAME = "value";
   private static final String EMAIL_COLUMN_NAME = "email";

   public List<ColumnOrSuperColumn> getColumns(Token token) throws Exception {
      List<ColumnOrSuperColumn> columns = new ArrayList<ColumnOrSuperColumn>();

      long timestamp = System.currentTimeMillis();

      // the value column.
              new Column(VALUE_COLUMN_NAME.getBytes(CHARSET),
              token.getValue().getBytes(CHARSET), timestamp)));

      // the email column.
              new Column(EMAIL_COLUMN_NAME.getBytes(CHARSET),
              token.getEmail().getBytes(CHARSET), timestamp)));

      return columns;

   public Token getEntity(List<ColumnOrSuperColumn> columns) {
      Token token = null;

      Map<String, String> fields = new HashMap<String, String>();
      for (ColumnOrSuperColumn column : columns) {
         fields.put(new String(, 
                 new String(column.column.value));
         token = new Token(fields.get(VALUE_COLUMN_NAME),

      return token;
Alternatives would have been to use an annotation based mapping mechanism for entities to Cassandra columns, or a JSON based API. Maybe they are out there, and I have just missed them?

Thursday, March 18, 2010

presenting some GWT magic

Rainer's recent papers give all the background on a map annotation tool we have implemented using GWT as frontend technology. Here are some interesting blog posts: and

The tools have been implemented on top of our image annotation tool as part of the:
LEMO annotation framework, published in the International Journal of Digital Libraries.

Finally, here is the link to the tool in case you like to play around with it: Image Annotation Toolset

Feedback is highly appreciated.