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