/*
 * Copyright 2016-2018 shardingsphere.io.
 * <p>
 * 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.
 * </p>
 */

package io.shardingsphere.transaction.common.config;

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import io.shardingsphere.core.constant.TransactionType;
import io.shardingsphere.core.util.EventBusInstance;
import io.shardingsphere.transaction.common.listener.TransactionListener;
import io.shardingsphere.transaction.common.spi.TransactionManager;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.ServiceLoader;

/**
 * Abstract transaction manager configuration.
 *
 * @author zhaojun
 */
@Slf4j
public abstract class TransactionConfigurationAdapter implements TransactionConfiguration {
    
    @Override
    public TransactionManager configTransactionContext(final TransactionType transactionType) {
        TransactionManager result = null;
        switch (transactionType) {
            case XA:
                result = doXaTransactionConfiguration();
                break;
            case BASE:
                break;
            default:
        }
        return result;
    }
    
    @Override
    public void registerListener() {
        EventBusInstance.getInstance().register(TransactionListener.getInstance());
    }
    
    protected abstract TransactionManager doXaTransactionConfiguration();
    
    protected Optional<TransactionManager> doSPIConfiguration() {
        List<TransactionManager> transactionManagerList = Lists.newArrayList(ServiceLoader.load(TransactionManager.class).iterator());
        if (transactionManagerList.size() > 1) {
            log.info("there is more than one transaction manger existing, chosen first one default.");
        }
        return transactionManagerList.isEmpty() ? Optional.<TransactionManager>absent() : Optional.of(transactionManagerList.get(0));
    }
}

@@ -1050,20 +1050,68 @@
 va.util.
-List
+HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0Aimport
@@ -1314,24 +1314,137 @@
 tion %7B%0A    %0A
+    private static final Map%3CTransactionType, Optional%3CTransactionManager%3E%3E SPI_RESOURCE = new HashMap%3C%3E();%0A    %0A
     @Overrid
@@ -1689,24 +1689,39 @@
 nfiguration(
+transactionType
 );%0A         
@@ -2062,16 +2062,47 @@
 uration(
+TransactionType transactionType
 );%0A    %0A
@@ -2163,20 +2163,220 @@
 uration(
-) %7B%0A
+final TransactionType transactionType) %7B%0A        if (SPI_RESOURCE.containsKey(transactionType)) %7B%0A            return SPI_RESOURCE.get(transactionType);%0A        %7D%0A        synchronized (SPI_RESOURCE) %7B%0A    
         
@@ -2506,24 +2506,28 @@
 ));%0A        
+    
 if (transact
@@ -2567,16 +2567,20 @@
         
+  
+  
 log.info
@@ -2662,16 +2662,20 @@
 ult.%22);%0A
+    
         
@@ -2684,22 +2684,69 @@
         
-return
+    Optional%3CTransactionManager%3E transactionManager =
  transac
@@ -2853,20 +2853,136 @@
 st.get(0));%0A
+            SPI_RESOURCE.put(transactionType, transactionManager);%0A            return transactionManager;%0A        %7D%0A
     %7D%0A%7D%0A

add local cache for transaction configuration adapter.