2009-05-04

Database Persistence in Confluence plugin

Last month I was busy with a Atlassian Confluence plugin for a local company. Next few blogs I'll devote to some problems I found in my way.
The plugin was about browsing existing Crowd users, create new users, attach pictures to users, make directory of cities (company is distributed to several cities), departments etc., similar to Userinfo example.

Developer documentation is quite useful while not complete... First thing I needed was to persist my dictionaries to database. After some discovering I've learned that Atlassian doesn't recommend using Hibernate (I couldn't attach mappings anyway) but provides Bandana instead (XML persistence based on XStream). It isn't going for me because I need to select, search, make relations between tables etc.. Make it all with Java classes?
Fortunatelly it is still possible to use pure SQL quieries. So these are the steps for using database in Confluence:
  1. declare DAO bean in atlassian-plugin.xml
  2. <spring name="citiesDao" key="citiesDao" 
    class="dot.userinfo.cities.dao.HibernateCitiesDao">
    <property name="sessionFactory">
    <ref bean="sessionFactory"/>
    </property>

    </spring>
    where sessionFactory is Hibernate's session factory provided by Confluence;
  3. implement DAO class and derive it from HibernateObjectDao (provided by Atlassian)
  4. public class HibernateCitiesDao 
    extends HibernateObjectDao {
    public Collection getAll() {
    List result = new ArrayList();
    Session session = null;
    try {
    session = getSessionFactory().openSession();
    ResultSet rs = session.connection().
    prepareStatement("select * from city").executeQuery();
    while (rs.next()) {
    CityInfo o = new CityInfo();
    fill(rs, o);
    result.add(o);
    }
    } finally {
    if (session != null) {
    session.disconnect();
    }
    }
    return result;
    }
    }
  5. connect DAO to an action in atlassian-plugin.xml:
  6. <action name="viewcities"
    class="dot.userinfo.cities.action.ViewCities">
    <external-ref name="citiesDao">citiesDao</external-ref>
    <result name="success" type="velocity">
    /templates/dot/userinfo/cities/viewcities.vm</result>
    </action>
    Class ViewCities must have a setter (and getter if you want to use it directly in page) methods for citiesDao:
    public void setCitiesDao(CitiesDao citiesDao) {
    this.citiesDao = citiesDao;
    }
    public CitiesDao getCitiesDao() {
    return citiesDao;
    }
  7. use cities on the page viewcities.vm:
  8. #set($cities = $action.citiesDao.all)
    #foreach( $item in $cities.iterator())
    ...
    #end

No comments:

Post a Comment