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

ars.database.spring.EntitySynchronUpgrader Maven / Gradle / Ivy

The newest version!
package ars.database.spring;

import java.util.List;
import java.util.LinkedList;
import java.util.Comparator;
import java.util.Collection;
import java.util.Collections;

import org.springframework.context.event.ContextRefreshedEvent;

import ars.util.Beans;
import ars.util.Strings;
import ars.database.model.TreeModel;
import ars.database.repository.Repository;
import ars.database.repository.Repositories;
import ars.spring.context.ApplicationInitializer;

/**
 * 对象实体同步更新
 *
 * @param  对象类型
 * @author wuyongqiang
 */
public class EntitySynchronUpgrader extends ApplicationInitializer {
    private Comparator comparator;
    private List entities = Collections.emptyList(); // 对象实体列表
    private String[] comparators = Strings.EMPTY_ARRAY; // 比较属性
    private List includes = new LinkedList();

    public List getEntities() {
        return entities;
    }

    public void setEntities(List entities) {
        this.entities = entities;
    }

    public String[] getComparators() {
        return comparators;
    }

    public void setComparators(String... comparators) {
        this.comparators = comparators;
    }

    /**
     * 对象实体同步(只是新增或修改,不包含删除操作)
     *
     * @param sources 源对象实体集合
     * @param targets 目标对象实体集合
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    protected void synchron(Collection sources, Collection targets) {
        outer:
        for (T target : targets) {
            for (T source : sources) {
                if (this.comparator.compare(source, target) == 0) {
                    if (source instanceof TreeModel) {
                        List children = ((TreeModel) target).getChildren();
                        if (!children.isEmpty()) {
                            for (Object child : children) {
                                ((TreeModel) child).setParent((TreeModel) source);
                            }
                            this.synchron((Collection) ((TreeModel) source).getChildren(),
                                (Collection) children);
                        }
                    }
                    if (!includes.isEmpty()) {
                        boolean different = false;
                        for (String property : this.includes) {
                            Object sourceValue = Beans.getValue(source, property);
                            Object targetValue = Beans.getValue(target, property);
                            if (!Beans.isEqual(sourceValue, targetValue)) {
                                Beans.setValue(source, property, targetValue);
                                different = true;
                            }
                        }
                        if (different) {
                            Repositories.update(source);
                        }
                    }
                    continue outer;
                }
            }
            if (target instanceof TreeModel) {
                Repositories.saveTree((TreeModel) target);
            } else {
                Repositories.save(target);
            }
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    @Override
    protected void execute(ContextRefreshedEvent event) {
        if (this.entities.isEmpty()) {
            throw new IllegalStateException("Entities not initialized");
        }
        Class model = (Class) this.entities.get(0).getClass();
        Repository repository = Repositories.getRepository(model);
        String primary = repository.getPrimary();
        List excludes = new LinkedList();
        final List conditions = new LinkedList();
        for (String property : this.comparators) {
            if (property.equals(primary)) {
                continue;
            } else if (property.charAt(0) == '+') {
                this.includes.add(property.substring(1));
            } else if (property.charAt(0) == '-') {
                excludes.add(property.substring(1));
            } else {
                conditions.add(property);
            }
        }
        if (this.includes.isEmpty() && !excludes.isEmpty()) {
            for (String property : Beans.getProperties(model)) {
                if (!property.equals(primary) && !excludes.contains(property)) {
                    this.includes.add(property);
                }
            }
        }

        this.comparator = new Comparator() {

            @Override
            public int compare(T o1, T o2) {
                if (conditions.isEmpty()) {
                    return o1.equals(o2) ? 0 : -1;
                }
                for (String property : conditions) {
                    if (!Beans.isEqual(Beans.getValue(o1, property), Beans.getValue(o2, property))) {
                        return -1;
                    }
                }
                return 0;
            }

        };

        List sources = repository.query().list();
        if (TreeModel.class.isAssignableFrom(model)) {
            sources = (List) Repositories.mergeTrees((List) sources);
        }
        this.synchron(sources, this.entities);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy