001package org.atteo.moonshine.hsqldb;
002
003import java.sql.SQLException;
004
005import javax.inject.Inject;
006import javax.sql.DataSource;
007import javax.xml.bind.annotation.XmlElement;
008import javax.xml.bind.annotation.XmlIDREF;
009import javax.xml.bind.annotation.XmlRootElement;
010
011import org.atteo.moonshine.database.DatabaseService;
012import org.atteo.moonshine.jta.JtaDataSourceWrapper;
013import org.atteo.moonshine.jta.JtaService;
014import org.atteo.moonshine.jta.PoolOptions;
015import org.atteo.moonshine.services.ImportService;
016import org.hsqldb.jdbc.pool.JDBCXADataSource;
017
018import com.google.inject.AbstractModule;
019import com.google.inject.Module;
020import com.google.inject.Provider;
021import com.google.inject.Singleton;
022
023/**
024 * Starts HSQLDB database.
025 */
026@XmlRootElement(name = "hsqldb")
027public class Hsqldb extends DatabaseService {
028    @XmlIDREF
029    @XmlElement
030    @ImportService
031    private JtaService jtaService;
032    @XmlElement
033    private String url = "jdbc:hsqldb:mem:mymemdb";
034
035    @XmlElement
036    private PoolOptions pool;
037
038    @Inject
039    private JtaDataSourceWrapper wrapper;
040
041    private DataSource dataSource;
042
043    @Singleton
044    private class DataSourceProvider implements Provider<DataSource> {
045        @Inject
046        private JtaDataSourceWrapper wrapper;
047
048        @Override
049        public DataSource get() {
050            final JDBCXADataSource xaDataSource;
051            try {
052                xaDataSource = new JDBCXADataSource();
053            } catch (SQLException e) {
054                throw new RuntimeException("Cannot create data source", e);
055            }
056            String name = "defaultDataSource";
057            if (getId() != null) {
058                name = getId();
059            }
060            xaDataSource.setUrl(url);
061            dataSource = wrapper.wrap(name, xaDataSource, pool, "VALUES 1");
062
063            executeMigrations(dataSource);
064            return dataSource;
065        }
066    }
067
068    @Override
069    public Module configure() {
070        return new AbstractModule() {
071            @Override
072            public void configure() {
073                bind(DataSource.class).toProvider(new DataSourceProvider()).in(Singleton.class);
074            }
075        };
076    }
077
078    @Override
079    public void close() {
080        if (dataSource != null) {
081            wrapper.close(dataSource);
082        }
083    }
084}