001 package com.basilv.examples.hibernate;
002
003 import java.io.Serializable;
004
005 import org.hibernate.EmptyInterceptor;
006 import org.hibernate.type.Type;
007
008 /**
009 * AuditInterceptor is used to populate the audit fields on onUpdate and onSave events.
010 *
011 */
012 public class AuditInterceptor extends EmptyInterceptor
013 {
014
015 private static ThreadLocal<String> userPerThread = new ThreadLocal<String>();
016
017 /**
018 * Store the user for the current thread.
019 * @param user Cannot be null or empty.
020 */
021 public static void setUserForCurrentThread(String user) {
022 userPerThread.set(user);
023 }
024
025 /**
026 * Get the user for the current thread.
027 * (Used primarily for testing).
028 * @return the current user.
029 */
030 public static String getUserForCurrentThread() {
031 return userPerThread.get();
032 }
033
034 @Override public boolean onFlushDirty(Object entity,
035 Serializable id, Object[] currentState,
036 Object[] previousState, String[] propertyNames,
037 Type[] types) {
038
039 boolean changed = false;
040
041 if (entity instanceof Auditable) {
042 changed = updateAuditable(currentState, propertyNames);
043 }
044 return changed;
045 }
046
047 @Override public boolean onSave(Object entity,
048 Serializable id, Object[] currentState,
049 String[] propertyNames, Type[] types) {
050
051 boolean changed = false;
052
053 if (entity instanceof Auditable) {
054 changed = updateAuditable(currentState, propertyNames);
055 }
056 return changed;
057
058 }
059
060 private boolean updateAuditable(Object[] currentState,
061 String[] propertyNames) {
062 boolean changed = false;
063 for (int i = 0; i < propertyNames.length; i++) {
064 if ("createUserId".equals(propertyNames[i])) {
065 if (currentState[i] == null) {
066 currentState[i] = userPerThread.get();
067 changed = true;
068 }
069 }
070 if ("updateUserId".equals(propertyNames[i])) {
071 currentState[i] = userPerThread.get();
072 changed = true;
073 }
074 }
075 return changed;
076 }
077
078 }