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.persistence;
021
022 import java.io.IOException;
023 import java.io.InputStream;
024
025 import org.apache.commons.io.IOUtils;
026 import org.apache.commons.lang.StringUtils;
027 import org.apache.ibatis.builder.xml.XMLMapperBuilder;
028 import org.apache.ibatis.mapping.Environment;
029 import org.apache.ibatis.session.*;
030 import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
031 import org.sonar.api.BatchComponent;
032 import org.sonar.api.ServerComponent;
033 import org.sonar.persistence.model.DuplicationMapper;
034 import org.sonar.persistence.model.DuplicationUnit;
035 import org.sonar.persistence.model.Rule;
036 import org.sonar.persistence.model.RuleMapper;
037
038 public class MyBatis implements BatchComponent, ServerComponent {
039
040 private Database database;
041 private SqlSessionFactory sessionFactory;
042
043 public MyBatis(Database database) {
044 this.database = database;
045 }
046
047 public MyBatis start() throws IOException {
048 Configuration conf = new Configuration();
049 conf.setEnvironment(new Environment("production", createTransactionFactory(), database.getDataSource()));
050 conf.setUseGeneratedKeys(true);
051 conf.setLazyLoadingEnabled(false);
052
053 loadAlias(conf, "DuplicationUnit", DuplicationUnit.class);
054 loadAlias(conf, "Rule", Rule.class);
055 loadMapper(conf, DuplicationMapper.class);
056 loadMapper(conf, RuleMapper.class);
057
058 sessionFactory = new SqlSessionFactoryBuilder().build(conf);
059 return this;
060 }
061
062 public SqlSessionFactory getSessionFactory() {
063 return sessionFactory;
064 }
065
066 public SqlSession openSession() {
067 return sessionFactory.openSession();
068 }
069
070 public SqlSession openSession(ExecutorType type) {
071 return sessionFactory.openSession(type);
072 }
073
074
075 private void loadMapper(Configuration conf, Class mapperClass) throws IOException {
076 // trick to use database-specific XML files for a single Mapper Java interface
077 InputStream input = getPathToMapper(mapperClass);
078 try {
079 XMLMapperBuilder mapperParser = new XMLMapperBuilder(input, conf, mapperClass.getName(), conf.getSqlFragments());
080 mapperParser.parse();
081 conf.addLoadedResource(mapperClass.getName());
082
083 } finally {
084 IOUtils.closeQuietly(input);
085 }
086 }
087
088 private InputStream getPathToMapper(Class mapperClass) {
089 InputStream input = getClass().getResourceAsStream("/" + StringUtils.replace(mapperClass.getName(), ".", "/") + "-" + database.getDialect().getId() + ".xml");
090 if (input == null) {
091 input = getClass().getResourceAsStream("/" + StringUtils.replace(mapperClass.getName(), ".", "/") + ".xml");
092 }
093 return input;
094 }
095
096 private void loadAlias(Configuration conf, String alias, Class dtoClass) {
097 conf.getTypeAliasRegistry().registerAlias(alias, dtoClass);
098 }
099
100 private static JdbcTransactionFactory createTransactionFactory() {
101 return new JdbcTransactionFactory();
102 }
103
104 }