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

ars.database.repository.Repositories Maven / Gradle / Ivy

The newest version!
package ars.database.repository;

import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Comparator;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.io.Serializable;

import ars.util.Beans;
import ars.util.Strings;
import ars.util.Randoms;
import ars.util.Formable;
import ars.util.SimpleTree;
import ars.database.model.TreeModel;

/**
 * 数据持久化操作工具类
 *
 * @author wuyongqiang
 */
public final class Repositories {
    /**
     * 树对象唯一标识字符串分隔符
     */
    public static final char TREE_KEY_SEPARATOR = 'x';

    /**
     * 默认数据模型主键名称
     */
    public static final String DEFAULT_PRIMARY_NAME = "id";

    /**
     * 数据持久化处理对象工厂
     */
    private static RepositoryFactory repositoryFactory;

    private Repositories() {

    }

    /**
     * 获取数据持久化处理对象工厂
     *
     * @return 数据持久化处理对象工厂
     */
    public static RepositoryFactory getRepositoryFactory() {
        if (repositoryFactory == null) {
            throw new IllegalStateException("RepositoryFactory not initialize");
        }
        return repositoryFactory;
    }

    /**
     * 设置数据持久化处理对象工厂
     *
     * @param repositoryFactory 数据持久化处理对象工厂
     */
    public static void setRepositoryFactory(RepositoryFactory repositoryFactory) {
        if (repositoryFactory == null) {
            throw new IllegalArgumentException("RepositoryFactory must not be null");
        }
        if (Repositories.repositoryFactory != null) {
            throw new IllegalStateException("RepositoryFactory already initialized");
        }
        synchronized (Repositories.class) {
            if (Repositories.repositoryFactory == null) {
                Repositories.repositoryFactory = repositoryFactory;
            }
        }
    }

    /**
     * 获取系统数据模型列表
     *
     * @return 数据模型列表
     */
    public static List> getModels() {
        List> models = new ArrayList>(getRepositoryFactory().getRepositories().keySet());
        Collections.sort(models, new Comparator>() {

            @Override
            public int compare(Class o1, Class o2) {
                return o1.getName().compareTo(o2.getName());
            }

        });
        return models;
    }

    /**
     * 获取数据持久化对象
     *
     * @param    数据类型
     * @param model 数据模型
     * @return 数据持久化对象
     */
    public static  Repository getRepository(Class model) {
        return getRepositoryFactory().getRepository(model);
    }

    /**
     * 获取父节点标识
     *
     * @param key 树标识
     * @return 树标识
     */
    public static String getParentKey(String key) {
        int count = 0, index1 = -1, index2 = -1;
        for (int i = key.length() - 1; i > -1; i--) {
            if (key.charAt(i) == TREE_KEY_SEPARATOR) {
                index1 = index2;
                index2 = i;
                if (++count > 2) {
                    break;
                }
            }
        }
        return count < 3 ? null : key.substring(0, index1 + 1);
    }

    /**
     * 根据树标识获取所有父节点标识
     *
     * @param key 树标识
     * @return 父节点标识数组
     */
    public static String[] getParentKeys(String key) {
        if (key == null || key.isEmpty()) {
            return Strings.EMPTY_ARRAY;
        }
        int offset = 0;
        List keys = new LinkedList();
        for (int i = 0; i < key.length(); i++) {
            char c = key.charAt(i);
            if (i > 0 && c == TREE_KEY_SEPARATOR) {
                keys.add(key.substring(offset, i + 1));
                offset = i;
            }
        }
        return keys.subList(0, keys.size() - 1).toArray(Strings.EMPTY_ARRAY);
    }

    /**
     * 构建树对象实体标识
     *
     * @param   数据类型
     * @param tree 树对象实体
     * @return 树标识
     */
    @SuppressWarnings("rawtypes")
    public static  String buildTreeKey(M tree) {
        if (tree == null) {
            throw new IllegalArgumentException("Tree must not be null");
        }
        return buildTreeKey(tree, tree.getId());
    }

    /**
     * 构建树对象实体标识
     *
     * @param       数据类型
     * @param tree     树对象实体
     * @param sequence 序号(不能小于0)
     * @return 树标识
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  String buildTreeKey(M tree, int sequence) {
        if (tree == null) {
            throw new IllegalArgumentException("Tree must not be null");
        }
        if (sequence < 0) {
            throw new IllegalArgumentException("Sequence must not be less than 0");
        }
        M parent = (M) tree.getParent();
        return new StringBuilder().append(parent == null ? TREE_KEY_SEPARATOR : parent.getKey()).append(sequence)
            .append(TREE_KEY_SEPARATOR).toString();
    }

    /**
     * 刷新树对象实体标识
     *
     * @param   数据类型
     * @param tree 树对象实体
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  void refreshTreeKey(M tree) {
        if (tree == null) {
            throw new IllegalArgumentException("Tree must not be null");
        }
        String key = tree.getKey();
        if (key == null) {
            tree.setKey(buildTreeKey(tree));
        } else {
            M parent = (M) tree.getParent();
            String pkey = getParentKey(key);
            if (parent == null && pkey != null) {
                tree.setKey(key.substring(pkey.length() - 1));
            } else if (pkey == null && parent != null) {
                tree.setKey(new StringBuilder(parent.getKey()).append(key.substring(1)).toString());
            } else if (parent != null && pkey != null && !Beans.isEqual(parent.getKey(), pkey)) {
                tree.setKey(new StringBuilder(parent.getKey()).append(key.substring(pkey.length())).toString());
            }
        }
    }

    /**
     * 合并树对象并返回根节点列表
     *
     * @param    数据类型
     * @param trees 树对象数组
     * @return 合并后的树对象根节点列表
     */
    @SuppressWarnings("rawtypes")
    public static  List mergeTrees(M[] trees) {
        if (trees == null) {
            throw new IllegalArgumentException("Trees must not be null");
        }
        return trees.length == 0 ? new ArrayList(0) : mergeTrees(Arrays.asList(trees));
    }

    /**
     * 合并树对象并返回根节点副本(根据key值组装树结构)
     *
     * @param    数据类型
     * @param trees 树对象集合
     * @return 根节点列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List mergeTrees(Collection trees) {
        if (trees == null) {
            throw new IllegalArgumentException("Trees must not be null");
        }
        if (trees.isEmpty()) {
            return new ArrayList(0);
        }
        Map temp = new LinkedHashMap(trees.size());
        Map> groups = new HashMap>();
        for (M tree : trees) {
            String key = tree.getKey();
            if (temp.containsKey(key)) {
                continue;
            }
            temp.put(key, tree);
            if (!groups.containsKey(key)) {
                groups.put(key, new LinkedList());
            }
            String parentKey = getParentKey(key);
            if (parentKey != null) {
                List group = groups.get(parentKey);
                if (group == null) {
                    group = new LinkedList();
                    groups.put(parentKey, group);
                }
                group.add(tree);
            }
        }
        LinkedList roots = new LinkedList();
        for (Entry entry : temp.entrySet()) {
            M tree = entry.getValue();
            tree.setChildren(groups.get(entry.getKey()));
            String parentKey = getParentKey(tree.getKey());
            if (parentKey == null || !temp.containsKey(parentKey)) {
                roots.add(tree);
            }
        }
        return roots;
    }

    /**
     * 获取主键名称
     *
     * @param model 数据模型
     * @return 主键名称
     */
    public static String getPrimary(Class model) {
        if (model == null) {
            throw new IllegalArgumentException("Model must not be null");
        }
        return getRepository(model).getPrimary();
    }

    /**
     * 获取对象主键
     *
     * @param object 对象实例
     * @return 主键标识
     */
    public static Serializable getIdentifier(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        return (Serializable) Beans.getValue(object, Repositories.getPrimary(object.getClass()));
    }

    /**
     * 根据主键获取对象实例
     *
     * @param    数据类型
     * @param model 数据模型
     * @param id    主键
     * @return 对象实例
     */
    public static  M get(Class model, Object id) {
        if (model == null) {
            throw new IllegalArgumentException("Model must not be null");
        }
        return id == null ? null : getRepository(model).get(id);
    }

    /**
     * 随机抽取对象实例
     *
     * @param    数据类型
     * @param model 数据模型
     * @return 对象实例
     */
    public static  M extract(Class model) {
        if (model == null) {
            throw new IllegalArgumentException("Model must not be null");
        }
        Repository repository = getRepository(model);
        int count = repository.query().count();
        if (count == 0) {
            return null;
        }
        int size = 100;
        int page = Randoms.randomInteger(1, (int) Math.ceil((double) count / size) + 1);
        List objects = repository.query().paging(page, size).list();
        return objects.get(Randoms.randomInteger(0, objects.size()));
    }

    /**
     * 保存对象
     *
     * @param object 对象实例
     * @return 数据主键
     */
    @SuppressWarnings("unchecked")
    public static Serializable save(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        return getRepository((Class) object.getClass()).save(object);
    }

    /**
     * 修改对象
     *
     * @param object 对象实例
     */
    @SuppressWarnings("unchecked")
    public static void update(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        getRepository((Class) object.getClass()).update(object);
    }

    /**
     * 删除对象
     *
     * @param object 对象实例
     */
    @SuppressWarnings("unchecked")
    public static void delete(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        getRepository((Class) object.getClass()).delete(object);
    }

    /**
     * 级联保存树对象
     *
     * @param     数据类型
     * @param object 树对象
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  void saveTree(M object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        saveTree(getRepository((Class) object.getClass()), object);
    }

    /**
     * 级联保存树对象
     *
     * @param         数据类型
     * @param repository 持久化操作对象
     * @param object     树对象
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  void saveTree(Repository repository, M object) {
        if (repository == null) {
            throw new IllegalArgumentException("Repository must not be null");
        }
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        List children = new ArrayList(object.getChildren());
        object.getChildren().clear();
        repository.save((M) object);
        for (int i = 0; i < children.size(); i++) {
            TreeModel child = (TreeModel) children.get(i);
            child.setParent(object);
            saveTree(repository, (M) child);
        }
    }

    /**
     * 获取对象实体的树形对象
     *
     * @param object 对象实体
     * @return 树形对象
     */
    public static SimpleTree getSimpleTree(Object object) {
        if (object == null) {
            throw new IllegalArgumentException("Object must not be null");
        }
        String id = new StringBuilder(object.getClass().getSimpleName()).append('_').append(object.hashCode())
            .toString();
        Map values = object instanceof Formable ? ((Formable) object).format()
            : Beans.getValues(object);
        return new SimpleTree(id, object.toString(), values);
    }

    /**
     * 获取对象实体的树形对象
     *
     * @param objects 对象实体集合
     * @return 树形对象列表
     */
    public static List getSimpleTrees(Collection objects) {
        return getSimpleTrees(objects, null);
    }

    /**
     * 获取对象实体的树形对象
     *
     * @param       数据类型
     * @param objects  对象实体集合
     * @param mappings 原始对象实例/树对象实例映射
     * @return 树形对象列表
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  List getSimpleTrees(Collection objects, Map mappings) {
        if (objects == null) {
            throw new IllegalArgumentException("Objects must not be null");
        }
        if (objects == null || objects.isEmpty()) {
            return new ArrayList(0);
        }
        List simples = new ArrayList(objects.size());
        for (M object : objects) {
            SimpleTree tree = getSimpleTree(object);
            if (mappings != null) {
                mappings.put(object, tree);
            }
            if (object instanceof TreeModel) {
                List children = ((TreeModel) object).getChildren();
                if (!children.isEmpty()) {
                    List schildren = getSimpleTrees(children, mappings);
                    tree.setChildren(schildren);
                    for (int i = 0; i < schildren.size(); i++) {
                        schildren.get(i).setParent(tree);
                    }
                }
            }
            simples.add(tree);
        }
        return simples;
    }

    /**
     * 获取数据查询集合
     *
     * @param    数据类型
     * @param model 数据模型
     * @return 数据查询集合
     */
    public static  Query query(Class model) {
        if (model == null) {
            throw new IllegalArgumentException("Model must not be null");
        }
        return getRepository(model).query();
    }

    /**
     * 获取数据空查询集合
     *
     * @param  数据类型
     * @return 数据空查询集合
     */
    public static  Query emptyQuery() {
        return EmptyQuery.instance();
    }

    /**
     * 随机生成对象实例
     *
     * @param    数据类型
     * @param model 数据模型
     * @return 对象实例
     */
    public static  M random(final Class model) {
        if (model == null) {
            throw new IllegalArgumentException("Model must not be null");
        }
        final Set> models = getRepositoryFactory().getRepositories().keySet();
        return Randoms.random(model).register(new Randoms.ExcludeStrategy() {

            @Override
            public boolean exclude(Class type, Field field) {
                return Modifier.isAbstract(type.getModifiers()) || (field != null && models.contains(type)
                    && (field.getName().equals(getPrimary(type)) || (TreeModel.class.isAssignableFrom(type)
                    && (field.getName().equals("key") || field.getName().equals("level")
                    || field.getName().equals("leaf") || field.getName().equals("parent")))));
            }

        }).register(new Randoms.RandomGeneratorFactory() {

            @Override
            public  Randoms.RandomGenerator getRandomGenerator(final Class type, Field field) {
                if (type == model || !models.contains(type)) {
                    return null;
                }
                return new Randoms.RandomGenerator() {

                    @Override
                    public T generate() {
                        return extract(type);
                    }

                };
            }

        }).build();
    }

}