Return to Snippet

Revision: 67116
at August 13, 2014 18:43 by jasonhue


Initial Code
package net.javabeat.spring.audit;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.hibernate.SessionFactory;
import org.hibernate.metadata.ClassMetadata;
import org.infinispan.commons.api.BasicCache;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import net.javabeat.spring.cache.LocalCacheManager;
import net.javabeat.spring.model.AuditTable;
import net.javabeat.spring.service.AuditFlowService;
import net.javabeat.spring.service.AuditTableService;
import net.javabeat.spring.util.JsonUtils;

@Aspect
@Component("auditTrailAspect")
@Configurable
@EnableAspectJAutoProxy
public class AuditTrailAspect {
	
	@Autowired
	private AuditTableService auditTableService;
	
	@Resource
    private SessionFactory sessionFactory;
	
	@Autowired private AuditFlowService auditFlowService;
	
	
	private static BasicCache<Object, Object> caches = LocalCacheManager.getCache();
	
	@Before("execution(public * net.javabeat.spring.dao..*.genericUpdate(..)) && args(bean)")
	public void traceBeforeUpdate(JoinPoint joinPoint, Object bean) {
		try {
			Advised advised = (Advised) joinPoint.getThis();
		    Class<?> cls = advised.getTargetSource().getTargetClass();
		    ClassMetadata metadata = sessionFactory.getClassMetadata(bean.getClass());
			String entityPrimaryKey = metadata.getIdentifierPropertyName();
			JsonUtils utils = new JsonUtils();
			int typeid = Integer.parseInt(utils.getProperty(bean, entityPrimaryKey)) ;

			Object service  = advised.getTargetSource().getTarget();
			Method findMethod = cls.getSuperclass().getMethod("genericGetById", new Class[] {int.class});

	        Object oldValue = findMethod.invoke(service, typeid);
	        
	        String key = bean.toString() + typeid;
	        caches.put(key, oldValue);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
      
	}
	
	
	@AfterReturning("execution(public * net.javabeat.spring.dao..*.genericUpdate(..)) && args(bean)")
	public void traceAfterUpdate(JoinPoint joinPoint, Object bean) {
		String key = null;
		try {
			Advised advised = (Advised) joinPoint.getThis();
		    Class<?> cls = advised.getTargetSource().getTargetClass();
		    
		    JsonUtils utils = new JsonUtils();
		    ClassMetadata metadata = sessionFactory.getClassMetadata(bean.getClass());
		    String entityPrimaryKey = metadata.getIdentifierPropertyName();
			int typeid = Integer.parseInt(utils.getProperty(bean,entityPrimaryKey)) ;
		    key = bean.toString() +  typeid;
		    Object oldValue =  (caches.get(key) == null ? null : caches.get(key));
		    
		    ObjectMapper mapper = new ObjectMapper();
			ChangeSetRecord changeSetRecord = new ChangeSetRecord ();
			changeSetRecord =  compareObjects(oldValue, bean);
			
			if (changeSetRecord != null){
				AuditTable auditRecord = new AuditTable();
				auditRecord.setEntityname(bean.getClass().getSimpleName());
				auditRecord.setAction("Update");
				auditRecord.setChangeset(mapper.writeValueAsString( changeSetRecord ) );
				auditTableService.createAudit(auditRecord);
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private class ChangeSetRecord extends HashMap<String, List<String>> {
        public void put(String key,String index) {
            List<String> current = get(key);
            if (current == null) {
                current = new ArrayList<String>();
                super.put(key, current);
            }
            current.add(index);
        }
    }
	
	public ChangeSetRecord compareObjects(Object oldObject, Object newObject) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        BeanMap map = new BeanMap(oldObject);
        PropertyUtilsBean propUtils = new PropertyUtilsBean();
        ChangeSetRecord changeSetRecord = new ChangeSetRecord();
        
        for (Object propNameObject : map.keySet()) {
            String propertyName = (String) propNameObject;
            Object property1 = propUtils.getProperty(oldObject, propertyName);
            Object property2 = propUtils.getProperty(newObject, propertyName);
            if (property1.equals(property2)) {
                System.out.println("  " + propertyName + " is equal");
            } else {
                System.out.println("> " + propertyName + " is different (oldValue=\"" + property1 + "\", newValue=\"" + property2 + "\")");
                
                
                changeSetRecord.put(propertyName, (property1 == null ? "" : property1.toString()));
                changeSetRecord.put(propertyName, (property2 == null ? "" : property2.toString()));
            }
        }
        return changeSetRecord;
    }

}

Initial URL


Initial Description
Audit Trail

Initial Title
Spring AOP Audit Trail

Initial Tags


Initial Language
Java