com.alibaba.otter.node.etl.common.db.dialect.DbDialectFactory.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.otter.node.etl.common.db.dialect.DbDialectFactory.java

Source

/*
 * Copyright (C) 2010-2101 Alibaba Group Holding Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.otter.node.etl.common.db.dialect;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;

import com.alibaba.otter.node.etl.common.datasource.DataSourceService;
import com.alibaba.otter.shared.common.model.config.data.db.DbMediaSource;
import com.google.common.base.Function;
import com.google.common.collect.GenericMapMaker;
import com.google.common.collect.MapEvictionListener;
import com.google.common.collect.MapMaker;

/**
 * @author jianghang 2011-10-27 ?02:12:06
 * @version 4.0.0
 */
public class DbDialectFactory implements DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(DbDialectFactory.class);
    private DataSourceService dataSourceService;
    private DbDialectGenerator dbDialectGenerator;

    // pipelineId , DbMediaSource id
    private Map<Long, Map<DbMediaSource, DbDialect>> dialects;

    public DbDialectFactory() {
        // map
        GenericMapMaker mapMaker = null;
        mapMaker = new MapMaker().softValues()
                .evictionListener(new MapEvictionListener<Long, Map<DbMediaSource, DbDialect>>() {

                    public void onEviction(Long pipelineId, Map<DbMediaSource, DbDialect> dialect) {
                        if (dialect == null) {
                            return;
                        }

                        for (DbDialect dbDialect : dialect.values()) {
                            dbDialect.destory();
                        }
                    }
                });

        dialects = mapMaker.makeComputingMap(new Function<Long, Map<DbMediaSource, DbDialect>>() {

            public Map<DbMediaSource, DbDialect> apply(final Long pipelineId) {
                // map
                return new MapMaker().makeComputingMap(new Function<DbMediaSource, DbDialect>() {

                    public DbDialect apply(final DbMediaSource source) {
                        DataSource dataSource = dataSourceService.getDataSource(pipelineId, source);
                        final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
                        return (DbDialect) jdbcTemplate.execute(new ConnectionCallback() {

                            public Object doInConnection(Connection c) throws SQLException, DataAccessException {
                                DatabaseMetaData meta = c.getMetaData();
                                String databaseName = meta.getDatabaseProductName();
                                int databaseMajorVersion = meta.getDatabaseMajorVersion();
                                int databaseMinorVersion = meta.getDatabaseMinorVersion();
                                DbDialect dialect = dbDialectGenerator.generate(jdbcTemplate, databaseName,
                                        databaseMajorVersion, databaseMinorVersion, source.getType());
                                if (dialect == null) {
                                    throw new UnsupportedOperationException("no dialect for" + databaseName);
                                }

                                if (logger.isInfoEnabled()) {
                                    logger.info(String.format("--- DATABASE: %s, SCHEMA: %s ---", databaseName,
                                            (dialect.getDefaultSchema() == null) ? dialect.getDefaultCatalog()
                                                    : dialect.getDefaultSchema()));
                                }

                                return dialect;
                            }
                        });

                    }
                });
            }
        });

    }

    public DbDialect getDbDialect(Long pipelineId, DbMediaSource source) {
        return dialects.get(pipelineId).get(source);
    }

    public void destory(Long pipelineId) {
        Map<DbMediaSource, DbDialect> dialect = dialects.remove(pipelineId);
        if (dialect != null) {
            for (DbDialect dbDialect : dialect.values()) {
                dbDialect.destory();
            }
        }
    }

    public void destroy() throws Exception {
        Set<Long> pipelineIds = new HashSet<Long>(dialects.keySet());
        for (Long pipelineId : pipelineIds) {
            destory(pipelineId);
        }
    }

    // =============== setter / getter =================

    public void setDataSourceService(DataSourceService dataSourceService) {
        this.dataSourceService = dataSourceService;
    }

    public void setDbDialectGenerator(DbDialectGenerator dbDialectGenerator) {
        this.dbDialectGenerator = dbDialectGenerator;
    }

}