Archive for July, 2007

Mylyn web connector

Again about the Mylyn plugin. If you install Eclipse 3.3 Europa there isn’t, due to the Mylar -> Mylyn renaming, the web connector plugin which could be found in the Mylyn 1.0. This plugin is useful when we are working with an unsupported web based bug repository. The plugin still exists but can be found in a separate update site. Simply add new remote update site: http://download.eclipse.org/tools/mylyn/update/extras to find a set of Mylyn plugins including the web connector.

If I find some time I will try to connect to Scrum Works repository using that plugin. If someone has done it already please let me know.

Popularity: 29% [?]

Comments (1)

Serializing objects to HSQLDB using blobs

Our task is to persist a state object called State in a database. State object has globally unique identifier and some other properties. And is serialisable.

Let’s start with creating methods for serialisation/deserialisation:

protected byte[] serialise(T state) {
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(state);
        oos.flush();
        return bos.toByteArray();
    } catch (IOException e) {
        throw new IllegalArgumentException(e);
    }
}
protected T deserialise(byte[] byteArray) {
    try {
        ObjectInputStream oip = new ObjectInputStream(new ByteArrayInputStream(byteArray));
        return (T) oip.readObject();
    } catch (IOException e) {
        throw new IllegalArgumentException(e);
    } catch (ClassNotFoundException e) {
        throw new IllegalArgumentException(e);
    }
}

So, we know how to serialise and deserialise object. The next step would be to think where to store that data. I have chosen HSQLDB for that example but it should be very easy to swap to some other db. It should be as easy as changing datasource properties and maybe amend a bit create script. Let’s crate one then for HSQLDB:

create table State (
object_id VARCHAR(32) not null primary key,
object_value LONGVARBINARY
);

Very simple table: object_id which a primary key and objet_value which is a binary representation of the object. And there is beauty of different flavours of databases (not!). We want to store the binary representation in a blob, and for HSQLDB there is no data type as blob. We have to use LONGVARBINARY. We have to be careful when switching to some other vendor and amend the create script. I will skip the part with details how to create schema etc. Contact me if you want more details on that.

Let’s create a datasource for HSQLDB in memory now using org.apache.commons.dbcp.BasicDataSource:

    String driver = "org.hsqldb.jdbcDriver";
    String url = "jdbc:hsqldb:mem:testdb";
    String username = "sa";
    String password = "";

    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(username);
    ds.setPassword(password);

The datasource will be used by Spring JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate) which we will happily use for interactions with db. You can reuse this object:

JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);

Let’s have a look how to store a serialised object in database (add necessary validation/exception handling):

public void add(T state) {
    Object[] params = new Object[] {state.getId(), new SqlLobValue(serialise(state))};
    int[] types = new int[] { Types.VARCHAR, Types.BLOB };
    jdbcTemplate.update("insert into State (object_id, object_value) values(?, ?)", params, types);
}

Retrieving of that object is slightly more complex. We have to create a callback RowMapper (org.springframework.jdbc.core.RowMapper) first which will map each row from database to our object. This object can be as well reused:

private RowMapper rowMapper = new RowMapper() {
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        byte[] bytes = rs.getBytes("object_value");
        return deserialise(bytes) ;
    }
};

And finally the code for retrieving and deserialising the object from database (validation and exception handling removed):

public T get(String id) {
    Object[] params = new Object[] {id};
    int[] types = new int[] {Types.VARCHAR};
    List results = jdbcTemplate.query("select object_id, object_value from State where object_id=?", params, types, rowMapper);
    if (results.size() == 0)
        return null;
    return (T)results.get(0);
}

Popularity: 38% [?]

Comments

Mylyn and Implementors

I migrated last week to Eclipse 3.3.0 and during usual routine of installing plugins (must to have: JBossIDE, SpringIDE, Subclipse) I decided to try two plugins I haven’t been using yet. First is a subproject from Eclipse Tools project called Implementors. It fills a gap in standard Eclipse source code navigation which doesn’t really well support working with interfaces. With Implementors plugin it is possible to jump to implementation of an interface and to an interface of implementation. Sounds unimpressive yeah? But it is really useful plugin and I could call it a “Plugin of the Month in Category Simple but Cool”. If I had that category. So, whenever you edit a class which has dependencies defined as interfaces just hit Alt-F3 on a method from an interface to go to implementation. If you have more than one implementation you will have a choice. Ctrl-Alt-F3 will take you to interface. Thanks Andy for introducing that plugin!

The second plugin I wanted to write about is Mylyn formerly known as Mylar. I have heard about this plugin long time ago, talked about it with Tomaz many times but never actually tried it out. My bad and now I regret that. Because I found Mylyn just awesome. In couple of words Mylyn is a task focused ui for Eclipse which filters all unneeded information noise, leaving you only relevant information. It monitors your activity when working on a particular task and creates a context of that task which makes it is very easy to switch between tasks. No more navigating, searching, scrolling again. Mylyn integrates with repositories like JIRA, Bugzilla or Trac. There is also option of using local task repository.

As I use Scrum Works for task management I would like to use that repository with Mylyn but couldn’t find a connector for that one. Anyone solved that problem?

Popularity: 26% [?]

Comments

Ant task generating random number

I created an ant task lately which generates random number and I thought that it might be useful for someone. The ant task will accept three parameters:

  • min
  • max
  • name of ant property to assign value to

Our class will extend org.apache.tools.ant.Task and the only thing which we have to do is really to override the execute method and to add setters for parameters. We can return value to ant environment using org.apache.tools.ant.Project which will give us a way of setting a property using its name. The code is as follows:


package your.package;

import java.util.Random;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

public class RandomTask extends Task {
    private String min;
    private String max;
    private String property;
    private Random random = new Random(System.currentTimeMillis());

    @Override
    public void execute() throws BuildException {
        if (min == null || min.equals(""))
            throw new BuildException("Min property not specified");

        if (max == null || max.equals(""))
            throw new BuildException("Max property not specified");

        int minInt = Integer.parseInt(min);
        int maxInt = Integer.parseInt(max);

        if (minInt > maxInt)
            throw new BuildException("Min is bigger than max");

        int randomInt = calculateRandom(minInt, maxInt);

        getProject().setNewProperty(property, String.valueOf(randomInt));
    }

    protected int calculateRandom(int minInt, int maxInt) {
        return minInt + random.nextInt(maxInt - minInt + 1);
    }

    public void setMin(String min) {
        this.min = min;
    }

    public void setMax(String max) {
        this.max = max;
    }

    public void setProperty(String property) {
        this.property = property;
    }
}

After compiling and building a jar we should copy that jat to ANT_HOME/lib and define the new task in our build.xml, lets call it “random”:

    <taskdef name="random" classname="your.package.RandomTask"></taskdef>

Let’s try if it works. We will generate a rundom integer from the range <4;10>, assign to a property and print it to console:

    <target name="testRandom">
        <random min="4" max="10" property="randomValue"></random>
        <echo>Random:${randomValue}</echo>
    </target>

Popularity: 30% [?]

Comments

Hello world!

After couple of months of non-existence of my website, when my old, shabby server in living room refused to breath, I decided to move the site to some real hosting. So… it happened today. I am not sure if I will keep posting regularly as it wasn’t the case so far but at least I have technical opportunity to do it now, no more excuses.

Popularity: 13% [?]

Comments

Close
E-mail It