All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ctp.cdi.query.audit.TimestampsProvider Maven / Gradle / Ivy

The newest version!
package com.ctp.cdi.query.audit;

import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.jboss.solder.properties.Property;
import org.jboss.solder.properties.query.AnnotatedPropertyCriteria;
import org.jboss.solder.properties.query.PropertyQueries;
import org.jboss.solder.properties.query.PropertyQuery;

/**
 * Set timestamps on marked properties.
 */
class TimestampsProvider extends AuditProvider {

    @Override
    public void prePersist(Object entity) {
        updateTimestamps(entity, true);
    }

    @Override
    public void preUpdate(Object entity) {
        updateTimestamps(entity, false);
    }
    
    private void updateTimestamps(Object entity, boolean create) {
        long systime = System.currentTimeMillis();
        List> properties = new LinkedList>();
        PropertyQuery query = PropertyQueries.createQuery(entity.getClass())
                .addCriteria(new AnnotatedPropertyCriteria(ModifiedOn.class));
        properties.addAll(query.getWritableResultList());
        if (create) {
            query = PropertyQueries.createQuery(entity.getClass())
                    .addCriteria(new AnnotatedPropertyCriteria(CreatedOn.class));
            properties.addAll(query.getWritableResultList());
        }
        for (Property property : properties) {
            setProperty(entity, property, systime, create);
        }
    }
    
    private void setProperty(Object entity, Property property, long systime, boolean create) {
        try {
            if (!isCorrectContext(property, create)) {
                return;
            }
            Object now = now(property.getJavaClass(), systime);
            property.setValue(entity, now);
            log.debugv("Updated property {0} with {1}", propertyName(entity, property), now);
        } catch (Exception e) {
            String message = "Failed to set property " + propertyName(entity, property) + ", is this a temporal type?";
            throw new AuditPropertyException(message, e);
        }
    }

    private boolean isCorrectContext(Property property, boolean create) {
        if (create && property.getAnnotatedElement().isAnnotationPresent(ModifiedOn.class)) {
            ModifiedOn annotation = property.getAnnotatedElement().getAnnotation(ModifiedOn.class);
            if (!annotation.onCreate()) {
                return false;
            }
        }
        return true;
    }

    private Object now(Class field, long systime) throws Exception {
        if (isCalendarClass(field)) {
            Calendar cal = Calendar.getInstance();
            cal.setTimeInMillis(systime);
            return cal;
        } else if (isDateClass(field)) {
            return field.getConstructor(Long.TYPE).newInstance(systime);
        }
        throw new IllegalArgumentException("Annotated field is not a date class: " + field);
    }

    private boolean isCalendarClass(Class field) {
        return Calendar.class.isAssignableFrom(field);
    }

    private boolean isDateClass(Class field) {
        return Date.class.isAssignableFrom(field);
    }

}