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

com.cybermkd.common.entity.Entity Maven / Gradle / Ivy

package com.cybermkd.common.entity;

import com.cybermkd.common.entity.exception.EntityException;
import com.cybermkd.common.util.Maper;
import com.cybermkd.common.util.json.Jsoner;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by ice on 14-12-31.
 */
public abstract class Entity {

    private Map attrs = new CaseInsensitiveMap();
    /**
     * Flag of attr has been modified. update need this flag
     */
    private Map modifyAttrs = new CaseInsensitiveMap();

    /**
     * get Conversion to convert attr
     *
     * @param attr
     * @return
     */
    public abstract Conversion getConversion(String attr);

    /**
     * Return attribute Map.
     * Danger! The update method will ignore the attribute if you change it directly.
     * You must use set method to change attribute that update method can handle it.
     */
    public Map getAttrs() {
        return attrs;
    }

    /**
     * Set attributes with other entity.
     *
     * @param entity the Model
     * @return this Model
     */
    public M setAttrs(M entity) {
        return (M) setAttrs(entity.getAttrs());
    }

    /**
     * Set attributes with Map.
     *
     * @param attrs attributes of this entity
     * @return this Model
     */
    public M setAttrs(Map attrs) {
        for (Map.Entry e : attrs.entrySet())
            set(e.getKey(), e.getValue());
        return (M) this;
    }

    /**
     * 获取更新的属性列表
     *
     * @return Map
     */
    public Map getModifyAttrs() {
        return modifyAttrs;
    }

    /**
     * check method for to json
     *
     * @return boolean
     */
    public boolean checkMethod() {
        return false;
    }

    /**
     * 判断数据库是否拥有该列
     *
     * @param attr 属性名
     * @return boolean
     */
    public abstract boolean hasColumn(String attr);

    /**
     * 获取改数据库列对应的java类型
     *
     * @param attr 属性名
     * @return class
     */
    public abstract Class getColumnType(String attr);

    /**
     * Set attribute to entity.
     *
     * @param attr  the attribute name of the entity
     * @param value the value of the attribute
     * @return this entity
     * @throws EntityException if the attribute is not exists of the entity
     */
    public M set(String attr, Object value) {
        if (hasColumn(attr)) {
            attrs.put(attr, value);
            modifyAttrs.put(attr, value);  // Add modify flag, update() need this flag.
            return (M) this;
        }
        throw new EntityException("The attribute name is not exists: " + attr);
    }

    /**
     * 初始化属性 不会添加到modify
     *
     * @param attr
     * @param value
     * @return
     */
    public M init(String attr, Object value) {
        attrs.put(attr, value);
        return (M) this;
    }

    public M initAttrs(Map attrs) {
        for (Map.Entry e : attrs.entrySet()) {
            init(e.getKey(), e.getValue());
        }
        return (M) this;
    }

    public M initAttrs(M entity) {
        return (M) initAttrs(entity.getAttrs());
    }

    /**
     * Put key value pair to the entity when the key is not attribute of the entity.
     *
     * @param attr  属性名称
     * @param value 属性值
     * @return 当前entity对象
     */
    public M put(String attr, Object value) {
        if (hasColumn(attr)) {
            modifyAttrs.put(attr, value);
        }
        attrs.put(attr, value);
        return (M) this;
    }

    public M putAttrs(Map attrs) {
        for (Map.Entry e : attrs.entrySet()) {
            put(e.getKey(), e.getValue());
        }
        return (M) this;
    }

    /**
     * Set attrs value with entity.
     *
     * @param entity the entity
     */
    public M putAttrs(M entity) {
        return (M) putAttrs(entity.getAttrs());
    }

    /**
     * Get attr of any sql type
     */
    public  T get(String attr) {
        return (T) attrs.get(attr);
    }

    /**
     * Parse attr to any type
     */
    public  T get(String attr, Class clazz) {
        if (attrs.containsKey(attr)) {
            Object value = attrs.get(attr);
            T result = null;

            if (value != null) {
                if (clazz.isAssignableFrom(value.getClass())) {
                    result = (T) value;
                } else {
                    result = Jsoner.toObject(Jsoner.toJSON(value), clazz);
                }
            }
            return result;
        } else {
            throw new EntityException("Attribute '" + attr + "' could not found.");
        }
    }

    /**
     * Get attr of any sql type. Returns defaultValue if null.
     */
    public  T get(String attr, Object defaultValue) {
        Object result = get(attr);
        return (T) (result != null ? result : defaultValue);
    }

    /**
     * Get attr for clazz. Returns defaultValue if null.
     */
    public  T get(String attr, Class clazz, Object defaultValue) {
        Object result = get(attr, clazz);
        return (T) (result != null ? result : defaultValue);
    }


    /**
     * Remove attribute of this entity.
     *
     * @param attr the attr name of the entity
     */
    public M remove(String attr) {
        this.attrs.remove(attr);
        this.modifyAttrs.remove(attr);
        return (M) this;
    }

    /**
     * Remove attrs of this entity.
     *
     * @param attrs the attr name of the entity
     */
    public M remove(String... attrs) {
        if (attrs != null)
            for (String attr : attrs) {
                remove(attr);
            }
        return (M) this;
    }

    /**
     * Remove attrs if it is null.
     */
    public M removeNull() {
        for (java.util.Iterator> it = attrs.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry e = it.next();
            if (e.getValue() == null) {
                it.remove();
            }
        }
        return (M) this;
    }

    /**
     * Keep attrs of this entity and remove other attrs.
     *
     * @param attrs the attr name of the entity
     */
    public M keep(String... attrs) {
        if (attrs != null && attrs.length > 0) {
            Map newAttrs = new HashMap(attrs.length);
            Map newModifyAttrs = new HashMap();
            for (String c : attrs) {
                if (this.attrs.containsKey(c)) { // prevent put null value to the newAttrs
                    newAttrs.put(c, this.attrs.get(c));
                    if (this.modifyAttrs.containsKey(c)) {
                        newModifyAttrs.put(c, this.attrs.get(c));
                    }
                }
            }
            this.attrs.clear();
            this.attrs.putAll(newAttrs);
            this.modifyAttrs.clear();
            this.modifyAttrs.putAll(newModifyAttrs);
        } else {
            this.attrs.clear();
            this.modifyAttrs.clear();
        }
        return (M) this;
    }

    /**
     * Keep attr of this entity and remove other attrs.
     *
     * @param attr the attr name of the entity
     */
    public M keep(String attr) {
        if (this.attrs.containsKey(attr)) {  // prevent put null value to the newAttrs

            Object keepIt = this.attrs.get(attr);
            this.attrs.clear();
            this.attrs.put(attr, keepIt);
            if (this.modifyAttrs.containsKey(attr)) {
                this.modifyAttrs.clear();
                this.modifyAttrs.put(attr, keepIt);
            }
        } else {
            this.attrs.clear();
            this.modifyAttrs.clear();
        }
        return (M) this;
    }

    /**
     * Remove all attrs of this entity.
     */
    public M clearAttrs() {
        attrs.clear();
        return (M) this;
    }

    public M clearModifyAttrs() {
        modifyAttrs.clear();
        return (M) this;
    }

    public M reSetAttrs(Map attrs) {
        this.attrs = attrs;
        return (M) this;
    }

    public M reSetModifyAttrs(Map modifyAttrs) {
        this.modifyAttrs = modifyAttrs;
        return (M) this;
    }

    /**
     * Return attr name of this record.
     */
    public String[] getAttrNames() {
        Set attrNameSet = attrs.keySet();
        return attrNameSet.toArray(new String[attrNameSet.size()]);
    }

    /**
     * Return attr values of this record.
     */
    public Object[] getAttrValues() {
        Collection attrValueCollection = attrs.values();
        return attrValueCollection.toArray(new Object[attrValueCollection.size()]);
    }

    public String[] getModifyAttrNames() {
        return getModifyAttrNames(null);
    }

    /**
     * Return attribute name of this entity.
     */
    public String[] getModifyAttrNames(String generatedKey) {
        Set attrNameSet = modifyAttrs.keySet();
        if (generatedKey != null && !generatedKey.isEmpty()) {
            attrNameSet.remove(generatedKey);
        }
        return attrNameSet.toArray(new String[attrNameSet.size()]);
    }

    /**
     * Return attribute values of this entity.
     */
    public Object[] getModifyAttrValues() {
        return getModifyAttrValues(null);
    }

    public Object[] getModifyAttrValues(String generatedKey) {
        Map attrValueMap = Maper.copyOf(new CaseInsensitiveMap(), modifyAttrs);
        if (generatedKey != null && !generatedKey.isEmpty()) {
            attrValueMap.remove(generatedKey);
        }

        Conversion conversion;
        for (Map.Entry attrValueEntry : attrValueMap.entrySet()) {
            conversion = getConversion(attrValueEntry.getKey());
            if (conversion != null) {
                attrValueEntry.setValue(conversion.write(attrValueEntry.getValue()));
            }
        }

        Collection attrValueCollection = attrValueMap.values();
        return attrValueCollection.toArray(new Object[attrValueCollection.size()]);
    }

    public String toString() {
        return toJson();
    }

    /**
     * Return json string of this record.
     */
    public String toJson() {
        return Jsoner.toJSON(attrs);
    }

}