Package framework.audit

Source Code of framework.audit.AuditDoc

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package framework.audit;

import framework.beans.BaseEntity;
import framework.beans.GenericEntity;
import framework.beans.collaborator.CollaboratorAbstract;
import framework.generic.ClipsServerException;
import framework.generic.HasEntityInfo;
import framework.utils.Converter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.JoinColumn;
import org.jdom.JDOMException;
import reportgen.cores.ejb.annotations.DefineQueryEntity;
import reportgen.cores.ejb.annotations.DefineQueryProperty;

/**
*
* @author vip
*/
public class AuditDoc<GEN extends BaseEntity> {
    private String value;
    private String title;
    private EntityValue oldValues;
    public CollaboratorAbstract collab;
    private Date date;
    private String className;
    private Integer id;
    private Map<String, String> xmlFormat = new HashMap<String, String>();
    private String nameEntity;
    private boolean checked;
    boolean changed;
   
    public AuditDoc(GEN old, CollaboratorAbstract collab) throws ClipsServerException {
        boolean isNew = false;
        if (old == null) {
            isNew = true;
        }
        if (old instanceof GenericEntity && ((GenericEntity)old).getId() == 0) {
            isNew = true;
        }
        //Запомним старые значения
        if (isNew) {
            oldValues = null;
        } else {
            Class aClass = old.getClass();
            if (aClass.isAnnotationPresent(DefineQueryEntity.class)) {
                DefineQueryEntity annotation = (DefineQueryEntity) aClass.getAnnotation(DefineQueryEntity.class);
                nameEntity = annotation.title();
            } else {
                nameEntity = aClass.getSimpleName();
            }

            className = old.getClass().getSimpleName();
            oldValues = getValues(old);
            id = oldValues.id;

        }

        this.collab = collab;
        this.date = new Date();
    }

    private EntityValue getValues(GEN old) throws ClipsServerException {
        EntityValue entityValue = new EntityValue(getValueOfField(old, null));
        HashMap<Field, Method> methodMap = getMethodMap(old == null ? null : old.getClass());
        Set<Entry<Field, Method>> entrySet = methodMap.entrySet();
        for (Entry<Field, Method> entry : entrySet) {
            try {
                Field field = entry.getKey();
                String metaData = xmlFormat.get(field.getName());
                Method method = entry.getValue();
                method.setAccessible(true);
                String valueOfField = getValueOfField(method.invoke(old), metaData);
                entityValue.put(entry.getKey(), valueOfField);
            } catch (IllegalAccessException ex) {
                throw  new RuntimeException(ex);
            } catch (IllegalArgumentException ex) {
                throw  new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                throw  new RuntimeException(ex);
            }
        }
        if (old instanceof GenericEntity) {
            entityValue.id = ((GenericEntity)old).getId();
        }
        return entityValue;
    }
    /**
     * Вызывается при удалении чекапов, передается старая сущность для
     * запоминания старых значений на основе старого значения сущности и метаданных.
     * Вообщето для всех нормальных способов старые значения запоминаются в конструкторе,
     * но в данном случае невозможно невозможно передать метаданные в конструктор,
     * поэтому старые значения формируются здесь.
     * Вызывается таким способом потомучто невозможно передать метаданные в конструктор
     * @param old
     * @param fieldName
     * @param metaData
     */
    public void addFieldFormat(GEN old, String fieldName, String metaData) throws ClipsServerException {
        xmlFormat.put(fieldName, metaData);
        oldValues = getValues(old);
    }

    /**
     * Вызывается при создании/модификации чекапов
     * @param fieldName
     * @param metaData
     */
    public void addFieldFormat(String fieldName, String metaData) {
        xmlFormat.put(fieldName, metaData);
    }

    public Date getDate() {
        return date;
    }

    private void add(String title) {
        value += title + "\n";
    }

    private void setTitle(String title) {
        this.title = title;
    }

    public String getResult() {
        if (changed) {
            return title + "\n" + value;
        } else {
            return null;
        }
    }

    public String getClassName() {
        return className;
    }

    public Integer getId() {
        return id;
    }

    /**
     * Проверяет были ли произведены какие либо изменения в сущности, и формирует
     * строковое значение аудита.
     * @param current
     * @return
     * @throws ClipsServerException
     */
    public boolean check(GEN current) throws ClipsServerException {
        changed = false;
        value = "";
        title = "";
        Class aClass = null;
        if (current != null) {
            aClass = current.getClass();
            className = current.getClass().getSimpleName();
            if (current instanceof GenericEntity) {
                id = ((GenericEntity)current).getId();
            }
            if (aClass.isAnnotationPresent(DefineQueryEntity.class)) {
                DefineQueryEntity annotation = (DefineQueryEntity) aClass.getAnnotation(DefineQueryEntity.class);
                nameEntity = annotation.title();
            } else {
                nameEntity = aClass.getSimpleName();
            }
        }

        HashMap<Field, Method> methodMap = getMethodMap(aClass);

        if (oldValues != null && current == null) {
            //Удаление
            changed = true;
            Set<Entry<Field, String>> entrySet = oldValues.entrySet();
            for (Entry<Field, String> entry : entrySet) {
                Field field = entry.getKey();
                boolean protectedField = (field.getAnnotation(AuditProtectedProperty.class) != null);
                String titleField;
                if (field.getAnnotation(DefineQueryProperty.class) != null) {
                    titleField = field.getAnnotation(DefineQueryProperty.class).title();
                } else {
                    titleField = field.getName();
                }
                if (!protectedField) {
                    add(titleField + " : \"" + entry.getValue() + "\"");
                } else {
                    add(titleField + " : \"*****\"");
                }
            }
            setTitle(Converter.dateToString(date, "dd.MM.yyyy-HH:mm:ss") + " сотрудником " +
                        collab.getClient().getFio() + " удален объект \"" + nameEntity + "\"\n" +
                    oldValues.info +
                    " (ID = " + oldValues.id + ")");
            checked = true;
            return true;
        }
        if (oldValues == null) {
            //Создание
            changed = true;
            Set<Entry<Field, Method>> entrySet = methodMap.entrySet();
            for (Entry<Field, Method> entry : entrySet) {
                try {
                    Field field = entry.getKey();
                    boolean protectedField = (field.getAnnotation(AuditProtectedProperty.class) != null);
                    String metaData = xmlFormat.get(field.getName());
                    Method method = entry.getValue();
                    method.setAccessible(true);
                    String titleField;
                    if (field.getAnnotation(DefineQueryProperty.class) != null) {
                        titleField = field.getAnnotation(DefineQueryProperty.class).title();
                    } else {
                        titleField = field.getName();
                    }
                    if (!protectedField) {
                        add(titleField + " : \"" + getValueOfField(method.invoke(current), metaData) + "\"");
                    } else {
                        add(titleField + " : \"*****\"");
                    }
                } catch (InvocationTargetException ex) {
                    throw new RuntimeException(ex);
                } catch (IllegalArgumentException ex) {
                    throw new RuntimeException(ex);
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                }


            }
            String t = Converter.dateToString(date, "dd.MM.yyyy-HH:mm:ss") + " сотрудником " +
                        collab.getClient().getFio() + " создан объект \"" + nameEntity + "\"\n" +
                    getValueOfField(current, null);
            if (current instanceof GenericEntity) {
                t = t + " (ID = " + ((GenericEntity)current).getId() + ")";
            }
            setTitle(t);
        } else {
            //Изменение
            Set<Entry<Field, String>> entrySet = oldValues.entrySet();
            for (Entry<Field, String> entry : entrySet) {
                try {
                    Field field = entry.getKey();
                    boolean protectedField = (field.getAnnotation(AuditProtectedProperty.class) != null);
                    Method method = methodMap.get(field);
                    method.setAccessible(true);
                    String titleField;
                    if (field.getAnnotation(DefineQueryProperty.class) != null) {
                        titleField = field.getAnnotation(DefineQueryProperty.class).title();
                    } else {
                        titleField = field.getName();
                    }
                    String metaData = xmlFormat.get(field.getName());
                    String oldFieldValue = entry.getValue();
                    Object newField = method.invoke(current);
                    String currentfieldValue = getValueOfField(newField, metaData);
                    if ((oldFieldValue == null) ? (currentfieldValue != null) : !oldFieldValue.equals(currentfieldValue)
                            || metaData != null) {
                        //Поле было изменено
                        if (metaData != null) {
                            oldFieldValue = null;
                        }
                        if (!protectedField) {
                            if (oldFieldValue == null) {
                                add(titleField + " : \"" + currentfieldValue + "\"");
                            } else {
                                add(titleField + " : \""+ oldFieldValue + "\" --> \"" + currentfieldValue + "\"");
                            }
                        } else {
                            if (oldFieldValue == null) {
                                add(titleField + " : \"*****\"");
                            } else {
                                add(titleField + " : \"*****\" --> \"*****\"");
                            }
                        }
                        changed = true;
                    }
                } catch (IllegalAccessException ex) {
                    throw  new RuntimeException(ex);
                } catch (IllegalArgumentException ex) {
                    throw  new RuntimeException(ex);
                } catch (InvocationTargetException ex) {
                    throw  new RuntimeException(ex);
                }
            }
            if (changed) {
                String t = Converter.dateToString(date, "dd.MM.yyyy-HH:mm:ss") + " сотрудником " +
                        collab.getClient().getFio() + " изменен объект \"" + nameEntity + "\"\n" +
                    getValueOfField(current, null);
                if (current instanceof GenericEntity) {
                    t = t + " (ID = " + ((GenericEntity)current).getId() + ")";
                }
                setTitle(t);
            }
        }
        checked = true;
        return changed;
    }

    private HashMap<Field, Method> getMethodMap(Class aClass) throws ClipsServerException{
        /*
         * Выбираем из класса и всех его предков все поля и ищем для них геттеры по имени.
         * исключая поля коллекции
         */
        HashMap<Field, Method> methodMap = new HashMap<Field, Method>();
        if (aClass == null) {
            return methodMap;
        }
        do {
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                if (field.getAnnotation(Column.class) == null
                        && field.getAnnotation(JoinColumn.class) == null) {
                    continue;
                }
                if (Collection.class.isAssignableFrom(field.getType())) {
                    continue;
                }
                Method method = null;
                String methodName = "get" + Converter.firstUpper(field.getName(), false);
                try {
                    method = aClass.getMethod(methodName);
                } catch (NoSuchMethodException ex) {
                    //Not found
                } catch (SecurityException ex) {
                    //Blocked
                }
                if (method == null) {
                    String alterName = "is" + Converter.firstUpper(field.getName(), false);
                    try {
                        method = aClass.getMethod(alterName);
                    } catch (NoSuchMethodException ex) {
                        throw new ClipsServerException("Несоответствие методов в сущности", ex);
                    } catch (SecurityException ex) {
                        throw new ClipsServerException("Метод в сущности заблокирован", ex);
                    }
                }
                if (!methodMap.containsKey(field) && method != null) {
                    methodMap.put(field, method);
                }
            }
            aClass = aClass.getSuperclass();
        } while (!aClass.equals(Object.class));
        return methodMap;
    }

    private String getValueOfField(Object field, String metaData) throws ClipsServerException {
        String valueField;
        if (field == null) {
            valueField = "-";
        } else if (field instanceof HasEntityInfo){
            valueField = ((HasEntityInfo)field).getInfo();
        } else if (field instanceof GenericEntity){
            valueField = String.valueOf(((GenericEntity)field).getId());
        } else if (field instanceof Date){
            valueField = Converter.dateToString((Date)field, "dd.MM.yyyy");
        } else if (field instanceof byte[]){
            valueField = Converter.hexDump((byte[]) field);
        } else if (metaData != null) {
            try {
                if (getClassName().equals("Checkup")) {
                    valueField = Parser.xmlCheckupToUserView(field.toString(), metaData);
                } else if (getClassName().equals("Certificate")) {
                    valueField = Parser.xmlCertificateToUserView(field.toString(), metaData);
                } else if (getClassName().equals("Collaborator")) {
                    valueField = Parser.xmlCollaboratorToUserView(field.toString(), metaData);
                } else {
                    throw new ClipsServerException("Неизвестный формат XML");
                }
            } catch (JDOMException ex) {
                throw new ClipsServerException("Невалидная XML");
            }
        } else {
            valueField = field.toString();
        }
        return valueField;
    }


    private class EntityValue extends HashMap<Field, String> {
        String info;
        int id;

        public EntityValue(String info) {
            this.info = info;
        }

    }

    public boolean isChecked() {
        return checked;
    }

}
TOP

Related Classes of framework.audit.AuditDoc

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.