org.workspace7.osgi.mybatis.extender.impl.MyBatisMapperRegistry.java Source code

Java tutorial

Introduction

Here is the source code for org.workspace7.osgi.mybatis.extender.impl.MyBatisMapperRegistry.java

Source

/*
 *
 *    Copyright (c) 2016. Kamesh Sampath.
 *
 *    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 org.workspace7.osgi.mybatis.extender.impl;

import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.jdbc.DataSourceFactory;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * @author kameshs
 */
public class MyBatisMapperRegistry {

    private static final Logger logger = LoggerFactory.getLogger(MyBatisMapperRegistry.class);

    private BundleContext bundleContext;

    private Set<Bundle> activeBundles = new HashSet();

    private Hashtable<String, Environment> registeredEnvironments = new Hashtable<>();
    private Hashtable<String, ServiceRegistration> registeredSqlSessionFactories = new Hashtable<>();
    private ServiceTracker environmentServiceTracker;

    public MyBatisMapperRegistry(final BundleContext bundleContext) {

        this.bundleContext = bundleContext;

        //Open Service Tracker to grab the registered mybatis environments

        environmentServiceTracker = new ServiceTracker(bundleContext, Environment.class.getName(),
                new ServiceTrackerCustomizer() {
                    @Override
                    public Object addingService(ServiceReference serviceReference) {

                        String configName = (String) serviceReference
                                .getProperty(DataSourceFactory.JDBC_DATASOURCE_NAME);

                        Environment myBatisEnv = (Environment) bundleContext.getService(serviceReference);

                        if (!registeredEnvironments.containsKey(configName)) {
                            registeredEnvironments.put(configName, myBatisEnv);
                        }

                        logger.info("Adding Environment {} to local cache ", configName);

                        return myBatisEnv;
                    }

                    @Override
                    public void modifiedService(ServiceReference serviceReference, Object o) {

                    }

                    @Override
                    public void removedService(ServiceReference serviceReference, Object o) {

                        String configName = (String) serviceReference
                                .getProperty(DataSourceFactory.JDBC_DATASOURCE_NAME);

                        if (registeredEnvironments.containsKey(configName)) {
                            registeredEnvironments.remove(configName);
                            logger.info("Removed Configuration {} from local cache ", configName);
                        }
                    }
                });

        environmentServiceTracker.open();
    }

    public void registerBundle(Bundle bundle) {

        Map<String, List<String>> dsMappers = ExtenderUtil.getMapperClauses(bundle);

        for (String dsName : dsMappers.keySet()) {

            Environment environment = registeredEnvironments.get(dsName);

            Configuration configuration = new Configuration(environment);

            if (configuration != null) {

                List<String> packageNames = dsMappers.get(dsName);

                for (String packageName : packageNames) {

                    String cleanPackageName = packageName.trim();

                    logger.info("Adding mappers and xmls from  package {} to Configuration {}", cleanPackageName,
                            dsName);

                    configuration.addMappers(cleanPackageName);

                    Enumeration<URL> mapperXmls = ExtenderUtil.findFilesFromBundle(bundle, packageName, "*.xml");

                    if (mapperXmls != null) {
                        while (mapperXmls.hasMoreElements()) {

                            URL mapperxmlUrl = mapperXmls.nextElement();

                            try {

                                String mappingFile = ExtenderUtil.mappingFileName(mapperxmlUrl.getFile());

                                logger.info("Adding Mapper XML {} to Config {} ", mappingFile, dsName);

                                InputStream in = mapperxmlUrl.openStream();

                                XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(in, configuration,
                                        mappingFile, configuration.getSqlFragments());
                                xmlMapperBuilder.parse();

                                in.close();

                                Collection<String> mappedStatements = configuration.getMappedStatementNames();
                                for (String mappedStmt : mappedStatements) {
                                    logger.info(" Added Mapped Statement: {}", mappedStmt);
                                }

                                unregisterSqlSessionFactory(dsName);

                                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                                        .build(configuration);
                                Dictionary<String, String> props = new Hashtable<>();
                                props.put("dataSourceName", dsName);
                                ServiceRegistration serviceRegistration = bundleContext.registerService(
                                        SqlSessionFactory.class.getName(), sqlSessionFactory, props);

                                registeredSqlSessionFactories.put(dsName, serviceRegistration);

                            } catch (IOException e) {
                                logger.error("Unable to add mapper {} ", mapperxmlUrl.toString(), e);

                            }
                        }
                    }
                }
            }
        }

        logger.info("Registering Mapper Bundle {} ", bundle.getSymbolicName());

        activeBundles.add(bundle);

    }

    public void unregisterBundle(Bundle bundle) {

        logger.info("UnRegistering Mapper Bundle {} ", bundle.getSymbolicName());

        activeBundles.remove(bundle);

        Map<String, List<String>> dsMappers = ExtenderUtil.getMapperClauses(bundle);

        for (String dsName : dsMappers.keySet()) {

            unregisterSqlSessionFactory(dsName);
        }

    }

    public void close() {
        if (environmentServiceTracker != null) {
            environmentServiceTracker.close();
        }
    }

    private void unregisterSqlSessionFactory(String dsName) {
        if (registeredSqlSessionFactories.containsKey(dsName)) {
            logger.info("Unregistering SqlSession Factory {}:", dsName);
            ServiceRegistration serviceRegistration = registeredSqlSessionFactories.get(dsName);
            serviceRegistration.unregister();
            registeredSqlSessionFactories.remove(dsName);
        }
    }

}