Search in sources :

Example 1 with GlobalTrackingLogLine

use of com.axelor.apps.base.db.GlobalTrackingLogLine in project axelor-open-suite by axelor.

the class GlobalAuditInterceptor method onSave.

@SuppressWarnings("unchecked")
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
    if (!super.onSave(entity, id, state, propertyNames, types) || Arrays.asList(BACKLISTED_CLASSES).contains(entity.getClass()) || !(entity instanceof AuditableModel)) {
        return false;
    }
    GlobalTrackingLog log = globalTracker.get().addLog((AuditableModel) entity, GlobalTrackingLogRepository.TYPE_CREATE);
    for (int i = 0; i < propertyNames.length; i++) {
        if (state[i] == null || CREATED_ON.equals(propertyNames[i]) || CREATED_BY.equals(propertyNames[i])) {
            continue;
        }
        GlobalTrackingLogLine logLine = new GlobalTrackingLogLine();
        logLine.setMetaFieldName(propertyNames[i]);
        if (state[i] instanceof AuditableModel) {
            logLine.setNewValue(String.valueOf(((AuditableModel) state[i]).getId()));
        } else if (state[i] instanceof Collection) {
            String newVal = "";
            if (CollectionUtils.isNotEmpty((Collection<Object>) state[i])) {
                newVal = String.format("[%s]", ((Collection<AuditableModel>) state[i]).stream().map(AuditableModel::getId).map(String::valueOf).collect(Collectors.joining(", ")));
            }
            logLine.setNewValue(newVal);
        } else {
            logLine.setNewValue(String.valueOf(Optional.ofNullable(state[i]).orElse("")));
        }
        log.addGlobalTrackingLogLineListItem(logLine);
    }
    if (log != null) {
        globalTracker.get().addLog(log);
    }
    return true;
}
Also used : GlobalTrackingLog(com.axelor.apps.base.db.GlobalTrackingLog) GlobalTrackingLogLine(com.axelor.apps.base.db.GlobalTrackingLogLine) Collection(java.util.Collection) AuditableModel(com.axelor.auth.db.AuditableModel)

Example 2 with GlobalTrackingLogLine

use of com.axelor.apps.base.db.GlobalTrackingLogLine in project axelor-open-suite by axelor.

the class GlobalAuditInterceptor method onFlushDirty.

@SuppressWarnings("unchecked")
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
    if (!super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types) || Arrays.asList(BACKLISTED_CLASSES).contains(entity.getClass()) || !(entity instanceof AuditableModel)) {
        return false;
    }
    if (globalTracker.get() == null) {
        globalTracker.set(new GlobalAuditTracker());
        globalTracker.get().init();
    }
    GlobalTrackingLog log = globalTracker.get().addLog((AuditableModel) entity, GlobalTrackingLogRepository.TYPE_UPDATE);
    for (int i = 0; i < propertyNames.length; i++) {
        if (Objects.equals(currentState[i], previousState[i]) || UPDATED_ON.equals(propertyNames[i]) || UPDATED_BY.equals(propertyNames[i])) {
            continue;
        }
        GlobalTrackingLogLine logLine = new GlobalTrackingLogLine();
        logLine.setMetaFieldName(propertyNames[i]);
        if (currentState[i] instanceof AuditableModel || previousState[i] instanceof AuditableModel) {
            logLine.setNewValue(currentState[i] instanceof AuditableModel ? String.valueOf(((AuditableModel) currentState[i]).getId()) : "");
            logLine.setPreviousValue(previousState[i] instanceof AuditableModel ? String.valueOf(((AuditableModel) previousState[i]).getId()) : "");
        } else if (currentState[i] instanceof Collection || previousState[i] instanceof Collection) {
            String prevVal = "";
            String newVal = "";
            if (CollectionUtils.isNotEmpty((Collection<Object>) previousState[i])) {
                prevVal = String.format("[%s]", ((Collection<AuditableModel>) previousState[i]).stream().map(AuditableModel::getId).map(String::valueOf).collect(Collectors.joining(", ")));
            }
            if (CollectionUtils.isNotEmpty((Collection<Object>) currentState[i])) {
                newVal = String.format("[%s]", ((Collection<AuditableModel>) currentState[i]).stream().map(AuditableModel::getId).map(String::valueOf).collect(Collectors.joining(", ")));
            }
            logLine.setPreviousValue(prevVal);
            logLine.setNewValue(newVal);
        } else {
            logLine.setNewValue(String.valueOf(Optional.ofNullable(currentState[i]).orElse("")));
            logLine.setPreviousValue(String.valueOf(Optional.ofNullable(previousState[i]).orElse("")));
        }
        log.addGlobalTrackingLogLineListItem(logLine);
    }
    return true;
}
Also used : GlobalTrackingLog(com.axelor.apps.base.db.GlobalTrackingLog) GlobalTrackingLogLine(com.axelor.apps.base.db.GlobalTrackingLogLine) Collection(java.util.Collection) AuditableModel(com.axelor.auth.db.AuditableModel)

Example 3 with GlobalTrackingLogLine

use of com.axelor.apps.base.db.GlobalTrackingLogLine in project axelor-open-suite by axelor.

the class GlobalAuditTracker method addCollectionModification.

@SuppressWarnings("unchecked")
protected void addCollectionModification(Object collection, Long id) {
    if (collection instanceof AbstractPersistentCollection) {
        AbstractPersistentCollection newValues = null;
        Collection<AuditableModel> oldValues = null;
        if (collection instanceof PersistentSet) {
            // MANY-TO-MANY
            newValues = (PersistentSet) collection;
            oldValues = (Collection<AuditableModel>) ((Map<?, ?>) newValues.getStoredSnapshot()).keySet();
        } else if (collection instanceof PersistentBag) {
            // ONE-TO-MANY
            newValues = (PersistentBag) collection;
            oldValues = (Collection<AuditableModel>) newValues.getStoredSnapshot();
        }
        if (newValues == null) {
            return;
        }
        Object owner = newValues.getOwner();
        if (owner == null || Arrays.asList(GlobalAuditInterceptor.BACKLISTED_CLASSES).contains(owner.getClass()) || !(owner instanceof AuditableModel)) {
            return;
        }
        String fieldName = newValues.getRole().replace(owner.getClass().getCanonicalName() + ".", "");
        GlobalTrackingLog log = LOGS.get().stream().filter(l -> l.getRelatedId().equals(id) && l.getMetaModelName().equals(owner.getClass().getSimpleName())).findFirst().orElse(addLog((AuditableModel) owner, GlobalTrackingLogRepository.TYPE_UPDATE));
        List<Long> previousIdList = new ArrayList<>();
        List<Long> newIdList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(oldValues)) {
            for (AuditableModel oldValue : oldValues) {
                if (oldValue != null) {
                    previousIdList.add(oldValue.getId());
                }
            }
        }
        for (AuditableModel newValue : (Collection<AuditableModel>) newValues) {
            if (newValue != null) {
                newIdList.add(newValue.getId());
            }
        }
        GlobalTrackingLogLine line = log.getGlobalTrackingLogLineList().stream().filter(l -> l.getMetaFieldName().equals(fieldName)).findFirst().orElse(null);
        if (line == null) {
            line = new GlobalTrackingLogLine();
            line.setMetaFieldName(fieldName);
            line.setGlobalTrackingLog(log);
            line.setPreviousValue(String.format("[%s]", previousIdList.stream().map(String::valueOf).collect(Collectors.joining(", "))));
            log.addGlobalTrackingLogLineListItem(line);
        }
        line.setNewValue(String.format("[%s]", newIdList.stream().map(String::valueOf).collect(Collectors.joining(", "))));
    }
}
Also used : GlobalTrackingLog(com.axelor.apps.base.db.GlobalTrackingLog) ArrayList(java.util.ArrayList) GlobalTrackingLogLine(com.axelor.apps.base.db.GlobalTrackingLogLine) AuditableModel(com.axelor.auth.db.AuditableModel) PersistentSet(org.hibernate.collection.internal.PersistentSet) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) PersistentBag(org.hibernate.collection.internal.PersistentBag) Collection(java.util.Collection) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with GlobalTrackingLogLine

use of com.axelor.apps.base.db.GlobalTrackingLogLine in project axelor-open-suite by axelor.

the class GlobalAuditTracker method onComplete.

/**
 * This method should be called from {@link
 * AuditInterceptor#beforeTransactionCompletion(Transaction)} method to finish change recording.
 *
 * @param tx the transaction in which the change tracking is being done
 * @param user the session user
 */
public void onComplete(Transaction tx, User user) {
    List<GlobalTrackingLog> logList = LOGS.get();
    LOGS.remove();
    if (CollectionUtils.isEmpty(logList)) {
        return;
    }
    MetaModelRepository modelRepo = Beans.get(MetaModelRepository.class);
    MetaFieldRepository fieldRepo = Beans.get(MetaFieldRepository.class);
    GlobalTrackingLogRepository logRepo = Beans.get(GlobalTrackingLogRepository.class);
    GlobalTrackingConfigurationLineRepository configLineRepo = Beans.get(GlobalTrackingConfigurationLineRepository.class);
    GlobalTrackingConfigurationLine configLine;
    List<GlobalTrackingConfigurationLine> configLineList;
    ScriptBindings bindings;
    for (GlobalTrackingLog log : logList) {
        configLineList = configLineRepo.all().filter("self.metaModel.name = ?", log.getMetaModelName()).fetch();
        if (configLineList.isEmpty()) {
            continue;
        }
        log.setMetaModel(modelRepo.findByName(log.getMetaModelName()));
        List<GlobalTrackingLogLine> logLinesToSave = new ArrayList<>();
        if ((CollectionUtils.isNotEmpty(log.getGlobalTrackingLogLineList()))) {
            try {
                bindings = new ScriptBindings(this.getContext(JPA.find((Class<Model>) Class.forName(log.getMetaModel().getFullName()), log.getRelatedId())));
            } catch (Exception e) {
                continue;
            }
            for (GlobalTrackingLogLine line : log.getGlobalTrackingLogLineList()) {
                configLine = configLineList.stream().filter(l -> l.getMetaField().getName().equals(line.getMetaFieldName())).findFirst().orElse(null);
                if (configLine == null || !this.canTrack(configLine, log.getTypeSelect()) || (!Strings.isNullOrEmpty(configLine.getTrackingCondition()) && !Boolean.TRUE.equals(new GroovyScriptHelper(bindings).eval(configLine.getTrackingCondition())))) {
                    continue;
                }
                line.setMetaField(fieldRepo.all().filter("self.metaModel.id = ? AND self.name = ?", log.getMetaModel().getId(), line.getMetaFieldName()).fetchOne());
                logLinesToSave.add(line);
            }
        }
        if (!logLinesToSave.isEmpty() || (GlobalTrackingLogRepository.TYPE_DELETE == log.getTypeSelect() && configLineList.stream().anyMatch(l -> Boolean.TRUE.equals(l.getTrackDeletion())))) {
            log.getGlobalTrackingLogLineList().stream().forEach(l -> l.setGlobalTrackingLog(null));
            logLinesToSave.stream().forEach(l -> l.setGlobalTrackingLog(log));
            log.setUser(user);
            logRepo.save(log);
        }
    }
}
Also used : GlobalTrackingConfigurationLine(com.axelor.apps.base.db.GlobalTrackingConfigurationLine) MetaModelRepository(com.axelor.meta.db.repo.MetaModelRepository) Arrays(java.util.Arrays) LocalDateTime(java.time.LocalDateTime) GroovyScriptHelper(com.axelor.script.GroovyScriptHelper) HashMap(java.util.HashMap) ScriptBindings(com.axelor.script.ScriptBindings) PersistentSet(org.hibernate.collection.internal.PersistentSet) ArrayList(java.util.ArrayList) Transaction(org.hibernate.Transaction) Strings(com.google.common.base.Strings) Introspector(java.beans.Introspector) GlobalTrackingLog(com.axelor.apps.base.db.GlobalTrackingLog) CollectionUtils(org.apache.commons.collections.CollectionUtils) AuditInterceptor(com.axelor.auth.AuditInterceptor) BeanInfo(java.beans.BeanInfo) Map(java.util.Map) GlobalTrackingLogRepository(com.axelor.apps.base.db.repo.GlobalTrackingLogRepository) Method(java.lang.reflect.Method) JPA(com.axelor.db.JPA) PersistentBag(org.hibernate.collection.internal.PersistentBag) Model(com.axelor.db.Model) Collection(java.util.Collection) GlobalTrackingLogLine(com.axelor.apps.base.db.GlobalTrackingLogLine) Collectors(java.util.stream.Collectors) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) GlobalTrackingConfigurationLineRepository(com.axelor.apps.base.db.repo.GlobalTrackingConfigurationLineRepository) List(java.util.List) Beans(com.axelor.inject.Beans) MetaFieldRepository(com.axelor.meta.db.repo.MetaFieldRepository) PropertyDescriptor(java.beans.PropertyDescriptor) AbstractPersistentCollection(org.hibernate.collection.internal.AbstractPersistentCollection) AuditableModel(com.axelor.auth.db.AuditableModel) AuthUtils(com.axelor.auth.AuthUtils) User(com.axelor.auth.db.User) MetaModelRepository(com.axelor.meta.db.repo.MetaModelRepository) GlobalTrackingLog(com.axelor.apps.base.db.GlobalTrackingLog) GlobalTrackingConfigurationLineRepository(com.axelor.apps.base.db.repo.GlobalTrackingConfigurationLineRepository) ArrayList(java.util.ArrayList) GlobalTrackingLogLine(com.axelor.apps.base.db.GlobalTrackingLogLine) MetaFieldRepository(com.axelor.meta.db.repo.MetaFieldRepository) GroovyScriptHelper(com.axelor.script.GroovyScriptHelper) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) GlobalTrackingLogRepository(com.axelor.apps.base.db.repo.GlobalTrackingLogRepository) GlobalTrackingConfigurationLine(com.axelor.apps.base.db.GlobalTrackingConfigurationLine) ScriptBindings(com.axelor.script.ScriptBindings)

Aggregations

GlobalTrackingLog (com.axelor.apps.base.db.GlobalTrackingLog)4 GlobalTrackingLogLine (com.axelor.apps.base.db.GlobalTrackingLogLine)4 AuditableModel (com.axelor.auth.db.AuditableModel)4 Collection (java.util.Collection)4 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 AbstractPersistentCollection (org.hibernate.collection.internal.AbstractPersistentCollection)2 PersistentBag (org.hibernate.collection.internal.PersistentBag)2 PersistentSet (org.hibernate.collection.internal.PersistentSet)2 GlobalTrackingConfigurationLine (com.axelor.apps.base.db.GlobalTrackingConfigurationLine)1 GlobalTrackingConfigurationLineRepository (com.axelor.apps.base.db.repo.GlobalTrackingConfigurationLineRepository)1 GlobalTrackingLogRepository (com.axelor.apps.base.db.repo.GlobalTrackingLogRepository)1 AuditInterceptor (com.axelor.auth.AuditInterceptor)1 AuthUtils (com.axelor.auth.AuthUtils)1 User (com.axelor.auth.db.User)1 JPA (com.axelor.db.JPA)1 Model (com.axelor.db.Model)1 Beans (com.axelor.inject.Beans)1 MetaFieldRepository (com.axelor.meta.db.repo.MetaFieldRepository)1