38.4. HibernateService Extension

The Hibernate distribution provides an implementation of HibernateServiceMBean in the class HibernateService. The MLet file above specifies an extension of this class that allows the HibernateService to be configured from an external file, such as the standard hibernate.cfg.xml file. There are a number of situations where it is desirable to use the Hibernate mapped classes outside of Jonas running a JMX server. This enables the Hibernate mapping files and properties to be specified in one place and used in multiple situations. If this is not needed, then the HibernateService class could be used directly.

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.jmx.HibernateService;

import org.apache.commons.digester.Digester;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;
/**
 * Extension of the HibernateService class to add configuration
 * ability from a Hibernate XML configuration file.
 * 
 * @author Jonny Wray
 *
 */
public class ConfigurableHibernateService extends HibernateService {

private static Log log = 
    LogFactory.getLog(ConfigurableHibernateService.class);

/**
 * Configure this HibernateService from an XML file
 * 
 * @param filename The Hibernate XML configuration file, for example
 * hibernate.cfg.xml
 * @param jndiName The JNDI name that the session factory will be 
 * registered under @param datasourceName 
 * The name of the datasource used by the session factory
 * @throws HibernateException 
 * If there's a problem reading the configuration file
 */
public ConfigurableHibernateService(String filename, 
    String jndiName, String datasourceName) 
        throws HibernateException{
        
        init(filename, jndiName, datasourceName);
        start();
}

private void init(String filename, String jndiName, 
    String datasourceName) throws HibernateException {
        if(log.isDebugEnabled()){
            log.debug("Configuring Hibernate JMX MBean with 
                filename "+filename+ ", JNDI name "+jndiName+" 
                and datasource "+datasourceName);
    }
    try{
        URL url = 
            this.getClass().getClassLoader().getResource(filename);
        Digester mappingDigester = configureMappingDigester();
        List results = 
            (List)mappingDigester.parse(url.openStream());
        Iterator it = results.iterator();
        while(it.hasNext()){
            StringBuffer buffer = (StringBuffer)it.next();
            addMapResource(buffer.toString());
            log.debug("Adding mapping resource "+buffer.toString());
        }
        
        Digester propertyDigester = configurePropertyDigester();
        Map resultMap = (Map)propertyDigester.parse(url.openStream());
        it = resultMap.keySet().iterator();
        while(it.hasNext()){
             String key = (String)it.next();
             String value = (String)resultMap.get(key);
             setProperty("hibernate."+key, value);
             log.debug("Adding property ("+key+","+value+")");
        }
        setJndiName(jndiName);
        setDatasource(datasourceName);
    }
    catch(IOException e){
        throw new HibernateException(e);
    }
    catch(SAXException e){
        throw new HibernateException(e);
    }
}

private Digester configureMappingDigester(){
    Digester digester = new Digester();
    digester.setClassLoader(this.getClass().getClassLoader());
    digester.setValidating(false);
    digester.addObjectCreate("hibernate-configuration/session-factory",
        ArrayList.class);
    
    digester.addObjectCreate(
        "hibernate-configuration/session-factory/mapping", 
        StringBuffer.class);
    digester.addCallMethod(
        "hibernate-configuration/session-factory/mapping", 
        "append", 1);
    digester.addCallParam(
        "hibernate-configuration/session-factory/mapping", 
        0, "resource");
    digester.addSetNext(
        "hibernate-configuration/session-factory/mapping", 
        "add");
    
    return digester;
}

private Digester configurePropertyDigester(){
    Digester digester = new Digester();
    digester.setClassLoader(this.getClass().getClassLoader());
    digester.setValidating(false);
    digester.addObjectCreate("hibernate-configuration/session-factory",
        HashMap.class);
    
    digester.addCallMethod(
        "hibernate-configuration/session-factory/property", "put", 2);
    digester.addCallParam(
        "hibernate-configuration/session-factory/property", 0, "name");
    digester.addCallParam(
        "hibernate-configuration/session-factory/property", 1);

    return digester;
}
}