已修改3个文件
已删除256个文件
已添加23个文件
| | |
| | | <component name="ProjectModuleManager"> |
| | | <modules> |
| | | <module fileurl="file://$PROJECT_DIR$/.idea/PLTWEB.iml" filepath="$PROJECT_DIR$/.idea/PLTWEB.iml" /> |
| | | <module fileurl="file://$PROJECT_DIR$/Source/platformProject/platform-parent.iml" filepath="$PROJECT_DIR$/Source/platformProject/platform-parent.iml" /> |
| | | <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-server-starter/vci-platform-server-starter.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-server-starter/vci-platform-server-starter.iml" /> |
| | | <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-starter/vci-platform-starter.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-starter/vci-platform-starter.iml" /> |
| | | <module fileurl="file://$PROJECT_DIR$/Source/platformProject/vci-platform-web/vci-platform-web.iml" filepath="$PROJECT_DIR$/Source/platformProject/vci-platform-web/vci-platform-web.iml" /> |
| | | </modules> |
| | | </component> |
| | | </project> |
| | |
| | | //return UIContentDO2VO(context,true); |
| | | return UIContentDO2VO(null,true); |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | package com.vci.web.util; |
| | | |
| | | |
| | | import com.vci.web.util.beans.BeanProperty; |
| | | import com.vci.web.util.beans.BladeBeanCopier; |
| | | import com.vci.web.util.convert.BladeConverter; |
| | | import com.vci.web.util.beans.BladeBeanMap; |
| | | import org.springframework.beans.BeanWrapper; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.beans.PropertyAccessorFactory; |
| | | import org.springframework.cglib.beans.BeanGenerator; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * å®ä½å·¥å
·ç±» |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class BeanUtil extends org.springframework.beans.BeanUtils { |
| | | |
| | | /** |
| | | * å®ä¾å对象 |
| | | * |
| | | * @param clazz ç±» |
| | | * @param <T> æ³åæ è®° |
| | | * @return 对象 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T newInstance(Class<?> clazz) { |
| | | return (T) instantiateClass(clazz); |
| | | } |
| | | |
| | | /** |
| | | * å®ä¾å对象 |
| | | * |
| | | * @param clazzStr ç±»å |
| | | * @param <T> æ³åæ è®° |
| | | * @return 对象 |
| | | */ |
| | | public static <T> T newInstance(String clazzStr) { |
| | | try { |
| | | Class<?> clazz = ClassUtil.forName(clazzStr, null); |
| | | return newInstance(clazz); |
| | | } catch (ClassNotFoundException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åBeanç屿§, æ¯æ propertyName å¤çº§ ï¼test.user.name |
| | | * |
| | | * @param bean bean |
| | | * @param propertyName 屿§å |
| | | * @return 屿§å¼ |
| | | */ |
| | | @Nullable |
| | | public static Object getProperty(@Nullable Object bean, String propertyName) { |
| | | if (bean == null) { |
| | | return null; |
| | | } |
| | | BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean); |
| | | return beanWrapper.getPropertyValue(propertyName); |
| | | } |
| | | |
| | | /** |
| | | * 设置Bean屿§, æ¯æ propertyName å¤çº§ ï¼test.user.name |
| | | * |
| | | * @param bean bean |
| | | * @param propertyName 屿§å |
| | | * @param value 屿§å¼ |
| | | */ |
| | | public static void setProperty(Object bean, String propertyName, Object value) { |
| | | Objects.requireNonNull(bean, "bean Could not null"); |
| | | BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean); |
| | | beanWrapper.setPropertyValue(propertyName, value); |
| | | } |
| | | |
| | | /** |
| | | * æ·±å¤å¶ |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Nullable |
| | | public static <T> T clone(@Nullable T source) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | return (T) BeanUtil.copy(source, source.getClass()); |
| | | } |
| | | |
| | | /** |
| | | * copy å¯¹è±¡å±æ§ï¼é»è®¤ä¸ä½¿ç¨Convert |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param clazz ç±»å |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | @Nullable |
| | | public static <T> T copy(@Nullable Object source, Class<T> clazz) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | return BeanUtil.copy(source, source.getClass(), clazz); |
| | | } |
| | | |
| | | /** |
| | | * copy å¯¹è±¡å±æ§ï¼é»è®¤ä¸ä½¿ç¨Convert |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param sourceClazz æºç±»å |
| | | * @param targetClazz è½¬æ¢æçç±»å |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | @Nullable |
| | | public static <T> T copy(@Nullable Object source, Class sourceClazz, Class<T> targetClazz) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, false); |
| | | T to = newInstance(targetClazz); |
| | | copier.copy(source, to, null); |
| | | return to; |
| | | } |
| | | |
| | | /** |
| | | * copy å表对象ï¼é»è®¤ä¸ä½¿ç¨Convert |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param sourceList æºå表 |
| | | * @param targetClazz è½¬æ¢æçç±»å |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | public static <T> List<T> copy(@Nullable Collection<?> sourceList, Class<T> targetClazz) { |
| | | if (sourceList == null || sourceList.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<T> outList = new ArrayList<>(sourceList.size()); |
| | | Class<?> sourceClazz = null; |
| | | for (Object source : sourceList) { |
| | | if (source == null) { |
| | | continue; |
| | | } |
| | | if (sourceClazz == null) { |
| | | sourceClazz = source.getClass(); |
| | | } |
| | | T bean = BeanUtil.copy(source, sourceClazz, targetClazz); |
| | | outList.add(bean); |
| | | } |
| | | return outList; |
| | | } |
| | | |
| | | /** |
| | | * æ·è´å¯¹è±¡ |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param targetBean éè¦èµå¼ç对象 |
| | | */ |
| | | public static void copy(@Nullable Object source, @Nullable Object targetBean) { |
| | | if (source == null || targetBean == null) { |
| | | return; |
| | | } |
| | | BladeBeanCopier copier = BladeBeanCopier |
| | | .create(source.getClass(), targetBean.getClass(), false); |
| | | |
| | | copier.copy(source, targetBean, null); |
| | | } |
| | | |
| | | /** |
| | | * æ·è´å¯¹è±¡ï¼source 屿§å null 夿ï¼Map 䏿¯æï¼map ä¼å instanceof 夿ï¼ä¸ä¼ |
| | | * |
| | | * <p> |
| | | * æ¯æ bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param targetBean éè¦èµå¼ç对象 |
| | | */ |
| | | public static void copyNonNull(@Nullable Object source, @Nullable Object targetBean) { |
| | | if (source == null || targetBean == null) { |
| | | return; |
| | | } |
| | | BladeBeanCopier copier = BladeBeanCopier |
| | | .create(source.getClass(), targetBean.getClass(), false, true); |
| | | |
| | | copier.copy(source, targetBean, null); |
| | | } |
| | | |
| | | /** |
| | | * æ·è´å¯¹è±¡å¹¶å¯¹ä¸åç±»å屿§è¿è¡è½¬æ¢ |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param targetClazz è½¬æ¢æçç±» |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | @Nullable |
| | | public static <T> T copyWithConvert(@Nullable Object source, Class<T> targetClazz) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | return BeanUtil.copyWithConvert(source, source.getClass(), targetClazz); |
| | | } |
| | | |
| | | /** |
| | | * æ·è´å¯¹è±¡å¹¶å¯¹ä¸åç±»å屿§è¿è¡è½¬æ¢ |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param source æºå¯¹è±¡ |
| | | * @param sourceClazz æºç±» |
| | | * @param targetClazz è½¬æ¢æçç±» |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | */ |
| | | @Nullable |
| | | public static <T> T copyWithConvert(@Nullable Object source, Class<?> sourceClazz, Class<T> targetClazz) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | BladeBeanCopier copier = BladeBeanCopier.create(sourceClazz, targetClazz, true); |
| | | T to = newInstance(targetClazz); |
| | | copier.copy(source, to, new BladeConverter(sourceClazz, targetClazz)); |
| | | return to; |
| | | } |
| | | |
| | | /** |
| | | * æ·è´å表并对ä¸åç±»å屿§è¿è¡è½¬æ¢ |
| | | * |
| | | * <p> |
| | | * æ¯æ map bean copy |
| | | * </p> |
| | | * |
| | | * @param sourceList æºå¯¹è±¡å表 |
| | | * @param targetClazz è½¬æ¢æçç±» |
| | | * @param <T> æ³åæ è®° |
| | | * @return List |
| | | */ |
| | | public static <T> List<T> copyWithConvert(@Nullable Collection<?> sourceList, Class<T> targetClazz) { |
| | | if (sourceList == null || sourceList.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<T> outList = new ArrayList<>(sourceList.size()); |
| | | Class<?> sourceClazz = null; |
| | | for (Object source : sourceList) { |
| | | if (source == null) { |
| | | continue; |
| | | } |
| | | if (sourceClazz == null) { |
| | | sourceClazz = source.getClass(); |
| | | } |
| | | T bean = BeanUtil.copyWithConvert(source, sourceClazz, targetClazz); |
| | | outList.add(bean); |
| | | } |
| | | return outList; |
| | | } |
| | | |
| | | /** |
| | | * Copy the property values of the given source bean into the target class. |
| | | * <p>Note: The source and target classes do not have to match or even be derived |
| | | * from each other, as long as the properties match. Any bean properties that the |
| | | * source bean exposes but the target bean does not will silently be ignored. |
| | | * <p>This is just a convenience method. For more complex transfer needs, |
| | | * |
| | | * @param source the source bean |
| | | * @param targetClazz the target bean class |
| | | * @param <T> æ³åæ è®° |
| | | * @return T |
| | | * @throws BeansException if the copying failed |
| | | */ |
| | | @Nullable |
| | | public static <T> T copyProperties(@Nullable Object source, Class<T> targetClazz) throws BeansException { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | T to = newInstance(targetClazz); |
| | | BeanUtil.copyProperties(source, to); |
| | | return to; |
| | | } |
| | | |
| | | /** |
| | | * Copy the property values of the given source bean into the target class. |
| | | * <p>Note: The source and target classes do not have to match or even be derived |
| | | * from each other, as long as the properties match. Any bean properties that the |
| | | * source bean exposes but the target bean does not will silently be ignored. |
| | | * <p>This is just a convenience method. For more complex transfer needs, |
| | | * |
| | | * @param sourceList the source list bean |
| | | * @param targetClazz the target bean class |
| | | * @param <T> æ³åæ è®° |
| | | * @return List |
| | | * @throws BeansException if the copying failed |
| | | */ |
| | | public static <T> List<T> copyProperties(@Nullable Collection<?> sourceList, Class<T> targetClazz) throws BeansException { |
| | | if (sourceList == null || sourceList.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | List<T> outList = new ArrayList<>(sourceList.size()); |
| | | for (Object source : sourceList) { |
| | | if (source == null) { |
| | | continue; |
| | | } |
| | | T bean = BeanUtil.copyProperties(source, targetClazz); |
| | | outList.add(bean); |
| | | } |
| | | return outList; |
| | | } |
| | | |
| | | /** |
| | | * å°å¯¹è±¡è£
æmapå½¢å¼ |
| | | * |
| | | * @param bean æºå¯¹è±¡ |
| | | * @return {Map} |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static Map<String, Object> toMap(@Nullable Object bean) { |
| | | if (bean == null) { |
| | | return new HashMap<>(0); |
| | | } |
| | | return BladeBeanMap.create(bean); |
| | | } |
| | | |
| | | /** |
| | | * å°map 转为 bean |
| | | * |
| | | * @param beanMap map |
| | | * @param valueType 对象类å |
| | | * @param <T> æ³åæ è®° |
| | | * @return {T} |
| | | */ |
| | | public static <T> T toBean(Map<String, Object> beanMap, Class<T> valueType) { |
| | | Objects.requireNonNull(beanMap, "beanMap Could not null"); |
| | | T to = newInstance(valueType); |
| | | if (beanMap.isEmpty()) { |
| | | return to; |
| | | } |
| | | BeanUtil.copy(beanMap, to); |
| | | return to; |
| | | } |
| | | |
| | | /** |
| | | * ç»ä¸ä¸ªBeanæ·»å åæ®µ |
| | | * |
| | | * @param superBean ç¶çº§Bean |
| | | * @param props æ°å¢å±æ§ |
| | | * @return {Object} |
| | | */ |
| | | @Nullable |
| | | public static Object generator(@Nullable Object superBean, BeanProperty... props) { |
| | | if (superBean == null) { |
| | | return null; |
| | | } |
| | | Class<?> superclass = superBean.getClass(); |
| | | Object genBean = generator(superclass, props); |
| | | BeanUtil.copy(superBean, genBean); |
| | | return genBean; |
| | | } |
| | | |
| | | /** |
| | | * ç»ä¸ä¸ªclassæ·»å åæ®µ |
| | | * |
| | | * @param superclass ç¶çº§ |
| | | * @param props æ°å¢å±æ§ |
| | | * @return {Object} |
| | | */ |
| | | public static Object generator(Class<?> superclass, BeanProperty... props) { |
| | | BeanGenerator generator = new BeanGenerator(); |
| | | generator.setSuperclass(superclass); |
| | | generator.setUseCache(true); |
| | | for (BeanProperty prop : props) { |
| | | generator.addProperty(prop.getName(), prop.getType()); |
| | | } |
| | | return generator.create(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | package com.vci.web.util; |
| | | |
| | | import org.springframework.core.BridgeMethodResolver; |
| | | import org.springframework.core.DefaultParameterNameDiscoverer; |
| | | import org.springframework.core.MethodParameter; |
| | | import org.springframework.core.ParameterNameDiscoverer; |
| | | import org.springframework.core.annotation.AnnotatedElementUtils; |
| | | import org.springframework.core.annotation.SynthesizingMethodParameter; |
| | | import org.springframework.web.method.HandlerMethod; |
| | | |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Constructor; |
| | | import java.lang.reflect.Method; |
| | | |
| | | /** |
| | | * ç±»æä½å·¥å
· |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class ClassUtil extends org.springframework.util.ClassUtils { |
| | | |
| | | private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer(); |
| | | |
| | | /** |
| | | * è·åæ¹æ³åæ°ä¿¡æ¯ |
| | | * |
| | | * @param constructor æé å¨ |
| | | * @param parameterIndex åæ°åºå· |
| | | * @return {MethodParameter} |
| | | */ |
| | | public static MethodParameter getMethodParameter(Constructor<?> constructor, int parameterIndex) { |
| | | MethodParameter methodParameter = new SynthesizingMethodParameter(constructor, parameterIndex); |
| | | methodParameter.initParameterNameDiscovery(PARAMETER_NAME_DISCOVERER); |
| | | return methodParameter; |
| | | } |
| | | |
| | | /** |
| | | * è·åæ¹æ³åæ°ä¿¡æ¯ |
| | | * |
| | | * @param method æ¹æ³ |
| | | * @param parameterIndex åæ°åºå· |
| | | * @return {MethodParameter} |
| | | */ |
| | | public static MethodParameter getMethodParameter(Method method, int parameterIndex) { |
| | | MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex); |
| | | methodParameter.initParameterNameDiscovery(PARAMETER_NAME_DISCOVERER); |
| | | return methodParameter; |
| | | } |
| | | |
| | | /** |
| | | * è·åAnnotation |
| | | * |
| | | * @param method Method |
| | | * @param annotationType 注解类 |
| | | * @param <A> æ³åæ è®° |
| | | * @return {Annotation} |
| | | */ |
| | | public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) { |
| | | Class<?> targetClass = method.getDeclaringClass(); |
| | | // The method may be on an interface, but we need attributes from the target class. |
| | | // If the target class is null, the method will be unchanged. |
| | | Method specificMethod = ClassUtil.getMostSpecificMethod(method, targetClass); |
| | | // If we are dealing with method with generic parameters, find the original method. |
| | | specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); |
| | | // å
æ¾æ¹æ³ï¼åæ¾æ¹æ³ä¸çç±» |
| | | A annotation = AnnotatedElementUtils.findMergedAnnotation(specificMethod, annotationType); |
| | | ; |
| | | if (null != annotation) { |
| | | return annotation; |
| | | } |
| | | // è·åç±»ä¸é¢çAnnotationï¼å¯è½å
å«ç»åæ³¨è§£ï¼æ
éç¨springçå·¥å
·ç±» |
| | | return AnnotatedElementUtils.findMergedAnnotation(specificMethod.getDeclaringClass(), annotationType); |
| | | } |
| | | |
| | | /** |
| | | * è·åAnnotation |
| | | * |
| | | * @param handlerMethod HandlerMethod |
| | | * @param annotationType 注解类 |
| | | * @param <A> æ³åæ è®° |
| | | * @return {Annotation} |
| | | */ |
| | | public static <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) { |
| | | // å
æ¾æ¹æ³ï¼åæ¾æ¹æ³ä¸çç±» |
| | | A annotation = handlerMethod.getMethodAnnotation(annotationType); |
| | | if (null != annotation) { |
| | | return annotation; |
| | | } |
| | | // è·åç±»ä¸é¢çAnnotationï¼å¯è½å
å«ç»åæ³¨è§£ï¼æ
éç¨springçå·¥å
·ç±» |
| | | Class<?> beanType = handlerMethod.getBeanType(); |
| | | return AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 夿æ¯å¦ææ³¨è§£ Annotation |
| | | * |
| | | * @param method Method |
| | | * @param annotationType 注解类 |
| | | * @param <A> æ³åæ è®° |
| | | * @return {boolean} |
| | | */ |
| | | public static <A extends Annotation> boolean isAnnotated(Method method, Class<A> annotationType) { |
| | | // å
æ¾æ¹æ³ï¼åæ¾æ¹æ³ä¸çç±» |
| | | boolean isMethodAnnotated = AnnotatedElementUtils.isAnnotated(method, annotationType); |
| | | if (isMethodAnnotated) { |
| | | return true; |
| | | } |
| | | // è·åç±»ä¸é¢çAnnotationï¼å¯è½å
å«ç»åæ³¨è§£ï¼æ
éç¨springçå·¥å
·ç±» |
| | | Class<?> targetClass = method.getDeclaringClass(); |
| | | return AnnotatedElementUtils.isAnnotated(targetClass, annotationType); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util; |
| | | |
| | | import com.vci.web.util.convert.BladeConversionService; |
| | | import org.springframework.core.convert.TypeDescriptor; |
| | | import org.springframework.core.convert.support.GenericConversionService; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * åºäº spring ConversionService ç±»åè½¬æ¢ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public class ConvertUtil { |
| | | |
| | | /** |
| | | * Convenience operation for converting a source object to the specified targetType. |
| | | * {@link TypeDescriptor#forObject(Object)}. |
| | | * @param source the source object |
| | | * @param targetType the target type |
| | | * @param <T> æ³åæ è®° |
| | | * @return the converted value |
| | | * @throws IllegalArgumentException if targetType is {@code null}, |
| | | * or sourceType is {@code null} but source is not {@code null} |
| | | */ |
| | | @Nullable |
| | | public static <T> T convert(@Nullable Object source, Class<T> targetType) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | if (ClassUtil.isAssignableValue(targetType, source)) { |
| | | return (T) source; |
| | | } |
| | | GenericConversionService conversionService = BladeConversionService.getInstance(); |
| | | return conversionService.convert(source, targetType); |
| | | } |
| | | |
| | | /** |
| | | * Convenience operation for converting a source object to the specified targetType, |
| | | * where the target type is a descriptor that provides additional conversion context. |
| | | * {@link TypeDescriptor#forObject(Object)}. |
| | | * @param source the source object |
| | | * @param sourceType the source type |
| | | * @param targetType the target type |
| | | * @param <T> æ³åæ è®° |
| | | * @return the converted value |
| | | * @throws IllegalArgumentException if targetType is {@code null}, |
| | | * or sourceType is {@code null} but source is not {@code null} |
| | | */ |
| | | @Nullable |
| | | public static <T> T convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | GenericConversionService conversionService = BladeConversionService.getInstance(); |
| | | return (T) conversionService.convert(source, sourceType, targetType); |
| | | } |
| | | |
| | | /** |
| | | * Convenience operation for converting a source object to the specified targetType, |
| | | * where the target type is a descriptor that provides additional conversion context. |
| | | * Simply delegates to {@link #convert(Object, TypeDescriptor, TypeDescriptor)} and |
| | | * encapsulates the construction of the source type descriptor using |
| | | * {@link TypeDescriptor#forObject(Object)}. |
| | | * @param source the source object |
| | | * @param targetType the target type |
| | | * @param <T> æ³åæ è®° |
| | | * @return the converted value |
| | | * @throws IllegalArgumentException if targetType is {@code null}, |
| | | * or sourceType is {@code null} but source is not {@code null} |
| | | */ |
| | | @Nullable |
| | | public static <T> T convert(@Nullable Object source, TypeDescriptor targetType) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | GenericConversionService conversionService = BladeConversionService.getInstance(); |
| | | return (T) conversionService.convert(source, targetType); |
| | | } |
| | | |
| | | } |
| | |
| | | package com.vci.web.util; |
| | | |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.aspose.words.ConvertUtil; |
| | | import com.fasterxml.jackson.core.JsonParser; |
| | | import com.fasterxml.jackson.core.type.TypeReference; |
| | | import com.fasterxml.jackson.databind.JsonNode; |
| | | import com.sun.jndi.toolkit.url.UrlUtil; |
| | | import com.vci.web.util.jackson.JsonUtil; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.beans.BeansException; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | package com.vci.web.util; |
| | | |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.cglib.core.CodeGenerationException; |
| | | import org.springframework.core.convert.Property; |
| | | import org.springframework.core.convert.TypeDescriptor; |
| | | import org.springframework.lang.Nullable; |
| | | import org.springframework.util.ReflectionUtils; |
| | | |
| | | import java.beans.PropertyDescriptor; |
| | | import java.lang.annotation.Annotation; |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.Method; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * åå°å·¥å
·ç±» |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class ReflectUtil extends ReflectionUtils { |
| | | |
| | | /** |
| | | * è·å Bean çææ getæ¹æ³ |
| | | * |
| | | * @param type ç±» |
| | | * @return PropertyDescriptoræ°ç» |
| | | */ |
| | | public static PropertyDescriptor[] getBeanGetters(Class type) { |
| | | return getPropertiesHelper(type, true, false); |
| | | } |
| | | |
| | | /** |
| | | * è·å Bean çææ setæ¹æ³ |
| | | * |
| | | * @param type ç±» |
| | | * @return PropertyDescriptoræ°ç» |
| | | */ |
| | | public static PropertyDescriptor[] getBeanSetters(Class type) { |
| | | return getPropertiesHelper(type, false, true); |
| | | } |
| | | |
| | | /** |
| | | * è·å Bean çææ PropertyDescriptor |
| | | * |
| | | * @param type ç±» |
| | | * @param read è¯»åæ¹æ³ |
| | | * @param write åæ¹æ³ |
| | | * @return PropertyDescriptoræ°ç» |
| | | */ |
| | | public static PropertyDescriptor[] getPropertiesHelper(Class type, boolean read, boolean write) { |
| | | try { |
| | | PropertyDescriptor[] all = BeanUtil.getPropertyDescriptors(type); |
| | | if (read && write) { |
| | | return all; |
| | | } else { |
| | | List<PropertyDescriptor> properties = new ArrayList<>(all.length); |
| | | for (PropertyDescriptor pd : all) { |
| | | if (read && pd.getReadMethod() != null) { |
| | | properties.add(pd); |
| | | } else if (write && pd.getWriteMethod() != null) { |
| | | properties.add(pd); |
| | | } |
| | | } |
| | | return properties.toArray(new PropertyDescriptor[0]); |
| | | } |
| | | } catch (BeansException ex) { |
| | | throw new CodeGenerationException(ex); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·å bean ç屿§ä¿¡æ¯ |
| | | * @param propertyType ç±»å |
| | | * @param propertyName 屿§å |
| | | * @return {Property} |
| | | */ |
| | | @Nullable |
| | | public static Property getProperty(Class<?> propertyType, String propertyName) { |
| | | PropertyDescriptor propertyDescriptor = BeanUtil.getPropertyDescriptor(propertyType, propertyName); |
| | | if (propertyDescriptor == null) { |
| | | return null; |
| | | } |
| | | return ReflectUtil.getProperty(propertyType, propertyDescriptor, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * è·å bean ç屿§ä¿¡æ¯ |
| | | * @param propertyType ç±»å |
| | | * @param propertyDescriptor PropertyDescriptor |
| | | * @param propertyName 屿§å |
| | | * @return {Property} |
| | | */ |
| | | public static Property getProperty(Class<?> propertyType, PropertyDescriptor propertyDescriptor, String propertyName) { |
| | | Method readMethod = propertyDescriptor.getReadMethod(); |
| | | Method writeMethod = propertyDescriptor.getWriteMethod(); |
| | | return new Property(propertyType, readMethod, writeMethod, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * è·å bean ç屿§ä¿¡æ¯ |
| | | * @param propertyType ç±»å |
| | | * @param propertyName 屿§å |
| | | * @return {Property} |
| | | */ |
| | | @Nullable |
| | | public static TypeDescriptor getTypeDescriptor(Class<?> propertyType, String propertyName) { |
| | | Property property = ReflectUtil.getProperty(propertyType, propertyName); |
| | | if (property == null) { |
| | | return null; |
| | | } |
| | | return new TypeDescriptor(property); |
| | | } |
| | | |
| | | /** |
| | | * è·å ç±»å±æ§ä¿¡æ¯ |
| | | * @param propertyType ç±»å |
| | | * @param propertyDescriptor PropertyDescriptor |
| | | * @param propertyName 屿§å |
| | | * @return {Property} |
| | | */ |
| | | public static TypeDescriptor getTypeDescriptor(Class<?> propertyType, PropertyDescriptor propertyDescriptor, String propertyName) { |
| | | Method readMethod = propertyDescriptor.getReadMethod(); |
| | | Method writeMethod = propertyDescriptor.getWriteMethod(); |
| | | Property property = new Property(propertyType, readMethod, writeMethod, propertyName); |
| | | return new TypeDescriptor(property); |
| | | } |
| | | |
| | | /** |
| | | * è·å ç±»å±æ§ |
| | | * @param clazz ç±»ä¿¡æ¯ |
| | | * @param fieldName 屿§å |
| | | * @return Field |
| | | */ |
| | | @Nullable |
| | | public static Field getField(Class<?> clazz, String fieldName) { |
| | | while (clazz != Object.class) { |
| | | try { |
| | | return clazz.getDeclaredField(fieldName); |
| | | } catch (NoSuchFieldException e) { |
| | | clazz = clazz.getSuperclass(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * è·å ææ field 屿§ä¸ç注解 |
| | | * @param clazz ç±» |
| | | * @param fieldName 屿§å |
| | | * @param annotationClass 注解 |
| | | * @param <T> 注解æ³å |
| | | * @return 注解 |
| | | */ |
| | | @Nullable |
| | | public static <T extends Annotation> T getAnnotation(Class<?> clazz, String fieldName, Class<T> annotationClass) { |
| | | Field field = ReflectUtil.getField(clazz, fieldName); |
| | | if (field == null) { |
| | | return null; |
| | | } |
| | | return field.getAnnotation(annotationClass); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util; |
| | | |
| | | import com.vci.web.util.function.*; |
| | | import java.util.Comparator; |
| | | import java.util.Objects; |
| | | import java.util.concurrent.Callable; |
| | | import java.util.function.Consumer; |
| | | import java.util.function.Function; |
| | | import java.util.function.Supplier; |
| | | |
| | | /** |
| | | * Lambda 忣å¼å¸¸å¤ç |
| | | * |
| | | * <p> |
| | | * https://segmentfault.com/a/1190000007832130 |
| | | * https://github.com/jOOQ/jOOL |
| | | * </p> |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class Unchecked { |
| | | |
| | | public static <T, R> Function<T, R> function(CheckedFunction<T, R> mapper) { |
| | | Objects.requireNonNull(mapper); |
| | | return t -> { |
| | | try { |
| | | return mapper.apply(t); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public static <T> Consumer<T> consumer(CheckedConsumer<T> mapper) { |
| | | Objects.requireNonNull(mapper); |
| | | return t -> { |
| | | try { |
| | | mapper.accept(t); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public static <T> Supplier<T> supplier(CheckedSupplier<T> mapper) { |
| | | Objects.requireNonNull(mapper); |
| | | return () -> { |
| | | try { |
| | | return mapper.get(); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public static Runnable runnable(CheckedRunnable runnable) { |
| | | Objects.requireNonNull(runnable); |
| | | return () -> { |
| | | try { |
| | | runnable.run(); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public static <T> Callable<T> callable(CheckedCallable<T> callable) { |
| | | Objects.requireNonNull(callable); |
| | | return () -> { |
| | | try { |
| | | return callable.call(); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | public static <T> Comparator<T> comparator(CheckedComparator<T> comparator) { |
| | | Objects.requireNonNull(comparator); |
| | | return (T o1, T o2) -> { |
| | | try { |
| | | return comparator.compare(o1, o2); |
| | | } catch (Throwable e) { |
| | | throw Exceptions.unchecked(e); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | package com.vci.web.util; |
| | | |
| | | import java.net.URI; |
| | | import java.net.URISyntaxException; |
| | | import java.nio.charset.Charset; |
| | | |
| | | /** |
| | | * urlå¤çå·¥å
·ç±» |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class UrlUtil extends org.springframework.web.util.UriUtils { |
| | | |
| | | /** |
| | | * url ç¼ç |
| | | * |
| | | * @param source source |
| | | * @return sourced String |
| | | */ |
| | | public static String encode(String source) { |
| | | return UrlUtil.encode(source, Charsets.UTF_8); |
| | | } |
| | | |
| | | /** |
| | | * url è§£ç |
| | | * |
| | | * @param source source |
| | | * @return decoded String |
| | | */ |
| | | public static String decode(String source) { |
| | | return UrlUtil.decode(source, Charsets.UTF_8); |
| | | } |
| | | |
| | | /** |
| | | * url ç¼ç |
| | | * |
| | | * @param source url |
| | | * @param charset å符é |
| | | * @return ç¼ç åçurl |
| | | */ |
| | | @Deprecated |
| | | public static String encodeURL(String source, Charset charset) { |
| | | return UrlUtil.encode(source, charset.name()); |
| | | } |
| | | |
| | | /** |
| | | * url è§£ç |
| | | * |
| | | * @param source url |
| | | * @param charset å符é |
| | | * @return è§£ç url |
| | | */ |
| | | @Deprecated |
| | | public static String decodeURL(String source, Charset charset) { |
| | | return UrlUtil.decode(source, charset.name()); |
| | | } |
| | | |
| | | /** |
| | | * è·åurlè·¯å¾ |
| | | * |
| | | * @param uriStr è·¯å¾ |
| | | * @return urlè·¯å¾ |
| | | */ |
| | | public static String getPath(String uriStr) { |
| | | URI uri; |
| | | |
| | | try { |
| | | uri = new URI(uriStr); |
| | | } catch (URISyntaxException var3) { |
| | | throw new RuntimeException(var3); |
| | | } |
| | | |
| | | return uri.getPath(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * Bean屿§ |
| | | * |
| | | * @author Chill |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public class BeanProperty { |
| | | private final String name; |
| | | private final Class<?> type; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import com.vci.web.util.BeanUtil; |
| | | import com.vci.web.util.ClassUtil; |
| | | import com.vci.web.util.ReflectUtil; |
| | | import com.vci.web.util.StringUtil; |
| | | import org.springframework.asm.ClassVisitor; |
| | | import org.springframework.asm.Label; |
| | | import org.springframework.asm.Opcodes; |
| | | import org.springframework.asm.Type; |
| | | import org.springframework.cglib.core.*; |
| | | import org.springframework.lang.Nullable; |
| | | import org.springframework.util.ClassUtils; |
| | | |
| | | import java.beans.PropertyDescriptor; |
| | | import java.lang.reflect.Method; |
| | | import java.lang.reflect.Modifier; |
| | | import java.security.ProtectionDomain; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * spring cglib éæ¹ |
| | | * |
| | | * <p> |
| | | * 1. æ¯æé¾å¼ beanï¼æ¯æ map |
| | | * 2. ClassLoader è· target ä¿æä¸è´ |
| | | * </p> |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public abstract class BladeBeanCopier { |
| | | private static final Type CONVERTER = TypeUtils.parseType("org.springframework.cglib.core.Converter"); |
| | | private static final Type BEAN_COPIER = TypeUtils.parseType(BladeBeanCopier.class.getName()); |
| | | private static final Type BEAN_MAP = TypeUtils.parseType(Map.class.getName()); |
| | | private static final Signature COPY = new Signature("copy", Type.VOID_TYPE, new Type[]{Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER}); |
| | | private static final Signature CONVERT = TypeUtils.parseSignature("Object convert(Object, Class, Object)"); |
| | | private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object)"); |
| | | private static final Type CLASS_UTILS = TypeUtils.parseType(ClassUtils.class.getName()); |
| | | private static final Signature IS_ASSIGNABLE_VALUE = TypeUtils.parseSignature("boolean isAssignableValue(Class, Object)"); |
| | | /** |
| | | * The map to store {@link BladeBeanCopier} of source type and class type for copy. |
| | | */ |
| | | private static final ConcurrentMap<BladeBeanCopierKey, BladeBeanCopier> BEAN_COPIER_MAP = new ConcurrentHashMap<>(); |
| | | |
| | | public static BladeBeanCopier create(Class source, Class target, boolean useConverter) { |
| | | return BladeBeanCopier.create(source, target, useConverter, false); |
| | | } |
| | | |
| | | public static BladeBeanCopier create(Class source, Class target, boolean useConverter, boolean nonNull) { |
| | | BladeBeanCopierKey copierKey = new BladeBeanCopierKey(source, target, useConverter, nonNull); |
| | | // å©ç¨ ConcurrentMap ç¼å æé«æ§è½ï¼æ¥è¿ ç´æ¥ get set |
| | | return BEAN_COPIER_MAP.computeIfAbsent(copierKey, key -> { |
| | | Generator gen = new Generator(); |
| | | gen.setSource(key.getSource()); |
| | | gen.setTarget(key.getTarget()); |
| | | gen.setUseConverter(key.isUseConverter()); |
| | | gen.setNonNull(key.isNonNull()); |
| | | return gen.create(key); |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * Bean copy |
| | | * |
| | | * @param from from Bean |
| | | * @param to to Bean |
| | | * @param converter Converter |
| | | */ |
| | | abstract public void copy(Object from, Object to, @Nullable Converter converter); |
| | | |
| | | public static class Generator extends AbstractClassGenerator { |
| | | private static final Source SOURCE = new Source(BladeBeanCopier.class.getName()); |
| | | private Class source; |
| | | private Class target; |
| | | private boolean useConverter; |
| | | private boolean nonNull; |
| | | |
| | | Generator() { |
| | | super(SOURCE); |
| | | } |
| | | |
| | | public void setSource(Class source) { |
| | | if (!Modifier.isPublic(source.getModifiers())) { |
| | | setNamePrefix(source.getName()); |
| | | } |
| | | this.source = source; |
| | | } |
| | | |
| | | public void setTarget(Class target) { |
| | | if (!Modifier.isPublic(target.getModifiers())) { |
| | | setNamePrefix(target.getName()); |
| | | } |
| | | this.target = target; |
| | | } |
| | | |
| | | public void setUseConverter(boolean useConverter) { |
| | | this.useConverter = useConverter; |
| | | } |
| | | |
| | | public void setNonNull(boolean nonNull) { |
| | | this.nonNull = nonNull; |
| | | } |
| | | |
| | | @Override |
| | | protected ClassLoader getDefaultClassLoader() { |
| | | // L.cm ä¿è¯ å è¿å使ç¨åä¸ä¸ª ClassLoader |
| | | return target.getClassLoader(); |
| | | } |
| | | |
| | | @Override |
| | | protected ProtectionDomain getProtectionDomain() { |
| | | return ReflectUtils.getProtectionDomain(source); |
| | | } |
| | | |
| | | @Override |
| | | public BladeBeanCopier create(Object key) { |
| | | return (BladeBeanCopier) super.create(key); |
| | | } |
| | | |
| | | @Override |
| | | public void generateClass(ClassVisitor v) { |
| | | Type sourceType = Type.getType(source); |
| | | Type targetType = Type.getType(target); |
| | | ClassEmitter ce = new ClassEmitter(v); |
| | | ce.begin_class(Constants.V1_2, |
| | | Constants.ACC_PUBLIC, |
| | | getClassName(), |
| | | BEAN_COPIER, |
| | | null, |
| | | Constants.SOURCE_FILE); |
| | | |
| | | EmitUtils.null_constructor(ce); |
| | | CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null); |
| | | |
| | | // map åç¬å¤ç |
| | | if (Map.class.isAssignableFrom(source)) { |
| | | generateClassFormMap(ce, e, sourceType, targetType); |
| | | return; |
| | | } |
| | | |
| | | // 2018.12.27 by L.cm æ¯æé¾å¼ bean |
| | | // 注æï¼æ¤å¤éå
¼å®¹é¾å¼bean 使ç¨äº spring çæ¹æ³ï¼æ¯è¾èæ¶ |
| | | PropertyDescriptor[] getters = ReflectUtil.getBeanGetters(source); |
| | | PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(target); |
| | | Map<String, PropertyDescriptor> names = new HashMap<>(16); |
| | | for (PropertyDescriptor getter : getters) { |
| | | names.put(getter.getName(), getter); |
| | | } |
| | | |
| | | Local targetLocal = e.make_local(); |
| | | Local sourceLocal = e.make_local(); |
| | | e.load_arg(1); |
| | | e.checkcast(targetType); |
| | | e.store_local(targetLocal); |
| | | e.load_arg(0); |
| | | e.checkcast(sourceType); |
| | | e.store_local(sourceLocal); |
| | | |
| | | for (PropertyDescriptor setter : setters) { |
| | | String propName = setter.getName(); |
| | | |
| | | CopyProperty targetIgnoreCopy = ReflectUtil.getAnnotation(target, propName, CopyProperty.class); |
| | | // set ä¸æå¿½ç¥ç 注解 |
| | | if (targetIgnoreCopy != null) { |
| | | if (targetIgnoreCopy.ignore()) { |
| | | continue; |
| | | } |
| | | // 注解ä¸çå«åï¼å¦æå«åä¸ä¸ºç©ºï¼ä½¿ç¨å«å |
| | | String aliasTargetPropName = targetIgnoreCopy.value(); |
| | | if (StringUtil.isNotBlank(aliasTargetPropName)) { |
| | | propName = aliasTargetPropName; |
| | | } |
| | | } |
| | | // æ¾å°å¯¹åºç get |
| | | PropertyDescriptor getter = names.get(propName); |
| | | // 没æ get è·³åº |
| | | if (getter == null) { |
| | | continue; |
| | | } |
| | | |
| | | MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod()); |
| | | Method writeMethod = setter.getWriteMethod(); |
| | | MethodInfo write = ReflectUtils.getMethodInfo(writeMethod); |
| | | Type returnType = read.getSignature().getReturnType(); |
| | | Type setterType = write.getSignature().getArgumentTypes()[0]; |
| | | Class<?> getterPropertyType = getter.getPropertyType(); |
| | | Class<?> setterPropertyType = setter.getPropertyType(); |
| | | |
| | | // L.cm 2019.01.12 ä¼åé»è¾ï¼å
å¤æç±»åï¼ç±»åä¸è´ç´æ¥ setï¼ä¸åå夿 æ¯å¦ ç±»åè½¬æ¢ |
| | | // nonNull Label |
| | | Label l0 = e.make_label(); |
| | | // å¤æç±»åæ¯å¦ä¸è´ï¼å
æ¬ å
è£
ç±»å |
| | | if (ClassUtil.isAssignable(setterPropertyType, getterPropertyType)) { |
| | | // 2018.12.27 by L.cm æ¯æé¾å¼ bean |
| | | e.load_local(targetLocal); |
| | | e.load_local(sourceLocal); |
| | | e.invoke(read); |
| | | boolean getterIsPrimitive = getterPropertyType.isPrimitive(); |
| | | boolean setterIsPrimitive = setterPropertyType.isPrimitive(); |
| | | |
| | | if (nonNull) { |
| | | // éè¦è½æ ï¼å¼ºå¶è£
ç®± |
| | | e.box(returnType); |
| | | Local var = e.make_local(); |
| | | e.store_local(var); |
| | | e.load_local(var); |
| | | // nonNull Label |
| | | e.ifnull(l0); |
| | | e.load_local(targetLocal); |
| | | e.load_local(var); |
| | | // éè¦è½æ ï¼å¼ºå¶æç®± |
| | | e.unbox_or_zero(setterType); |
| | | } else { |
| | | // 妿 get 为åå§ç±»åï¼éè¦è£
ç®± |
| | | if (getterIsPrimitive && !setterIsPrimitive) { |
| | | e.box(returnType); |
| | | } |
| | | // 妿 set 为åå§ç±»åï¼éè¦æç®± |
| | | if (!getterIsPrimitive && setterIsPrimitive) { |
| | | e.unbox_or_zero(setterType); |
| | | } |
| | | } |
| | | |
| | | // æé set æ¹æ³ |
| | | invokeWrite(e, write, writeMethod, nonNull, l0); |
| | | } else if (useConverter) { |
| | | e.load_local(targetLocal); |
| | | e.load_arg(2); |
| | | e.load_local(sourceLocal); |
| | | e.invoke(read); |
| | | e.box(returnType); |
| | | |
| | | if (nonNull) { |
| | | Local var = e.make_local(); |
| | | e.store_local(var); |
| | | e.load_local(var); |
| | | e.ifnull(l0); |
| | | e.load_local(targetLocal); |
| | | e.load_arg(2); |
| | | e.load_local(var); |
| | | } |
| | | |
| | | EmitUtils.load_class(e, setterType); |
| | | // æ´æ¹æäºå±æ§åï¼ä¹åæ¯ set æ¹æ³å |
| | | e.push(propName); |
| | | e.invoke_interface(CONVERTER, CONVERT); |
| | | e.unbox_or_zero(setterType); |
| | | |
| | | // æé set æ¹æ³ |
| | | invokeWrite(e, write, writeMethod, nonNull, l0); |
| | | } |
| | | } |
| | | e.return_value(); |
| | | e.end_method(); |
| | | ce.end_class(); |
| | | } |
| | | |
| | | private static void invokeWrite(CodeEmitter e, MethodInfo write, Method writeMethod, boolean nonNull, Label l0) { |
| | | // è¿åå¼ï¼å¤æ é¾å¼ bean |
| | | Class<?> returnType = writeMethod.getReturnType(); |
| | | e.invoke(write); |
| | | // é¾å¼ beanï¼æè¿åå¼éè¦ pop |
| | | if (!returnType.equals(Void.TYPE)) { |
| | | e.pop(); |
| | | } |
| | | if (nonNull) { |
| | | e.visitLabel(l0); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | protected Object firstInstance(Class type) { |
| | | return BeanUtil.newInstance(type); |
| | | } |
| | | |
| | | @Override |
| | | protected Object nextInstance(Object instance) { |
| | | return instance; |
| | | } |
| | | |
| | | /** |
| | | * å¤ç map ç copy |
| | | * @param ce ClassEmitter |
| | | * @param e CodeEmitter |
| | | * @param sourceType sourceType |
| | | * @param targetType targetType |
| | | */ |
| | | public void generateClassFormMap(ClassEmitter ce, CodeEmitter e, Type sourceType, Type targetType) { |
| | | // 2018.12.27 by L.cm æ¯æé¾å¼ bean |
| | | PropertyDescriptor[] setters = ReflectUtil.getBeanSetters(target); |
| | | |
| | | // å
¥å£åé |
| | | Local targetLocal = e.make_local(); |
| | | Local sourceLocal = e.make_local(); |
| | | e.load_arg(1); |
| | | e.checkcast(targetType); |
| | | e.store_local(targetLocal); |
| | | e.load_arg(0); |
| | | e.checkcast(sourceType); |
| | | e.store_local(sourceLocal); |
| | | Type mapBox = Type.getType(Object.class); |
| | | |
| | | for (PropertyDescriptor setter : setters) { |
| | | String propName = setter.getName(); |
| | | |
| | | // set ä¸æå¿½ç¥ç 注解 |
| | | CopyProperty targetIgnoreCopy = ReflectUtil.getAnnotation(target, propName, CopyProperty.class); |
| | | if (targetIgnoreCopy != null) { |
| | | if (targetIgnoreCopy.ignore()) { |
| | | continue; |
| | | } |
| | | // 注解ä¸çå«å |
| | | String aliasTargetPropName = targetIgnoreCopy.value(); |
| | | if (StringUtil.isNotBlank(aliasTargetPropName)) { |
| | | propName = aliasTargetPropName; |
| | | } |
| | | } |
| | | |
| | | Method writeMethod = setter.getWriteMethod(); |
| | | MethodInfo write = ReflectUtils.getMethodInfo(writeMethod); |
| | | Type setterType = write.getSignature().getArgumentTypes()[0]; |
| | | |
| | | e.load_local(targetLocal); |
| | | e.load_local(sourceLocal); |
| | | |
| | | e.push(propName); |
| | | // æ§è¡ map get |
| | | e.invoke_interface(BEAN_MAP, BEAN_MAP_GET); |
| | | // box è£
ç®±ï¼é¿å
array[] æ°ç»é®é¢ |
| | | e.box(mapBox); |
| | | |
| | | // çæåé |
| | | Local var = e.make_local(); |
| | | e.store_local(var); |
| | | e.load_local(var); |
| | | |
| | | // å
夿 ä¸ä¸ºnullï¼ç¶ååç±»å夿 |
| | | Label l0 = e.make_label(); |
| | | e.ifnull(l0); |
| | | EmitUtils.load_class(e, setterType); |
| | | e.load_local(var); |
| | | // ClassUtils.isAssignableValue(Integer.class, id) |
| | | e.invoke_static(CLASS_UTILS, IS_ASSIGNABLE_VALUE); |
| | | Label l1 = new Label(); |
| | | // è¿åå¼ï¼å¤æ é¾å¼ bean |
| | | Class<?> returnType = writeMethod.getReturnType(); |
| | | if (useConverter) { |
| | | e.if_jump(Opcodes.IFEQ, l1); |
| | | e.load_local(targetLocal); |
| | | e.load_local(var); |
| | | e.unbox_or_zero(setterType); |
| | | e.invoke(write); |
| | | if (!returnType.equals(Void.TYPE)) { |
| | | e.pop(); |
| | | } |
| | | e.goTo(l0); |
| | | e.visitLabel(l1); |
| | | e.load_local(targetLocal); |
| | | e.load_arg(2); |
| | | e.load_local(var); |
| | | EmitUtils.load_class(e, setterType); |
| | | e.push(propName); |
| | | e.invoke_interface(CONVERTER, CONVERT); |
| | | e.unbox_or_zero(setterType); |
| | | e.invoke(write); |
| | | } else { |
| | | e.if_jump(Opcodes.IFEQ, l0); |
| | | e.load_local(targetLocal); |
| | | e.load_local(var); |
| | | e.unbox_or_zero(setterType); |
| | | e.invoke(write); |
| | | } |
| | | // è¿åå¼ï¼å¤æ é¾å¼ bean |
| | | if (!returnType.equals(Void.TYPE)) { |
| | | e.pop(); |
| | | } |
| | | e.visitLabel(l0); |
| | | } |
| | | e.return_value(); |
| | | e.end_method(); |
| | | ce.end_class(); |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * copy key |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @Getter |
| | | @EqualsAndHashCode |
| | | @AllArgsConstructor |
| | | public class BladeBeanCopierKey { |
| | | private final Class<?> source; |
| | | private final Class<?> target; |
| | | private final boolean useConverter; |
| | | private final boolean nonNull; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import org.springframework.asm.ClassVisitor; |
| | | import org.springframework.cglib.beans.BeanMap; |
| | | import org.springframework.cglib.core.AbstractClassGenerator; |
| | | import org.springframework.cglib.core.ReflectUtils; |
| | | |
| | | import java.security.ProtectionDomain; |
| | | |
| | | /** |
| | | * éå cglib BeanMapï¼æ¯æé¾å¼bean |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public abstract class BladeBeanMap extends BeanMap { |
| | | protected BladeBeanMap() { |
| | | } |
| | | |
| | | protected BladeBeanMap(Object bean) { |
| | | super(bean); |
| | | } |
| | | |
| | | public static BladeBeanMap create(Object bean) { |
| | | BladeGenerator gen = new BladeGenerator(); |
| | | gen.setBean(bean); |
| | | return gen.create(); |
| | | } |
| | | |
| | | /** |
| | | * newInstance |
| | | * |
| | | * @param o Object |
| | | * @return BladeBeanMap |
| | | */ |
| | | @Override |
| | | public abstract BladeBeanMap newInstance(Object o); |
| | | |
| | | public static class BladeGenerator extends AbstractClassGenerator { |
| | | private static final Source SOURCE = new Source(BladeBeanMap.class.getName()); |
| | | |
| | | private Object bean; |
| | | private Class beanClass; |
| | | private int require; |
| | | |
| | | public BladeGenerator() { |
| | | super(SOURCE); |
| | | } |
| | | |
| | | /** |
| | | * Set the bean that the generated map should reflect. The bean may be swapped |
| | | * out for another bean of the same type using {@link #setBean}. |
| | | * Calling this method overrides any value previously set using {@link #setBeanClass}. |
| | | * You must call either this method or {@link #setBeanClass} before {@link #create}. |
| | | * |
| | | * @param bean the initial bean |
| | | */ |
| | | public void setBean(Object bean) { |
| | | this.bean = bean; |
| | | if (bean != null) { |
| | | beanClass = bean.getClass(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Set the class of the bean that the generated map should support. |
| | | * You must call either this method or {@link #setBeanClass} before {@link #create}. |
| | | * |
| | | * @param beanClass the class of the bean |
| | | */ |
| | | public void setBeanClass(Class beanClass) { |
| | | this.beanClass = beanClass; |
| | | } |
| | | |
| | | /** |
| | | * Limit the properties reflected by the generated map. |
| | | * |
| | | * @param require any combination of {@link #REQUIRE_GETTER} and |
| | | * {@link #REQUIRE_SETTER}; default is zero (any property allowed) |
| | | */ |
| | | public void setRequire(int require) { |
| | | this.require = require; |
| | | } |
| | | |
| | | @Override |
| | | protected ClassLoader getDefaultClassLoader() { |
| | | return beanClass.getClassLoader(); |
| | | } |
| | | |
| | | @Override |
| | | protected ProtectionDomain getProtectionDomain() { |
| | | return ReflectUtils.getProtectionDomain(beanClass); |
| | | } |
| | | |
| | | /** |
| | | * Create a new instance of the <code>BeanMap</code>. An existing |
| | | * generated class will be reused if possible. |
| | | * |
| | | * @return {BladeBeanMap} |
| | | */ |
| | | public BladeBeanMap create() { |
| | | if (beanClass == null) { |
| | | throw new IllegalArgumentException("Class of bean unknown"); |
| | | } |
| | | setNamePrefix(beanClass.getName()); |
| | | BladeBeanMapKey key = new BladeBeanMapKey(beanClass, require); |
| | | return (BladeBeanMap) super.create(key); |
| | | } |
| | | |
| | | @Override |
| | | public void generateClass(ClassVisitor v) throws Exception { |
| | | new BladeBeanMapEmitter(v, getClassName(), beanClass, require); |
| | | } |
| | | |
| | | @Override |
| | | protected Object firstInstance(Class type) { |
| | | return ((BeanMap) ReflectUtils.newInstance(type)).newInstance(bean); |
| | | } |
| | | |
| | | @Override |
| | | protected Object nextInstance(Object instance) { |
| | | return ((BeanMap) instance).newInstance(bean); |
| | | } |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import com.vci.web.util.ReflectUtil; |
| | | import org.springframework.asm.ClassVisitor; |
| | | import org.springframework.asm.Label; |
| | | import org.springframework.asm.Type; |
| | | import org.springframework.cglib.core.*; |
| | | |
| | | import java.beans.PropertyDescriptor; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * éå cglib BeanMap å¤çå¨ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | class BladeBeanMapEmitter extends ClassEmitter { |
| | | private static final Type BEAN_MAP = TypeUtils.parseType(BladeBeanMap.class.getName()); |
| | | private static final Type FIXED_KEY_SET = TypeUtils.parseType("org.springframework.cglib.beans.FixedKeySet"); |
| | | private static final Signature CSTRUCT_OBJECT = TypeUtils.parseConstructor("Object"); |
| | | private static final Signature CSTRUCT_STRING_ARRAY = TypeUtils.parseConstructor("String[]"); |
| | | private static final Signature BEAN_MAP_GET = TypeUtils.parseSignature("Object get(Object, Object)"); |
| | | private static final Signature BEAN_MAP_PUT = TypeUtils.parseSignature("Object put(Object, Object, Object)"); |
| | | private static final Signature KEY_SET = TypeUtils.parseSignature("java.util.Set keySet()"); |
| | | private static final Signature NEW_INSTANCE = new Signature("newInstance", BEAN_MAP, new Type[]{Constants.TYPE_OBJECT}); |
| | | private static final Signature GET_PROPERTY_TYPE = TypeUtils.parseSignature("Class getPropertyType(String)"); |
| | | |
| | | public BladeBeanMapEmitter(ClassVisitor v, String className, Class type, int require) { |
| | | super(v); |
| | | |
| | | begin_class(Constants.V1_2, Constants.ACC_PUBLIC, className, BEAN_MAP, null, Constants.SOURCE_FILE); |
| | | EmitUtils.null_constructor(this); |
| | | EmitUtils.factory_method(this, NEW_INSTANCE); |
| | | generateConstructor(); |
| | | |
| | | Map<String, PropertyDescriptor> getters = makePropertyMap(ReflectUtil.getBeanGetters(type)); |
| | | Map<String, PropertyDescriptor> setters = makePropertyMap(ReflectUtil.getBeanSetters(type)); |
| | | Map<String, PropertyDescriptor> allProps = new HashMap<>(32); |
| | | allProps.putAll(getters); |
| | | allProps.putAll(setters); |
| | | |
| | | if (require != 0) { |
| | | for (Iterator it = allProps.keySet().iterator(); it.hasNext(); ) { |
| | | String name = (String) it.next(); |
| | | if ((((require & BladeBeanMap.REQUIRE_GETTER) != 0) && !getters.containsKey(name)) || |
| | | (((require & BladeBeanMap.REQUIRE_SETTER) != 0) && !setters.containsKey(name))) { |
| | | it.remove(); |
| | | getters.remove(name); |
| | | setters.remove(name); |
| | | } |
| | | } |
| | | } |
| | | generateGet(type, getters); |
| | | generatePut(type, setters); |
| | | |
| | | String[] allNames = getNames(allProps); |
| | | generateKeySet(allNames); |
| | | generateGetPropertyType(allProps, allNames); |
| | | end_class(); |
| | | } |
| | | |
| | | private Map<String, PropertyDescriptor> makePropertyMap(PropertyDescriptor[] props) { |
| | | Map<String, PropertyDescriptor> names = new HashMap<>(16); |
| | | for (PropertyDescriptor prop : props) { |
| | | String propName = prop.getName(); |
| | | // è¿æ»¤ getClassï¼Spring çå·¥å
·ç±»ä¼æ¿å°è¯¥æ¹æ³ |
| | | if (!"class".equals(propName)) { |
| | | names.put(propName, prop); |
| | | } |
| | | } |
| | | return names; |
| | | } |
| | | |
| | | private String[] getNames(Map<String, PropertyDescriptor> propertyMap) { |
| | | return propertyMap.keySet().toArray(new String[0]); |
| | | } |
| | | |
| | | private void generateConstructor() { |
| | | CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null); |
| | | e.load_this(); |
| | | e.load_arg(0); |
| | | e.super_invoke_constructor(CSTRUCT_OBJECT); |
| | | e.return_value(); |
| | | e.end_method(); |
| | | } |
| | | |
| | | private void generateGet(Class type, final Map<String, PropertyDescriptor> getters) { |
| | | final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null); |
| | | e.load_arg(0); |
| | | e.checkcast(Type.getType(type)); |
| | | e.load_arg(1); |
| | | e.checkcast(Constants.TYPE_STRING); |
| | | EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { |
| | | @Override |
| | | public void processCase(Object key, Label end) { |
| | | PropertyDescriptor pd = getters.get(key); |
| | | MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod()); |
| | | e.invoke(method); |
| | | e.box(method.getSignature().getReturnType()); |
| | | e.return_value(); |
| | | } |
| | | |
| | | @Override |
| | | public void processDefault() { |
| | | e.aconst_null(); |
| | | e.return_value(); |
| | | } |
| | | }); |
| | | e.end_method(); |
| | | } |
| | | |
| | | private void generatePut(Class type, final Map<String, PropertyDescriptor> setters) { |
| | | final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null); |
| | | e.load_arg(0); |
| | | e.checkcast(Type.getType(type)); |
| | | e.load_arg(1); |
| | | e.checkcast(Constants.TYPE_STRING); |
| | | EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { |
| | | @Override |
| | | public void processCase(Object key, Label end) { |
| | | PropertyDescriptor pd = setters.get(key); |
| | | if (pd.getReadMethod() == null) { |
| | | e.aconst_null(); |
| | | } else { |
| | | MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod()); |
| | | e.dup(); |
| | | e.invoke(read); |
| | | e.box(read.getSignature().getReturnType()); |
| | | } |
| | | // move old value behind bean |
| | | e.swap(); |
| | | // new value |
| | | e.load_arg(2); |
| | | MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod()); |
| | | e.unbox(write.getSignature().getArgumentTypes()[0]); |
| | | e.invoke(write); |
| | | e.return_value(); |
| | | } |
| | | |
| | | @Override |
| | | public void processDefault() { |
| | | // fall-through |
| | | } |
| | | }); |
| | | e.aconst_null(); |
| | | e.return_value(); |
| | | e.end_method(); |
| | | } |
| | | |
| | | private void generateKeySet(String[] allNames) { |
| | | // static initializer |
| | | declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null); |
| | | |
| | | CodeEmitter e = begin_static(); |
| | | e.new_instance(FIXED_KEY_SET); |
| | | e.dup(); |
| | | EmitUtils.push_array(e, allNames); |
| | | e.invoke_constructor(FIXED_KEY_SET, CSTRUCT_STRING_ARRAY); |
| | | e.putfield("keys"); |
| | | e.return_value(); |
| | | e.end_method(); |
| | | |
| | | // keySet |
| | | e = begin_method(Constants.ACC_PUBLIC, KEY_SET, null); |
| | | e.load_this(); |
| | | e.getfield("keys"); |
| | | e.return_value(); |
| | | e.end_method(); |
| | | } |
| | | |
| | | private void generateGetPropertyType(final Map allProps, String[] allNames) { |
| | | final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null); |
| | | e.load_arg(0); |
| | | EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { |
| | | @Override |
| | | public void processCase(Object key, Label end) { |
| | | PropertyDescriptor pd = (PropertyDescriptor) allProps.get(key); |
| | | EmitUtils.load_class(e, Type.getType(pd.getPropertyType())); |
| | | e.return_value(); |
| | | } |
| | | |
| | | @Override |
| | | public void processDefault() { |
| | | e.aconst_null(); |
| | | e.return_value(); |
| | | } |
| | | }); |
| | | e.end_method(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * bean map keyï¼æé«æ§è½ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @EqualsAndHashCode |
| | | @AllArgsConstructor |
| | | public class BladeBeanMapKey { |
| | | private final Class type; |
| | | private final int require; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.beans; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * copy åæ®µ é
ç½® |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @Target(ElementType.FIELD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface CopyProperty { |
| | | |
| | | /** |
| | | * 屿§åï¼ç¨äºæå®å«åï¼é»è®¤ä½¿ç¨ï¼field name |
| | | * @return 屿§å |
| | | */ |
| | | String value() default ""; |
| | | |
| | | /** |
| | | * 忽ç¥ï¼é»è®¤ä¸º false |
| | | * @return æ¯å¦å¿½ç¥ |
| | | */ |
| | | boolean ignore() default false; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.convert; |
| | | |
| | | import com.vci.web.util.convert.EnumToStringConverter; |
| | | import org.springframework.boot.convert.ApplicationConversionService; |
| | | import org.springframework.core.convert.support.GenericConversionService; |
| | | import org.springframework.lang.Nullable; |
| | | import org.springframework.util.StringValueResolver; |
| | | |
| | | /** |
| | | * ç±»å è½¬æ¢ æå¡ï¼æ·»å äº IEnum è½¬æ¢ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | public class BladeConversionService extends ApplicationConversionService { |
| | | @Nullable |
| | | private static volatile BladeConversionService SHARED_INSTANCE; |
| | | |
| | | public BladeConversionService() { |
| | | this(null); |
| | | } |
| | | |
| | | public BladeConversionService(@Nullable StringValueResolver embeddedValueResolver) { |
| | | super(embeddedValueResolver); |
| | | super.addConverter(new EnumToStringConverter()); |
| | | super.addConverter(new StringToEnumConverter()); |
| | | } |
| | | |
| | | /** |
| | | * Return a shared default application {@code ConversionService} instance, lazily |
| | | * building it once needed. |
| | | * <p> |
| | | * Note: This method actually returns an {@link BladeConversionService} |
| | | * instance. However, the {@code ConversionService} signature has been preserved for |
| | | * binary compatibility. |
| | | * @return the shared {@code BladeConversionService} instance (never{@code null}) |
| | | */ |
| | | public static GenericConversionService getInstance() { |
| | | BladeConversionService sharedInstance = BladeConversionService.SHARED_INSTANCE; |
| | | if (sharedInstance == null) { |
| | | synchronized (BladeConversionService.class) { |
| | | sharedInstance = BladeConversionService.SHARED_INSTANCE; |
| | | if (sharedInstance == null) { |
| | | sharedInstance = new BladeConversionService(); |
| | | BladeConversionService.SHARED_INSTANCE = sharedInstance; |
| | | } |
| | | } |
| | | } |
| | | return sharedInstance; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.vci.web.util.convert; |
| | | |
| | | import com.vci.web.util.ClassUtil; |
| | | import com.vci.web.util.ConvertUtil; |
| | | import com.vci.web.util.ReflectUtil; |
| | | import com.vci.web.util.Unchecked; |
| | | import com.vci.web.util.function.CheckedFunction; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.cglib.core.Converter; |
| | | import org.springframework.core.convert.TypeDescriptor; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * ç»å spring cglib Converter å spring ConversionService |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @Slf4j |
| | | @AllArgsConstructor |
| | | public class BladeConverter implements Converter { |
| | | private static final ConcurrentMap<String, TypeDescriptor> TYPE_CACHE = new ConcurrentHashMap<>(); |
| | | private final Class<?> sourceClazz; |
| | | private final Class<?> targetClazz; |
| | | |
| | | /** |
| | | * cglib convert |
| | | * |
| | | * @param value æºå¯¹è±¡å±æ§ |
| | | * @param target ç®æ å¯¹è±¡å±æ§ç±» |
| | | * @param fieldName ç®æ çfieldåï¼å为 set æ¹æ³åï¼BladeBeanCopier éåäºæ´æ¹ |
| | | * @return {Object} |
| | | */ |
| | | @Override |
| | | @Nullable |
| | | public Object convert(Object value, Class target, final Object fieldName) { |
| | | if (value == null) { |
| | | return null; |
| | | } |
| | | // ç±»å䏿 ·ï¼ä¸éè¦è½¬æ¢ |
| | | if (ClassUtil.isAssignableValue(target, value)) { |
| | | return value; |
| | | } |
| | | try { |
| | | TypeDescriptor targetDescriptor = BladeConverter.getTypeDescriptor(targetClazz, (String) fieldName); |
| | | // 1. 夿 sourceClazz 为 Map |
| | | if (Map.class.isAssignableFrom(sourceClazz)) { |
| | | return ConvertUtil.convert(value, targetDescriptor); |
| | | } else { |
| | | TypeDescriptor sourceDescriptor = BladeConverter.getTypeDescriptor(sourceClazz, (String) fieldName); |
| | | return ConvertUtil.convert(value, sourceDescriptor, targetDescriptor); |
| | | } |
| | | } catch (Throwable e) { |
| | | log.warn("BladeConverter error", e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private static TypeDescriptor getTypeDescriptor(final Class<?> clazz, final String fieldName) { |
| | | String srcCacheKey = clazz.getName() + fieldName; |
| | | // å¿½ç¥æåºå¼å¸¸ç彿°ï¼å®ä¹å®æ´æ³åï¼é¿å
ç¼è¯é®é¢ |
| | | CheckedFunction<String, TypeDescriptor> uncheckedFunction = (key) -> { |
| | | // è¿é property ç论ä¸ä¸ä¼ä¸º null |
| | | Field field = ReflectUtil.getField(clazz, fieldName); |
| | | if (field == null) { |
| | | throw new NoSuchFieldException(fieldName); |
| | | } |
| | | return new TypeDescriptor(field); |
| | | }; |
| | | return TYPE_CACHE.computeIfAbsent(srcCacheKey, Unchecked.function(uncheckedFunction)); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.convert; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonValue; |
| | | import com.vci.web.util.ConvertUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.core.convert.TypeDescriptor; |
| | | import org.springframework.core.convert.converter.ConditionalGenericConverter; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | import java.lang.reflect.AccessibleObject; |
| | | import java.lang.reflect.Field; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.lang.reflect.Method; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * æ¥æ¶åæ° å jackson Enum -ã String è½¬æ¢ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @Slf4j |
| | | public class EnumToStringConverter implements ConditionalGenericConverter { |
| | | /** |
| | | * ç¼å Enum 类信æ¯ï¼æä¾æ§è½ |
| | | */ |
| | | private static final ConcurrentMap<Class<?>, AccessibleObject> ENUM_CACHE_MAP = new ConcurrentHashMap<>(8); |
| | | |
| | | @Nullable |
| | | private static AccessibleObject getAnnotation(Class<?> clazz) { |
| | | Set<AccessibleObject> accessibleObjects = new HashSet<>(); |
| | | // JsonValue METHOD, FIELD |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | Collections.addAll(accessibleObjects, fields); |
| | | // methods |
| | | Method[] methods = clazz.getDeclaredMethods(); |
| | | Collections.addAll(accessibleObjects, methods); |
| | | for (AccessibleObject accessibleObject : accessibleObjects) { |
| | | // å¤ç¨ jackson ç JsonValue 注解 |
| | | JsonValue jsonValue = accessibleObject.getAnnotation(JsonValue.class); |
| | | if (jsonValue != null && jsonValue.value()) { |
| | | accessibleObject.setAccessible(true); |
| | | return accessibleObject; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public Set<ConvertiblePair> getConvertibleTypes() { |
| | | Set<ConvertiblePair> pairSet = new HashSet<>(3); |
| | | pairSet.add(new ConvertiblePair(Enum.class, String.class)); |
| | | pairSet.add(new ConvertiblePair(Enum.class, Integer.class)); |
| | | pairSet.add(new ConvertiblePair(Enum.class, Long.class)); |
| | | return Collections.unmodifiableSet(pairSet); |
| | | } |
| | | |
| | | @Override |
| | | public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
| | | if (source == null) { |
| | | return null; |
| | | } |
| | | Class<?> sourceClazz = sourceType.getType(); |
| | | AccessibleObject accessibleObject = ENUM_CACHE_MAP.computeIfAbsent(sourceClazz, EnumToStringConverter::getAnnotation); |
| | | Class<?> targetClazz = targetType.getType(); |
| | | // å¦æä¸ºnullï¼èµ°é»è®¤çè½¬æ¢ |
| | | if (accessibleObject == null) { |
| | | if (String.class == targetClazz) { |
| | | return ((Enum) source).name(); |
| | | } |
| | | int ordinal = ((Enum) source).ordinal(); |
| | | return ConvertUtil.convert(ordinal, targetClazz); |
| | | } |
| | | try { |
| | | return EnumToStringConverter.invoke(sourceClazz, accessibleObject, source, targetClazz); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Nullable |
| | | private static Object invoke(Class<?> clazz, AccessibleObject accessibleObject, Object source, Class<?> targetClazz) |
| | | throws IllegalAccessException, InvocationTargetException { |
| | | Object value = null; |
| | | if (accessibleObject instanceof Field) { |
| | | Field field = (Field) accessibleObject; |
| | | value = field.get(source); |
| | | } else if (accessibleObject instanceof Method) { |
| | | Method method = (Method) accessibleObject; |
| | | Class<?> paramType = method.getParameterTypes()[0]; |
| | | // ç±»åè½¬æ¢ |
| | | Object object = ConvertUtil.convert(source, paramType); |
| | | value = method.invoke(clazz, object); |
| | | } |
| | | if (value == null) { |
| | | return null; |
| | | } |
| | | return ConvertUtil.convert(value, targetClazz); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.convert; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonCreator; |
| | | import com.vci.web.util.ConvertUtil; |
| | | import com.vci.web.util.StringUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.core.convert.TypeDescriptor; |
| | | import org.springframework.core.convert.converter.ConditionalGenericConverter; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | import java.lang.reflect.AccessibleObject; |
| | | import java.lang.reflect.Constructor; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.lang.reflect.Method; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * æ¥æ¶åæ° å jackson String -ã Enum è½¬æ¢ |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @Slf4j |
| | | public class StringToEnumConverter implements ConditionalGenericConverter { |
| | | /** |
| | | * ç¼å Enum 类信æ¯ï¼æä¾æ§è½ |
| | | */ |
| | | private static final ConcurrentMap<Class<?>, AccessibleObject> ENUM_CACHE_MAP = new ConcurrentHashMap<>(8); |
| | | |
| | | @Nullable |
| | | private static AccessibleObject getAnnotation(Class<?> clazz) { |
| | | Set<AccessibleObject> accessibleObjects = new HashSet<>(); |
| | | // JsonCreator METHOD, CONSTRUCTOR |
| | | Constructor<?>[] constructors = clazz.getConstructors(); |
| | | Collections.addAll(accessibleObjects, constructors); |
| | | // methods |
| | | Method[] methods = clazz.getDeclaredMethods(); |
| | | Collections.addAll(accessibleObjects, methods); |
| | | for (AccessibleObject accessibleObject : accessibleObjects) { |
| | | // å¤ç¨ jackson ç JsonCreator注解 |
| | | JsonCreator jsonCreator = accessibleObject.getAnnotation(JsonCreator.class); |
| | | if (jsonCreator != null && JsonCreator.Mode.DISABLED != jsonCreator.mode()) { |
| | | accessibleObject.setAccessible(true); |
| | | return accessibleObject; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public Set<ConvertiblePair> getConvertibleTypes() { |
| | | return Collections.singleton(new ConvertiblePair(String.class, Enum.class)); |
| | | } |
| | | |
| | | @Nullable |
| | | @Override |
| | | public Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { |
| | | if (StringUtil.isBlank((String) source)) { |
| | | return null; |
| | | } |
| | | Class<?> clazz = targetType.getType(); |
| | | AccessibleObject accessibleObject = ENUM_CACHE_MAP.computeIfAbsent(clazz, StringToEnumConverter::getAnnotation); |
| | | String value = ((String) source).trim(); |
| | | // å¦æä¸ºnullï¼èµ°é»è®¤çè½¬æ¢ |
| | | if (accessibleObject == null) { |
| | | return valueOf(clazz, value); |
| | | } |
| | | try { |
| | | return StringToEnumConverter.invoke(clazz, accessibleObject, value); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | @SuppressWarnings("unchecked") |
| | | private static <T extends Enum<T>> T valueOf(Class<?> clazz, String value){ |
| | | return Enum.valueOf((Class<T>) clazz, value); |
| | | } |
| | | |
| | | @Nullable |
| | | private static Object invoke(Class<?> clazz, AccessibleObject accessibleObject, String value) |
| | | throws IllegalAccessException, InvocationTargetException, InstantiationException { |
| | | if (accessibleObject instanceof Constructor) { |
| | | Constructor constructor = (Constructor) accessibleObject; |
| | | Class<?> paramType = constructor.getParameterTypes()[0]; |
| | | // ç±»åè½¬æ¢ |
| | | Object object = ConvertUtil.convert(value, paramType); |
| | | return constructor.newInstance(object); |
| | | } |
| | | if (accessibleObject instanceof Method) { |
| | | Method method = (Method) accessibleObject; |
| | | Class<?> paramType = method.getParameterTypes()[0]; |
| | | // ç±»åè½¬æ¢ |
| | | Object object = ConvertUtil.convert(value, paramType); |
| | | return method.invoke(clazz, object); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * 忣ç Callable |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedCallable<T> { |
| | | |
| | | /** |
| | | * Run this callable. |
| | | * |
| | | * @return result |
| | | * @throws Throwable CheckedException |
| | | */ |
| | | @Nullable |
| | | T call() throws Throwable; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | /** |
| | | * 忣ç Comparator |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedComparator<T> { |
| | | |
| | | /** |
| | | * Compares its two arguments for order. |
| | | * |
| | | * @param o1 o1 |
| | | * @param o2 o2 |
| | | * @return int |
| | | * @throws Throwable CheckedException |
| | | */ |
| | | int compare(T o1, T o2) throws Throwable; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * 忣ç Consumer |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedConsumer<T> { |
| | | |
| | | /** |
| | | * Run the Consumer |
| | | * |
| | | * @param t T |
| | | * @throws Throwable UncheckedException |
| | | */ |
| | | @Nullable |
| | | void accept(@Nullable T t) throws Throwable; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * 忣ç function |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedFunction<T, R> { |
| | | |
| | | /** |
| | | * Run the Function |
| | | * |
| | | * @param t T |
| | | * @return R R |
| | | * @throws Throwable CheckedException |
| | | */ |
| | | @Nullable |
| | | R apply(@Nullable T t) throws Throwable; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | /** |
| | | * 忣ç runnable |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedRunnable { |
| | | |
| | | /** |
| | | * Run this runnable. |
| | | * |
| | | * @throws Throwable CheckedException |
| | | */ |
| | | void run() throws Throwable; |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, DreamLu All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: DreamLu 墿¥æ¢¦ (596392912@qq.com) |
| | | */ |
| | | |
| | | package com.vci.web.util.function; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * 忣ç Supplier |
| | | * |
| | | * @author L.cm |
| | | */ |
| | | @FunctionalInterface |
| | | public interface CheckedSupplier<T> { |
| | | |
| | | /** |
| | | * Run the Supplier |
| | | * |
| | | * @return T |
| | | * @throws Throwable CheckedException |
| | | */ |
| | | @Nullable |
| | | T get() throws Throwable; |
| | | |
| | | } |