private void createRowKeyForUnmappedProperties(
     ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, String columnPrefix)
     throws SQLException {
   final MetaClass metaType = MetaClass.forClass(resultMap.getType());
   List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
   for (String column : unmappedColumnNames) {
     String property = column;
     if (columnPrefix != null && columnPrefix.length() > 0) {
       // When columnPrefix is specified,
       // ignore columns without the prefix.
       if (column.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
         property = column.substring(columnPrefix.length());
       } else {
         continue;
       }
     }
     if (metaType.findProperty(property, configuration.isMapUnderscoreToCamelCase()) != null) {
       String value = rsw.getResultSet().getString(column);
       if (value != null) {
         cacheKey.update(column);
         cacheKey.update(value);
       }
     }
   }
 }
 private void settingsElement(XNode context) throws Exception {
   if (context != null) {
     Properties props = context.getChildrenAsProperties();
     // Check that all settings are known to the configuration class
     MetaClass metaConfig = MetaClass.forClass(Configuration.class);
     for (Object key : props.keySet()) {
       if (!metaConfig.hasSetter(String.valueOf(key))) {
         throw new BuilderException(
             "The setting "
                 + key
                 + " is not known.  Make sure you spelled it correctly (case sensitive).");
       }
     }
     configuration.setAutoMappingBehavior(
         AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
     configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
     configuration.setProxyFactory(
         (ProxyFactory) createInstance(props.getProperty("proxyFactory")));
     configuration.setLazyLoadingEnabled(
         booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
     configuration.setAggressiveLazyLoading(
         booleanValueOf(props.getProperty("aggressiveLazyLoading"), true));
     configuration.setMultipleResultSetsEnabled(
         booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
     configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
     configuration.setUseGeneratedKeys(
         booleanValueOf(props.getProperty("useGeneratedKeys"), false));
     configuration.setDefaultExecutorType(
         ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
     configuration.setDefaultStatementTimeout(
         integerValueOf(props.getProperty("defaultStatementTimeout"), null));
     configuration.setMapUnderscoreToCamelCase(
         booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
     configuration.setSafeRowBoundsEnabled(
         booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
     configuration.setLocalCacheScope(
         LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
     configuration.setJdbcTypeForNull(
         JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
     configuration.setLazyLoadTriggerMethods(
         stringSetValueOf(
             props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
     configuration.setSafeResultHandlerEnabled(
         booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
     configuration.setDefaultScriptingLanguage(
         resolveClass(props.getProperty("defaultScriptingLanguage")));
     configuration.setCallSettersOnNulls(
         booleanValueOf(props.getProperty("callSettersOnNulls"), false));
     configuration.setLogPrefix(props.getProperty("logPrefix"));
     configuration.setLogImpl(resolveClass(props.getProperty("logImpl")));
     configuration.setConfigurationFactory(
         resolveClass(props.getProperty("configurationFactory")));
   }
 }
 /**
  * copy from mybatis sourceCode
  *
  * @param resultType
  * @param property
  * @param javaType
  * @return
  */
 private Class<?> resolveResultJavaType(Class<?> resultType, String property, Class<?> javaType) {
   if (javaType == null && property != null) {
     try {
       MetaClass metaResultType = MetaClass.forClass(resultType, REFLECTOR_FACTORY);
       javaType = metaResultType.getSetterType(property);
     } catch (Exception ignored) {
       // ignore, following null check statement will deal with the
       // situation
     }
   }
   if (javaType == null) {
     javaType = Object.class;
   }
   return javaType;
 }
  public static String getPropertyNameForAssociationEntity(
      Class<?> entityClass, MetaClass metaClass, String key) {
    String[] readablePropertyNames = metaClass.getGetterNames();
    for (String propertyName : readablePropertyNames) {
      Method getterMethod = findGetterMethod(propertyName, entityClass);
      if (getterMethod == null) {
        continue;
      }

      Association association = AnnotationUtils.findAnnotation(getterMethod, Association.class);
      if (association != null) {
        String joinColumn = association.joinColumn();
        if (key.equals(joinColumn)) {
          return propertyName;
        }
      }
    }

    return null;
  }
  private TypeHandler resolveTypeHandler(
      Class clazz, String propertyName, String javaType, JdbcType jdbcType) {
    TypeHandler handler;
    if (clazz == null) {
      // Unknown
      handler = typeHandlerRegistry.getUnknownTypeHandler();
    } else if (java.util.Map.class.isAssignableFrom(clazz)) {
      // Map
      if (javaType == null) {
        handler = typeHandlerRegistry.getUnknownTypeHandler(); // BUG 1012591 -
        // typeHandlerRegistry.getTypeHandler(java.lang.Object.class, jdbcType);
      } else {
        try {
          Class javaClass = typeAliasRegistry.resolveAlias(javaType);
          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
        } catch (Exception e) {
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
        }
      }
    } else if (typeHandlerRegistry.getTypeHandler(clazz, jdbcType) != null) {
      // Primitive
      handler = typeHandlerRegistry.getTypeHandler(clazz, jdbcType);
    } else {
      // JavaBean
      if (javaType == null) {

        Class type = MetaClass.forClass(clazz).getGetterType(propertyName);
        handler = typeHandlerRegistry.getTypeHandler(type, jdbcType);

      } else {
        try {
          Class javaClass = typeAliasRegistry.resolveAlias(javaType);
          handler = typeHandlerRegistry.getTypeHandler(javaClass, jdbcType);
        } catch (Exception e) {
          throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
        }
      }
    }
    return handler;
  }
  public static <T> List<ColumnModel> getColumnModelListForUpdate(
      Configuration configuration,
      Class<?> entityClass,
      T entity,
      boolean isMapUnderscoreToCamelCase,
      Map<String, Object> parameterMap) {
    MetaClass metaClass = MetaClass.forClass(entityClass, configuration.getReflectorFactory());
    String[] readablePropertyNames = metaClass.getGetterNames();

    List<ColumnModel> columnModelList = new ArrayList<ColumnModel>();
    ColumnModel columnModel = null;
    for (String propertyName : readablePropertyNames) {
      Method getterMethod = findGetterMethod(propertyName, entityClass);
      if (getterMethod == null) {
        continue;
      }

      if (AnnotationUtils.findAnnotation(getterMethod, Transient.class) != null
          || AnnotationUtils.findAnnotation(getterMethod, CreatedDate.class) != null) {
        continue;
      }

      columnModel = new ColumnModel();
      try {
        Invoker method = metaClass.getGetInvoker(propertyName);
        try {
          Object value = method.invoke(entity, null);
          String columnName = getColumnName(propertyName, isMapUnderscoreToCamelCase);

          // Handle PK
          if (AnnotationUtils.findAnnotation(getterMethod, Id.class) != null) {
            Assert.notNull(value, propertyName + " is required");
            parameterMap.put(columnName, value);
            continue;
          }

          // Handle the property that annotated by ${#link ModifiedDate}
          if (AnnotationUtils.findAnnotation(getterMethod, ModifiedDate.class) != null) {
            if (methodReturnTypeCheck(getterMethod, Date.class)) {
              value = new Date();
            }
          }

          if (value != null
              || AnnotationUtils.findAnnotation(getterMethod, NullableForUpdate.class) != null) {
            // Handle the property that annotated by {#link Enumerated}
            Enumerated enumrated = AnnotationUtils.findAnnotation(getterMethod, Enumerated.class);
            if (enumrated != null) {
              if (enumrated.value() == EnumType.ORDINAL) {
                Class<?> returnType = getterMethod.getReturnType();
                value =
                    Enum.valueOf(returnType.asSubclass(Enum.class), String.valueOf(value))
                        .ordinal();
              }
            }

            // Handle the property that annotated by {#link Association}
            if (AnnotationUtils.findAnnotation(getterMethod, Association.class) != null) {
              Association association =
                  AnnotationUtils.findAnnotation(getterMethod, Association.class);
              String joinColumn = association.joinColumn();
              if (joinColumn == null || "".equals(joinColumn.trim())) {
                columnName = columnName + "_id";
              } else {
                columnName = association.joinColumn();
              }

              Class<?> returnType = getterMethod.getReturnType();
              MetaClass associationMetaClass =
                  MetaClass.forClass(returnType, configuration.getReflectorFactory());
              Invoker m =
                  associationMetaClass.getGetInvoker(
                      "id"); // TODO, now just support the primary key that named "id"
              value = m.invoke(value, null);
            }

            columnModel.setName(columnName);
            columnModel.setValue(value);
            columnModelList.add(columnModel);
          }

        } catch (Throwable t) {
          throw ExceptionUtil.unwrapThrowable(t);
        }
      } catch (Throwable t) {
        throw new ReflectionException(
            "Could not get the value of property '"
                + propertyName
                + "' of '"
                + entityClass
                + "' Cause: "
                + t.toString(),
            t);
      }
    }

    return columnModelList;
  }
  public static <T> T populate(
      Configuration configuration,
      Class<?> entityClass,
      T entity,
      Map<String, Object> resultMap,
      boolean isMapUnderscoreToCamelCase) {
    MetaClass metaClass = MetaClass.forClass(entityClass, configuration.getReflectorFactory());

    for (String key : resultMap.keySet()) {
      String property = metaClass.findProperty(key, isMapUnderscoreToCamelCase);
      if (property == null) {
        property =
            metaClass.findProperty(
                key.replace("_id", ""),
                isMapUnderscoreToCamelCase); // just for association entity property
        if (property == null) {
          property = getPropertyNameForAssociationEntity(entityClass, metaClass, key);
        }
      }

      if (property != null && metaClass.hasSetter(property)) {
        Object value = resultMap.get(key);
        try {
          Method getterMethod = findGetterMethod(property, entityClass);

          // Handle the property that annotated by {#link Enumerated}.
          Enumerated enumrated = AnnotationUtils.findAnnotation(getterMethod, Enumerated.class);
          if (enumrated != null) {
            Class<?> returnType = getterMethod.getReturnType();
            if (enumrated.value() == EnumType.STRING) {
              value = Enum.valueOf(returnType.asSubclass(Enum.class), String.valueOf(value));
            } else {
              value = returnType.asSubclass(Enum.class).getEnumConstants()[(int) value];
            }
          }

          // Handler the property that annotated by {#link Association}
          Association association = AnnotationUtils.findAnnotation(getterMethod, Association.class);
          if (association != null) {
            Class<?> returnType = getterMethod.getReturnType();
            MetaClass associationMetaClass =
                MetaClass.forClass(returnType, configuration.getReflectorFactory());
            Invoker m = associationMetaClass.getSetInvoker("id");
            Object associationEntity = returnType.newInstance();
            Object[] params = {value};
            m.invoke(associationEntity, params);
            value = associationEntity;
          }

          Invoker method = metaClass.getSetInvoker(property);
          Object[] params = {value};
          try {
            method.invoke(entity, params);
          } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
          }
        } catch (Throwable t) {
          throw new ReflectionException(
              "Could not set property '"
                  + property
                  + "' of '"
                  + entityClass
                  + "' with value '"
                  + value
                  + "' Cause: "
                  + t.toString(),
              t);
        }
      }
    }

    return entity;
  }