001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.datasource;
017
018import com.mybatisflex.core.exception.FlexExceptions;
019import com.mybatisflex.core.util.ClassUtil;
020import org.apache.ibatis.logging.LogFactory;
021
022import javax.sql.DataSource;
023import java.lang.reflect.Method;
024
025/**
026 * @author michael
027 */
028public class DataSourceManager {
029
030    private static DataSourceDecipher decipher;
031
032    public static DataSourceDecipher getDecipher() {
033        return decipher;
034    }
035
036    public static void setDecipher(DataSourceDecipher decipher) {
037        DataSourceManager.decipher = decipher;
038    }
039
040
041    public static void decryptDataSource(DataSource dataSource) {
042        if (decipher == null) {
043            return;
044        }
045
046        try {
047            restartDataSource(dataSource);
048        } catch (Exception ignored) {
049            // do nothing here.
050        }
051
052        for (DataSourceProperty property : DataSourceProperty.values()) {
053            Method getterMethod = ClassUtil.getAnyMethod(dataSource.getClass(), property.getGetterMethods());
054            if (getterMethod != null) {
055                String value = invokeMethod(getterMethod, dataSource);
056                if (value != null) {
057                    value = decipher.decrypt(property, value);
058                    Method setter = ClassUtil.getAnyMethod(dataSource.getClass(), property.getSetterMethods());
059                    if (setter != null && value != null) {
060                        invokeMethod(setter, dataSource, value);
061                    }
062                }
063            }
064        }
065    }
066
067    static void restartDataSource(DataSource dataSource) {
068        Method restartMethod = ClassUtil.getFirstMethod(ClassUtil.getUsefulClass(dataSource.getClass())
069            , method -> "restart".equals(method.getName()) && method.getParameterCount() == 0);
070        if (restartMethod != null) {
071            try {
072                restartMethod.invoke(dataSource);
073            } catch (Exception e) {
074                throw FlexExceptions.wrap(e);
075            }
076        }
077    }
078
079
080    static String invokeMethod(Method method, Object object, Object... params) {
081        try {
082            return (String) method.invoke(object, params);
083        } catch (Exception e) {
084            LogFactory.getLog(DataSourceManager.class).error("Can not invoke method: " + method.getName(), e);
085        }
086        return null;
087    }
088
089
090}