Tuesday, January 24, 2012

Use package-info.java for all your package level annotation needs

I had a problem, I needed to annotate all the occurrences of java.sql.Timestamp with an XmlJavaTypeAdapter for all classes in a Java package. For example I needed this done in dozens of generated source files:

@XmlJavaTypeAdapter(com.fourgablesguy.dao.hibernate.util.TimestampAdapter.class)
public Timestamp getCreateTs() {
return this.createTs;
}

The TimestampAdapter class is the following:
package com.fourgablesguy.dao.hibernate.util;

import java.sql.Timestamp;
import java.util.Date;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class TimestampAdapter extends XmlAdapter {

@Override
public Date marshal(Timestamp v) throws Exception {
return new Date(v.getTime());
}

@Override
public Timestamp unmarshal(Date v) throws Exception {
return new Timestamp(v.getTime());
}

}


The reason I needed this done is because Timestamp does not have a public no-arg constructor and XStream could not marshall objects containing Timestamp objects. The nice solution to annotating these is to use package-info.java, you place this file in the same folder as the source java files, but it is not a typical source file. Here is the contents of my package-info.java:
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters
({
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=com.fourgablesguy.dao.hibernate.util.TimestampAdapter.class,type=java.sql.Timestamp.class)
})
package com.myama.dao.hibernate;

This package-info file is used by Java to annotate all classes in a package, with this single file my problem was resolved. My TimestampAdapter allowed me to marshall Timestamp objects with XStream. I used fully qualified names of classes in the package-info since I was not clear if you could import packages or if you had package access to the enclosing namespace.

No comments:

About Me

My photo
Lead Java Developer Husband and Father

Tags