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.table.IdInfo;
019import com.mybatisflex.core.table.TableInfo;
020import com.mybatisflex.core.table.TableInfoFactory;
021import com.mybatisflex.core.update.ModifyAttrsRecordProxyFactory;
022import org.apache.ibatis.reflection.Reflector;
023import org.apache.ibatis.reflection.invoker.Invoker;
024
025import java.lang.reflect.Array;
026import java.util.List;
027
028public class UpdateEntity {
029
030    private UpdateEntity() {
031    }
032
033
034    public static <T> T of(Class<T> clazz) {
035        clazz = ClassUtil.getUsefulClass(clazz);
036        return ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
037    }
038
039
040    public static <T> T of(Class<T> clazz, Object id) {
041        clazz = ClassUtil.getUsefulClass(clazz);
042        T newEntity = ModifyAttrsRecordProxyFactory.getInstance().get(clazz);
043        TableInfo tableInfo = TableInfoFactory.ofEntityClass(clazz);
044        List<IdInfo> primaryKeyList = tableInfo.getPrimaryKeyList();
045        Reflector reflector = Reflectors.of(clazz);
046
047        if (primaryKeyList != null && !primaryKeyList.isEmpty()) {
048            for (int i = 0; i < primaryKeyList.size(); i++) {
049                IdInfo idInfo = primaryKeyList.get(i);
050                Object idValue = getIdValue(id, i);
051                Invoker setInvoker = reflector.getSetInvoker(idInfo.getProperty());
052                try {
053                    setInvoker.invoke(newEntity, new Object[]{ConvertUtil.convert(idValue, idInfo.getPropertyType())});
054                } catch (Exception e) {
055                    throw new RuntimeException(e.getMessage(), e);
056                }
057            }
058        }
059        return newEntity;
060    }
061
062
063    private static Object getIdValue(Object id, int index) {
064        if (id == null) {
065            return null;
066        }
067        if (ClassUtil.isArray(id.getClass())) {
068            if (index >= Array.getLength(id)) {
069                return null;
070            } else {
071                return Array.get(id, index);
072            }
073        }
074        //not array
075        return index == 0 ? id : null;
076    }
077
078
079    public static <T> T ofNotNull(T entity) {
080        Class<?> usefulClass = ClassUtil.getUsefulClass(entity.getClass());
081
082        T newEntity = (T) of(usefulClass);
083
084        Reflector reflector = Reflectors.of(usefulClass);
085        String[] propertyNames = reflector.getGetablePropertyNames();
086
087        for (String propertyName : propertyNames) {
088            try {
089                Object value = reflector.getGetInvoker(propertyName)
090                    .invoke(entity, null);
091                if (value != null) {
092                    reflector.getSetInvoker(propertyName).invoke(newEntity, new Object[]{value});
093                }
094            } catch (Exception ignored) {
095                // do nothing here.
096            }
097        }
098
099        return newEntity;
100    }
101
102
103}