001/*
002 * Copyright 2011 Atteo.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014package org.atteo.moonshine.h2;
015
016import javax.inject.Inject;
017import javax.sql.DataSource;
018import javax.xml.bind.annotation.XmlElement;
019import javax.xml.bind.annotation.XmlIDREF;
020import javax.xml.bind.annotation.XmlRootElement;
021
022import org.atteo.evo.config.XmlDefaultValue;
023import org.atteo.moonshine.database.DatabaseService;
024import org.atteo.moonshine.jta.JtaDataSourceWrapper;
025import org.atteo.moonshine.jta.JtaService;
026import org.atteo.moonshine.jta.PoolOptions;
027import org.atteo.moonshine.services.ImportService;
028import org.h2.jdbcx.JdbcDataSource;
029
030import com.google.inject.AbstractModule;
031import com.google.inject.Module;
032import com.google.inject.Provider;
033import com.google.inject.Scopes;
034
035/**
036 * Starts H2 database
037 */
038@XmlRootElement(name = "h2")
039public class H2 extends DatabaseService {
040    @XmlIDREF
041    @XmlElement
042    @ImportService
043    private JtaService jtaService;
044
045    /**
046     * Database URL.
047     * <p>
048     * By default file database is used. For in-memory database set url to:
049     * <pre>
050     * jdbc:h2:mem:;DB_CLOSE_DELAY=-1
051     * </pre>
052     * </p>
053     * @see <a href="http://www.h2database.com/html/features.html#database_url">H2 documentation</a>
054     */
055    @XmlElement
056    @XmlDefaultValue("jdbc:h2:${dataHome}/database")
057    private String url;
058
059    /**
060     * Database user.
061     */
062    @XmlElement
063    private String username = "";
064
065    /**
066     * Database password.
067     */
068    @XmlElement
069    private String password = "";
070
071    /**
072     * Connection pool options.
073     */
074    @XmlElement
075    private PoolOptions pool;
076
077    @XmlElement
078    private String testQuery = "select 1";
079
080    @Inject
081    private JtaDataSourceWrapper wrapper;
082
083    private DataSource dataSource;
084
085    private class DataSourceProvider implements Provider<DataSource> {
086        @Inject
087        private JtaDataSourceWrapper wrapper;
088
089        @Override
090        public DataSource get() {
091            final JdbcDataSource xaDataSource = new JdbcDataSource();
092            xaDataSource.setURL(url + ";DB_CLOSE_ON_EXIT=FALSE");
093            xaDataSource.setUser(username);
094            xaDataSource.setPassword(password);
095            String name = "defaultDataSource";
096            if (getId() != null) {
097                name = getId();
098                xaDataSource.setDescription(name);
099            }
100            dataSource = wrapper.wrap(name, xaDataSource, pool, testQuery);
101            executeMigrations(dataSource);
102            return dataSource;
103        }
104    }
105
106    @Override
107    public Module configure() {
108        return new AbstractModule() {
109            @Override
110            protected void configure() {
111                bind(DataSource.class).toProvider(new DataSourceProvider()).in(Scopes.SINGLETON);
112            }
113        };
114    }
115
116    @Override
117    public void close() {
118        if (wrapper != null) {
119            wrapper.close(dataSource);
120        }
121    }
122}