content: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   *
   * 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.druid.support.ibatis;
  
  import com.alibaba.druid.support.logging.Log;
  import com.alibaba.druid.support.logging.LogFactory;
  import com.ibatis.sqlmap.client.SqlMapExecutor;
  import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
  import com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl;
  import com.ibatis.sqlmap.engine.scope.SessionScope;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  
  public class IbatisUtils {
      private static Log LOG = LogFactory.getLog(IbatisUtils.class);
  
      private static boolean VERSION_2_3_4;
  
      private static Method methodGetId;
      private static Method methodGetResource;
      private static Field sessionField;
  
      static {
          try {
              Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass("com.ibatis.sqlmap.engine.mapping.result.AutoResultMap");
              Method[] methods = clazz.getMethods();
              for (Method method : methods) {
                  if (method.getName().equals("setResultObjectValues")) { // ibatis 2.3.4 add method 'setResultObjectValues'
                      VERSION_2_3_4 = true;
                      break;
                  }
              }
          } catch (Throwable e) {
              LOG.error("Error while initializing", e);
          }
      }
  
      public static boolean isVersion2_3_4() {
          return VERSION_2_3_4;
      }
  
      public static SqlMapExecutor setClientImpl(SqlMapExecutor session, SqlMapClientImplWrapper clientImplWrapper) {
          if (session == null || clientImplWrapper == null) {
              return session;
          }
  
          if (session.getClass() == SqlMapSessionImpl.class) {
              SqlMapSessionImpl sessionImpl = (SqlMapSessionImpl) session;
              set(sessionImpl, clientImplWrapper);
          }
  
          return session;
      }
  
      /**
       * 通过反射的方式得到id，能够兼容2.3.0和2.3.4
       *
       * @param statement the statement object from which to retrieve the ID
       * @return the ID as a string, or null if an error occurs or if the ID is null
       */
      protected static String getId(Object statement) {
          try {
              if (methodGetId == null) {
                  Class<?> clazz = statement.getClass();
                  methodGetId = clazz.getMethod("getId");
              }
  
              Object returnValue = methodGetId.invoke(statement);
  
              if (returnValue == null) {
                  return null;
              }
  
              return returnValue.toString();
          } catch (Exception ex) {
              LOG.error("createIdError", ex);
              return null;
          }
      }
  
      /**
       * 通过反射的方式得到resource，能够兼容2.3.0和2.3.4
       *
       * @param statement the statement object from which to retrieve the resource
       * @return the resource as a string, or null if an error occurs
       */
      protected static String getResource(Object statement) {
          try {
              if (methodGetResource == null) {
                  methodGetResource = statement.getClass().getMethod("getResource");
              }
  
              return (String) methodGetResource.invoke(statement);
          } catch (Exception ex) {
              return null;
          }
      }
  
      public static void set(SqlMapSessionImpl session, SqlMapClientImpl client) {
          if (sessionField == null) {
              for (Field field : SqlMapSessionImpl.class.getDeclaredFields()) {
                  if (field.getName().equals("session") || field.getName().equals("sessionScope")) {
                      sessionField = field;
                      sessionField.setAccessible(true);
                      break;
                  }
              }
          }
  
          if (sessionField != null) {
              SessionScope sessionScope;
              try {
                  sessionScope = (SessionScope) sessionField.get(session);
  
                  if (sessionScope != null) {
                      if (sessionScope.getSqlMapClient() != null && sessionScope.getSqlMapClient().getClass() == SqlMapClientImpl.class) {
                          sessionScope.setSqlMapClient(client);
                      }
                      if (sessionScope.getSqlMapExecutor() != null && sessionScope.getSqlMapExecutor().getClass() == SqlMapClientImpl.class) {
                          sessionScope.setSqlMapExecutor(client);
                      }
                      if (sessionScope.getSqlMapTxMgr() != null && sessionScope.getSqlMapTxMgr().getClass() == SqlMapClientImpl.class) {
                          sessionScope.setSqlMapTxMgr(client);
                      }
                  }
              } catch (Exception e) {
                  LOG.error(e.getMessage(), e);
              }
          }
      }
  }
  