001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.core.persistence;
021    
022    import org.apache.commons.io.IOUtils;
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.ibatis.builder.xml.XMLMapperBuilder;
025    import org.apache.ibatis.mapping.Environment;
026    import org.apache.ibatis.session.*;
027    import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
028    import org.sonar.api.BatchComponent;
029    import org.sonar.api.ServerComponent;
030    import org.sonar.core.dashboard.*;
031    import org.sonar.core.duplication.DuplicationMapper;
032    import org.sonar.core.duplication.DuplicationUnitDto;
033    import org.sonar.core.resource.ResourceDto;
034    import org.sonar.core.resource.ResourceIndexDto;
035    import org.sonar.core.resource.ResourceIndexerMapper;
036    import org.sonar.core.review.ReviewDto;
037    import org.sonar.core.review.ReviewMapper;
038    import org.sonar.core.rule.RuleDto;
039    import org.sonar.core.rule.RuleMapper;
040    import org.sonar.core.template.LoadedTemplateDto;
041    import org.sonar.core.template.LoadedTemplateMapper;
042    
043    import java.io.IOException;
044    import java.io.InputStream;
045    
046    public class MyBatis implements BatchComponent, ServerComponent {
047    
048      private Database database;
049      private SqlSessionFactory sessionFactory;
050    
051      public MyBatis(Database database) {
052        this.database = database;
053      }
054    
055      public MyBatis start() throws IOException {
056        Configuration conf = new Configuration();
057        conf.setEnvironment(new Environment("production", createTransactionFactory(), database.getDataSource()));
058        conf.setUseGeneratedKeys(true);
059        conf.setLazyLoadingEnabled(false);
060    
061        loadAlias(conf, "ActiveDashboard", ActiveDashboardDto.class);
062        loadAlias(conf, "Dashboard", DashboardDto.class);
063        loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class);
064        loadAlias(conf, "LoadedTemplate", LoadedTemplateDto.class);
065        loadAlias(conf, "Review", ReviewDto.class);
066        loadAlias(conf, "Resource", ResourceDto.class);
067        loadAlias(conf, "ResourceIndex", ResourceIndexDto.class);
068        loadAlias(conf, "Rule", RuleDto.class);
069        loadAlias(conf, "Widget", WidgetDto.class);
070        loadAlias(conf, "WidgetProperty", WidgetPropertyDto.class);
071    
072        loadMapper(conf, ActiveDashboardMapper.class);
073        loadMapper(conf, DashboardMapper.class);
074        loadMapper(conf, DuplicationMapper.class);
075        loadMapper(conf, LoadedTemplateMapper.class);
076        loadMapper(conf, ReviewMapper.class);
077        loadMapper(conf, ResourceIndexerMapper.class);
078        loadMapper(conf, RuleMapper.class);
079        loadMapper(conf, WidgetMapper.class);
080        loadMapper(conf, WidgetPropertyMapper.class);
081    
082        sessionFactory = new SqlSessionFactoryBuilder().build(conf);
083        return this;
084      }
085    
086      public SqlSessionFactory getSessionFactory() {
087        return sessionFactory;
088      }
089    
090      public SqlSession openSession() {
091        return sessionFactory.openSession();
092      }
093    
094      public SqlSession openSession(ExecutorType type) {
095        return sessionFactory.openSession(type);
096      }
097    
098      private void loadMapper(Configuration conf, Class mapperClass) throws IOException {
099        // trick to use database-specific XML files for a single Mapper Java interface
100        InputStream input = getPathToMapper(mapperClass);
101        try {
102          XMLMapperBuilder mapperParser = new XMLMapperBuilder(input, conf, mapperClass.getName(), conf.getSqlFragments());
103          mapperParser.parse();
104          conf.addLoadedResource(mapperClass.getName());
105    
106        } finally {
107          IOUtils.closeQuietly(input);
108        }
109      }
110    
111      private InputStream getPathToMapper(Class mapperClass) {
112        InputStream input = getClass().getResourceAsStream(
113          "/" + StringUtils.replace(mapperClass.getName(), ".", "/") + "-" + database.getDialect().getId() + ".xml");
114        if (input == null) {
115          input = getClass().getResourceAsStream("/" + StringUtils.replace(mapperClass.getName(), ".", "/") + ".xml");
116        }
117        return input;
118      }
119    
120      private void loadAlias(Configuration conf, String alias, Class dtoClass) {
121        conf.getTypeAliasRegistry().registerAlias(alias, dtoClass);
122      }
123    
124      private static JdbcTransactionFactory createTransactionFactory() {
125        return new JdbcTransactionFactory();
126      }
127    
128    }