Java tutorial
/* * Copyright 2009 Denys Pavlov, Igor Azarnyi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.yes.cart.payment.persistence.service.impl; import org.apache.commons.lang.StringUtils; import org.hibernate.EmptyInterceptor; import org.hibernate.Hibernate; import org.hibernate.type.Type; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.yes.cart.payment.persistence.entity.Auditable; import java.io.Serializable; import java.util.*; /** * Audit interceptor for entities. * User: Igor Azarny iazarny@yahoo.com * Date: 07-May-2011 * Time: 10:22:53 */ public class AuditInterceptor extends EmptyInterceptor { private final Logger LOG = LoggerFactory.getLogger("AUDIT"); private Map<String, Set<String>> prohibitedFields = new HashMap<String, Set<String>>(); private String getUserName() { if (SecurityContextHolder.getContext() != null) { final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getPrincipal() instanceof User) { return ((User) auth.getPrincipal()).getUsername(); } } return "anonymous"; } /** * {@inheritDoc} */ @Override public boolean onSave(final Object entity, final Serializable id, final Object[] state, final String[] propertyNames, final Type[] types) { if (entity instanceof Auditable) { final Auditable auditable = ((Auditable) entity); final Date date = new Date(); final String userName = getUserName(); if (StringUtils.isBlank(auditable.getGuid())) { final String guid = UUID.randomUUID().toString(); setValue(state, propertyNames, "guid", guid); auditable.setGuid(guid); } setValue(state, propertyNames, "createdBy", userName); auditable.setCreatedBy(userName); setValue(state, propertyNames, "createdTimestamp", date); auditable.setCreatedTimestamp(date); setValue(state, propertyNames, "updatedBy", userName); auditable.setUpdatedBy(userName); setValue(state, propertyNames, "updatedTimestamp", date); auditable.setUpdatedTimestamp(date); logOperation("SAVE", (Auditable) entity, userName, id, state, propertyNames, types); } return super.onSave(entity, id, state, propertyNames, types); } /** * {@inheritDoc} */ @Override public void onDelete(final Object entity, final Serializable id, final Object[] state, final String[] propertyNames, final Type[] types) { if (entity instanceof Auditable) { final String userName = getUserName(); logOperation("DELETE", (Auditable) entity, userName, id, state, propertyNames, types); } super.onDelete(entity, id, state, propertyNames, types); } /** * {@inheritDoc} */ @Override public boolean onFlushDirty(final Object entity, final Serializable id, final Object[] currentState, final Object[] previousState, final String[] propertyNames, final Type[] types) { if (entity instanceof Auditable) { final Auditable auditable = (Auditable) entity; final Date date = new Date(); final String userName = getUserName(); if (auditable.getCreatedTimestamp() == null) { setValue(currentState, propertyNames, "createdBy", userName); auditable.setCreatedBy(userName); setValue(currentState, propertyNames, "createdTimestamp", date); auditable.setCreatedTimestamp(date); } if (StringUtils.isBlank(((Auditable) entity).getGuid())) { final String guid = UUID.randomUUID().toString(); setValue(currentState, propertyNames, "guid", guid); auditable.setGuid(guid); } setValue(currentState, propertyNames, "updatedBy", userName); auditable.setUpdatedBy(userName); setValue(currentState, propertyNames, "updatedTimestamp", date); auditable.setUpdatedTimestamp(date); logOperation("FLUSH-PREV", (Auditable) entity, userName, id, previousState, propertyNames, types); logOperation("FLUSH-CURR", (Auditable) entity, userName, id, currentState, propertyNames, types); } return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types); } private void logOperation(final String operation, final Auditable entity, final String user, final Serializable id, final Object[] state, final String[] propertyNames, final Type[] types) { if (LOG.isTraceEnabled()) { final String className = entity.getClass().getSimpleName(); final Set<String> prohibited = prohibitedFields.get(className); final StringBuilder line = new StringBuilder(); line.append(operation); line.append(",\""); line.append(className); line.append("\",\""); if (id == null || (id instanceof Number && ((Number) id).longValue() <= 0L)) { line.append("N/A"); } else { line.append(id); } line.append("\",\""); line.append(user); line.append("\",\""); line.append(entity.getGuid()); line.append('"'); if (state != null) { for (int i = 0; i < propertyNames.length; i++) { final Type type = types[i]; if (type.isCollectionType()) { continue; // skip collections } final String prop = propertyNames[i]; final Object value = state[i]; line.append(",\""); line.append(prop); line.append(":"); if (prohibited == null || !prohibited.contains(prop)) { if (type.isEntityType()) { if (Hibernate.isInitialized(value)) { line.append(value); } else { line.append("lazy"); } } else { if (value instanceof String) { line.append(((String) value).replace('"', '\'')); } else { line.append(value); } } } else { line.append("[prohibited]"); } line.append("\""); } } LOG.trace(line.toString()); } } private void setValue(final Object[] currentState, final String[] propertyNames, final String propertyToSet, final Object value) { int index = Arrays.asList(propertyNames).indexOf(propertyToSet); if (index > -1) { currentState[index] = value; } } /** * Set field that should not output to audit log due to security reasons. * * @param prohibitedFields class to fields map */ public void setProhibitedFields(final Map<String, Set<String>> prohibitedFields) { if (prohibitedFields != null) { this.prohibitedFields.putAll(prohibitedFields); } } }