Package com.jengine.orm.model

Source Code of com.jengine.orm.model.ModelClassBase

/*
*  This file is part of JEngine.
*  *
*  * Copyright (C) 2013-2014 Cetus (http://cs1.com.ua/). All rights reserved.
*  *
*  * JEngine is free software: you can redistribute it and/or modify
*  * it under the terms of the GNU General Public License as published by
*  * the Free Software Foundation, either version 3 of the License, or
*  * (at your option) any later version.
*  *
*  * JEngine is distributed in the hope that it will be useful,
*  * but WITHOUT ANY WARRANTY; without even the implied warranty of
*  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  * GNU General Public License for more details.
*  *
*  * You should have received a copy of the GNU General Public License
*  * along with JEngine.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.jengine.orm.model;

import com.jengine.orm.DB;
import com.jengine.orm.db.DBException;
import com.jengine.orm.db.provider.Provider;
import com.jengine.orm.exception.ValidateException;
import com.jengine.orm.model.field.Attribute;
import com.jengine.orm.model.field.Field;
import com.jengine.orm.model.field.ModelProperty;
import com.jengine.orm.model.field.reference.ManyReferenceField;
import com.jengine.orm.model.multi.field.CalcMultiField;
import com.jengine.orm.model.multi.field.aggregation.*;
import com.jengine.orm.model.query.ModelQuery;
import com.jengine.orm.model.query.filter.Filter;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

import static com.jengine.utils.commons.CollectionUtil.map;

public class ModelClassBase<T extends Model> {
    protected DB db;
    protected Provider provider;
    protected ModelManager manager;
    protected String name;
    protected Class<T> cls;

    public ModelClassBase(String name, Class<T> cls) {
        this.name = name;
        this.cls = cls;
    }

    public void register() {
        db.register(this);
    }

    public T newInstance(Map values) throws DBException {
        Model obj = newInstance();
        obj.setModelClass(this);
        obj.setValues(values);
        return (T) obj;
    }

    public T newInstance() throws DBException {
        Model obj = null;
        try {
            obj = cls.newInstance();
            obj.setModelClass(this);
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new DBException(e.getMessage());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new DBException(e.getMessage());
        }
        return (T) obj;
    }

    public T get(Object id) throws DBException {
        Model obj = getCache(manager.getPrimaryKey().cast(id));
        return (T) (obj != null ? obj : (Model) new ModelQuery(manager).filter(manager.getPrimaryKey().eq(id)).one());
    }

    public ModelQuery select(Object ... fields) throws DBException {
        return select(Arrays.asList(fields));
    }

    public ModelQuery select(List fields) throws DBException {
        return new ModelQuery(manager).targets(fields);
    }

    public ModelQuery filter(String query, Object ... params) throws DBException {
        return new ModelQuery(manager).filter(query, (Object[]) params);
    }

    public ModelQuery filter(Map<String, Object> filter) throws DBException {
        return new ModelQuery(manager).filter(filter);
    }

    public ModelQuery filter(Filter... filters) throws DBException {
        return filter(Arrays.asList(filters));
    }

    public ModelQuery filter(List<Filter> filter) throws DBException {
        return new ModelQuery(manager).filter(filter);
    }

    public Long count() throws DBException {
        return (Long) new ModelQuery(manager).target(new Count(manager.getPrimaryKey())).one();
    }

    public Long count(String field) throws DBException {
        return (Long) new ModelQuery(manager).target(new Count(field)).one();
    }

    public Object max(String field) throws DBException {
        return new ModelQuery(manager).target(new Max(field)).one();
    }

    public Object min(String field) throws DBException {
        return new ModelQuery(manager).target(new Min(field)).one();
    }

    public Object avg(String field) throws DBException {
        return new ModelQuery(manager).target(new Avg(field)).one();
    }

    public Object sum(String field) throws DBException {
        return new ModelQuery(manager).target(new Sum(field)).one();
    }

    public Long count(Field field) throws DBException {
        return (Long) new ModelQuery(manager).target(new Count(field)).one();
    }

    public <ResultType> ResultType max(Field field) throws DBException {
        return (ResultType) new ModelQuery(manager).target(new Max(field)).one();
    }

    public <ResultType> ResultType min(Field field) throws DBException {
        return (ResultType) new ModelQuery(manager).target(new Min(field)).one();
    }

    public <ResultType> ResultType avg(Field field) throws DBException {
        return (ResultType) new ModelQuery(manager).target(new Avg(field)).one();
    }

    public <ResultType> ResultType sum(Field field) throws DBException {
        return (ResultType) new ModelQuery(manager).target(new Sum(field)).one();
    }

    public <ResultType> ResultType calc(String name, Class type, String expr, Field ... fields) throws DBException {
        List<String> fieldNames = new ArrayList<String>();
        for (Field field : fields) {
            fieldNames.add(field.getFieldName());
        }
        return (ResultType) new ModelQuery(manager).target(new CalcMultiField(name, type, null, expr, fieldNames, map())).one();
    }

    public void remove() throws DBException {
        new ModelQuery(manager).remove();
        clearCache();
    }

    public Model wrap(Map<String, Object> values) throws DBException {
        Model obj = newInstance();
        for(String columnName : values.keySet()) {
            obj.setValue(manager.getFieldByColumn(columnName), values.get(columnName));
        }
        obj.setNew(false);
        return obj;
    }

    /* Cache methods  */

    public boolean isCacheEnabled() throws DBException {
        return manager.getCacheEnabled() && provider.isCacheEnabled();
    }

    public T getCache(Object id) throws DBException {
        if (isCacheEnabled()) {
            Map<String, Object> values = null;
            try {
                values = provider.getCache(manager.getTableName(), id);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return values != null ? (T) wrap(values) : null;
        } else {
            return null;
        }
    }

    public void clearCache() throws DBException {
        if (isCacheEnabled()) {
            provider.clearCache(manager.getTableName());
        }
    }

    public void clearCache(Model obj) throws DBException {
        if (isCacheEnabled()) {
            provider.clearCache(manager.getTableName(), obj.getPrimaryKey());
        }
    }

    public void cache(Model obj) throws DBException {
        if (isCacheEnabled()) {
            Map<String, Object> attributes = new HashMap<String, Object>();
            attributes.putAll(obj.getPersistenceValues());
            attributes.putAll(obj.getFunctionValues());
            provider.cache(manager.getTableName(), manager.getPrimaryKey().getPersistenceValue(obj), attributes);
        }
    }


    /* Model object methods  */

    public T insert(T obj) throws ValidateException, DBException {
        boolean autoIncrement = obj.getPrimaryKey() == null && manager.getPrimaryKey().isAutoIncrement();
        Object id = provider.insert(manager.getTableName(), obj.getPersistenceValues(), autoIncrement);
        obj.setNew(false);
        if (autoIncrement && id != null) {
            obj.setPrimaryKey((Serializable) id);
        }
        insertManyReference(obj);
        calcFunctionField(obj);
        return obj;
    }

    public T update(T obj) throws ValidateException, DBException {
        Map<String, Object> changes = obj.getChangedPersistenceValues();
        if (changes.size() > 0) {
            provider.update(manager.getTableName(), manager.getPrimaryKey().getColumnName(), obj.getPrimaryKey(), changes);
        }
        updateManyReference(obj);
        calcFunctionField(obj);
        return obj;
    }

    protected void updateManyReference(T obj) throws ValidateException, DBException {
        for (Field field : manager.getFields(Field.Type.MANY_REFERENCE, Field.Type.REVERSE_MANY_REFERENCE)) {
            ((ManyReferenceField) field).update(obj);
            obj.getData().remove(field.getFieldName());
        }
    }

    protected void insertManyReference(T obj) throws ValidateException, DBException {
        for (Field field : manager.getFields(Field.Type.MANY_REFERENCE, Field.Type.REVERSE_MANY_REFERENCE)) {
            ((ManyReferenceField) field).insert(obj);
            obj.getData().remove(field.getFieldName());
        }
    }

    protected void calcFunctionField(T obj) throws ValidateException, DBException {
        List<Field> functionFields = manager.getFunctionFields();
        if (manager.getFunctionFields().size() > 0) {
            Model updatedObject = get(obj.getId());

            for (Field field : functionFields) {
                obj.getData().put(field.getFieldName(), updatedObject.getData().get(field.getFieldName()));
            }
        }
    }

    public void remove(Model obj) throws DBException {
        provider.remove(manager.getTableName(), manager.getPrimaryKey().getColumnName(), obj.getPrimaryKey());
    }


    /* getters and setters */

    public Provider getProvider() {
        return provider;
    }

    public ModelManager getManager() {
        return manager;
    }

    public String getName() {
        return name;
    }

    public DB getDb() {
        return db;
    }


    /* collect methods */

    public Map<String, Field> collectFields(Class cls) {
        Map<String, Field> modelFields = new LinkedHashMap<String, Field>();
        for (java.lang.reflect.Field fld : cls.getDeclaredFields()){
            if (Modifier.isStatic(fld.getModifiers())) {
                try {
                    if (fld.get(null) instanceof Field) {
                        Field modelField = (Field) fld.get(null);
                        modelFields.put(fld.getName(), modelField);
                    }
                } catch (IllegalAccessException e) {
                }
            }
        }
        for (java.lang.reflect.Field fld : getAllFields(cls.getSuperclass())){
            if (Modifier.isStatic(fld.getModifiers())) {
                try {
                    if (fld.get(null) instanceof Field) {
                        Field modelField = (Field) fld.get(null);
                        try {
                            modelFields.put(fld.getName(), modelField.copy());
                        } catch (DBException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (IllegalAccessException e) {
                }
            }
        }
        return modelFields;
    }

    public Map<String, ModelProperty> collectProperties(Class cls) {
        Map<String, ModelProperty> properties =  new LinkedHashMap<String, ModelProperty>();

        for (Method method : cls.getMethods()) {
            if (method.isAnnotationPresent(Attribute.class)) {
                Attribute attribute = method.getAnnotation(Attribute.class);
                properties.put(attribute.name(),
                        new ModelProperty(method.getName(), method.getReturnType(),
                                map("verbose", attribute.verbose(), "visible", attribute.visible()))
                );
            }
        }

        return properties;
    }

    public static List<java.lang.reflect.Field> getAllFields(Class<?> type) {
        List<java.lang.reflect.Field> fields = new ArrayList<java.lang.reflect.Field>();

        for (java.lang.reflect.Field field: type.getDeclaredFields()) {
            fields.add(field);
        }
        if (type.getSuperclass() != null) {
            fields.addAll(getAllFields(type.getSuperclass()));
        }

        return fields;
    }


}
TOP

Related Classes of com.jengine.orm.model.ModelClassBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.