All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mybatisflex.core.util.FieldWrapper Maven / Gradle / Ivy

There is a newer version: 1.10.5
Show newest version
/*
 *  Copyright (c) 2022-2025, Mybatis-Flex ([email protected]).
 *  

* 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.mybatisflex.core.util; import com.mybatisflex.annotation.Column; import org.apache.ibatis.reflection.Reflector; import java.lang.reflect.*; import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class FieldWrapper { public static Map, Map> cache = new ConcurrentHashMap<>(); private Field field; private boolean isIgnore = false; private Class fieldType; private Class mappingType; private Class keyType; private Method getterMethod; private Method setterMethod; public static FieldWrapper of(Class clazz, String fieldName) { Map wrapperMap = cache.get(clazz); if (wrapperMap == null) { synchronized (clazz) { wrapperMap = cache.get(clazz); if (wrapperMap == null) { wrapperMap = new ConcurrentHashMap<>(); cache.put(clazz, wrapperMap); } } } FieldWrapper fieldWrapper = wrapperMap.get(fieldName); if (fieldWrapper == null) { synchronized (clazz) { fieldWrapper = wrapperMap.get(fieldName); if (fieldWrapper == null) { Field findField = ClassUtil.getFirstField(clazz, field -> field.getName().equalsIgnoreCase(fieldName)); if (findField == null) { throw new IllegalStateException("Can not find field \"" + fieldName + "\" in class: " + clazz.getName()); } String setterName = "set" + StringUtil.firstCharToUpperCase(findField.getName()); Method setter = ClassUtil.getFirstMethod(clazz, method -> method.getParameterCount() == 1 && Modifier.isPublic(method.getModifiers()) && method.getName().equals(setterName)); fieldWrapper = new FieldWrapper(); fieldWrapper.field = findField; fieldWrapper.fieldType = findField.getType(); initMappingTypeAndKeyType(clazz, findField, fieldWrapper); Column column = findField.getAnnotation(Column.class); if (column != null && column.ignore()) { fieldWrapper.isIgnore = true; } fieldWrapper.setterMethod = setter; String[] getterNames = new String[]{"get" + StringUtil.firstCharToUpperCase(findField.getName()), "is" + StringUtil.firstCharToUpperCase(findField.getName())}; fieldWrapper.getterMethod = ClassUtil.getFirstMethod(clazz, method -> method.getParameterCount() == 0 && Modifier.isPublic(method.getModifiers()) && ArrayUtil.contains(getterNames, method.getName())); wrapperMap.put(fieldName, fieldWrapper); } } } return fieldWrapper; } private static void initMappingTypeAndKeyType(Class clazz, Field field, FieldWrapper fieldWrapper) { Reflector reflector = Reflectors.of(clazz); Class fieldType = reflector.getGetterType(field.getName()); if (Collection.class.isAssignableFrom(fieldType)) { Type genericType = field.getGenericType(); try{ //使用Kotlin时,若Collection泛型类型为协变类型时(如 List),并且传入的具体泛型类型为open,genericType的具体类型为WildcardType(? extends ExampleClass),该类型不可转为Class(无具体类型),使用instanceOf会抛出转换异常。 //该错误目前只在以上情况中发现 if (genericType instanceof ParameterizedType) { Type actualTypeArgument = ((ParameterizedType) genericType).getActualTypeArguments()[0]; fieldWrapper.mappingType = (Class) actualTypeArgument; } }catch (ClassCastException e){ throw new UnsupportedOperationException(String.format("不支持使用[%s]作为集合类型。请使用MutableList",fieldType.getName())); } } else if (Map.class.isAssignableFrom(fieldType)) { Type genericType = field.getGenericType(); if (genericType instanceof ParameterizedType) { fieldWrapper.keyType = (Class) ((ParameterizedType) genericType).getActualTypeArguments()[0]; Type actualTypeArgument = ((ParameterizedType) genericType).getActualTypeArguments()[1]; if (actualTypeArgument instanceof ParameterizedType) { fieldWrapper.mappingType = (Class) ((ParameterizedType) actualTypeArgument).getRawType(); } else { fieldWrapper.mappingType = (Class) actualTypeArgument; } } } else { fieldWrapper.mappingType = fieldType; } } public void set(Object value, Object to) { try { if (setterMethod == null) { throw new IllegalStateException("Can not find method \"set" + StringUtil.firstCharToUpperCase(field.getName()) + "\" in class: " + to.getClass().getName()); } setterMethod.invoke(to, value); } catch (Exception e) { throw new RuntimeException(e); } } public Object get(Object target) { try { if (getterMethod == null) { throw new IllegalStateException("Can not find method \"get" + StringUtil.firstCharToUpperCase(field.getName()) + ", is" + StringUtil.firstCharToUpperCase(field.getName()) + "\" in class: " + target.getClass().getName()); } return getterMethod.invoke(target); } catch (Exception e) { throw new RuntimeException(e); } } public Class getFieldType() { return fieldType; } public Class getMappingType() { return mappingType; } public Class getKeyType() { return keyType; } public Field getField() { return field; } public boolean isIgnore() { return isIgnore; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy