001/**
002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package com.mybatisflex.core.util;
017
018import com.mybatisflex.core.javassist.ModifyAttrsRecordProxyFactory;
019import com.mybatisflex.core.table.IdInfo;
020import com.mybatisflex.core.table.TableInfo;
021import com.mybatisflex.core.table.TableInfoFactory;
022import org.apache.ibatis.reflection.DefaultReflectorFactory;
023import org.apache.ibatis.reflection.Reflector;
024import org.apache.ibatis.reflection.ReflectorFactory;
025import org.apache.ibatis.reflection.invoker.Invoker;
026
027import java.lang.reflect.Array;
028import java.util.List;
029
030public class UpdateEntity {
031
032    private static ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
033
034
035    public static <T> T of(Class<T> clazz) {
036        return ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
037    }
038
039
040    public static <T> T of(Class<T> clazz, Object id) {
041        T newEntity = ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
042        TableInfo tableInfo = TableInfoFactory.ofEntityClass(clazz);
043        List<IdInfo> primaryKeyList = tableInfo.getPrimaryKeyList();
044        Reflector reflector = reflectorFactory.findForClass(clazz);
045
046        if (primaryKeyList != null && !primaryKeyList.isEmpty()) {
047            for (int i = 0; i < primaryKeyList.size(); i++) {
048                IdInfo idInfo = primaryKeyList.get(i);
049                Object idValue = getIdValue(id, i);
050                Invoker setInvoker = reflector.getSetInvoker(idInfo.getProperty());
051                try {
052                    setInvoker.invoke(newEntity, new Object[]{ConvertUtil.convert(idValue, idInfo.getPropertyType())});
053                } catch (Exception e) {
054                    throw new RuntimeException(e.getMessage(), e);
055                }
056            }
057        }
058        return newEntity;
059    }
060
061
062    private static Object getIdValue(Object id, int index) {
063        if (id == null) {
064            return null;
065        }
066        if (ClassUtil.isArray(id.getClass())) {
067            if (index >= Array.getLength(id)) {
068                return null;
069            } else {
070                return Array.get(id, index);
071            }
072        }
073        //not array
074        return index == 0 ? id : null;
075    }
076
077
078    public static <T> T ofNotNull(T entity) {
079        Class<?> usefulClass = ClassUtil.getUsefulClass(entity.getClass());
080
081        T newEntity = (T) of(usefulClass);
082
083        Reflector reflector = reflectorFactory.findForClass(usefulClass);
084        String[] propertyNames = reflector.getGetablePropertyNames();
085
086        for (String propertyName : propertyNames) {
087            try {
088                Object value = reflector.getGetInvoker(propertyName)
089                        .invoke(entity, null);
090                if (value != null) {
091                    reflector.getSetInvoker(propertyName).invoke(newEntity, new Object[]{value});
092                }
093            } catch (Exception e) {
094                //ignore;
095            }
096        }
097
098        return newEntity;
099    }
100
101
102}