use of org.hibernate.envers.Audited in project hibernate-orm by hibernate.
the class ComponentAuditedPropertiesReader method checkAudited.
@Override
protected boolean checkAudited(XProperty property, PropertyAuditingData propertyData, String propertyName, Audited allClassAudited, String modifiedFlagSuffix) {
// Checking if this property is explicitly audited or if all properties are.
final Audited aud = property.getAnnotation(Audited.class);
if (aud != null) {
propertyData.setStore(aud.modStore());
propertyData.setRelationTargetAuditMode(aud.targetAuditMode());
propertyData.setUsingModifiedFlag(checkUsingModifiedFlag(aud));
if (aud.modifiedColumnName() != null && !"".equals(aud.modifiedColumnName())) {
propertyData.setModifiedFlagName(aud.modifiedColumnName());
} else {
propertyData.setModifiedFlagName(MetadataTools.getModifiedFlagPropertyName(propertyName, modifiedFlagSuffix));
}
} else {
propertyData.setStore(ModificationStore.FULL);
}
return true;
}
use of org.hibernate.envers.Audited in project hibernate-orm by hibernate.
the class RevisionInfoConfiguration method configure.
public RevisionInfoConfigurationResult configure(MetadataImplementor metadata, ReflectionManager reflectionManager) {
boolean revisionEntityFound = false;
RevisionInfoGenerator revisionInfoGenerator = null;
Class<?> revisionInfoClass = null;
for (PersistentClass persistentClass : metadata.getEntityBindings()) {
// Ensure we're in POJO, not dynamic model, mapping.
if (persistentClass.getClassName() != null) {
XClass clazz;
try {
clazz = reflectionManager.classForName(persistentClass.getClassName());
} catch (ClassLoadingException e) {
throw new MappingException(e);
}
final RevisionEntity revisionEntity = clazz.getAnnotation(RevisionEntity.class);
if (revisionEntity != null) {
if (revisionEntityFound) {
throw new MappingException("Only one entity may be annotated with @RevisionEntity!");
}
// Checking if custom revision entity isn't audited
if (clazz.getAnnotation(Audited.class) != null) {
throw new MappingException("An entity annotated with @RevisionEntity cannot be audited!");
}
revisionEntityFound = true;
final MutableBoolean revisionNumberFound = new MutableBoolean();
final MutableBoolean revisionTimestampFound = new MutableBoolean();
final MutableBoolean modifiedEntityNamesFound = new MutableBoolean();
searchForRevisionInfoCfg(clazz, reflectionManager, revisionNumberFound, revisionTimestampFound, modifiedEntityNamesFound);
if (!revisionNumberFound.isSet()) {
throw new MappingException("An entity annotated with @RevisionEntity must have a field annotated " + "with @RevisionNumber!");
}
if (!revisionTimestampFound.isSet()) {
throw new MappingException("An entity annotated with @RevisionEntity must have a field annotated " + "with @RevisionTimestamp!");
}
revisionInfoEntityName = persistentClass.getEntityName();
revisionInfoClass = persistentClass.getMappedClass();
final Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass(revisionEntity.value());
revisionInfoTimestampType = persistentClass.getProperty(revisionInfoTimestampData.getName()).getType();
if (globalCfg.isTrackEntitiesChangedInRevision() || (globalCfg.isUseRevisionEntityWithNativeId() && DefaultTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(revisionInfoClass)) || (!globalCfg.isUseRevisionEntityWithNativeId() && SequenceIdTrackingModifiedEntitiesRevisionEntity.class.isAssignableFrom(revisionInfoClass)) || modifiedEntityNamesFound.isSet()) {
// If tracking modified entities parameter is enabled, custom revision info entity is a subtype
// of DefaultTrackingModifiedEntitiesRevisionEntity class, or @ModifiedEntityNames annotation is used.
revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), modifiedEntityNamesData, metadata.getMetadataBuildingOptions().getServiceRegistry());
globalCfg.setTrackEntitiesChangedInRevision(true);
} else {
revisionInfoGenerator = new DefaultRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), metadata.getMetadataBuildingOptions().getServiceRegistry());
}
}
}
}
// In case of a custom revision info generator, the mapping will be null.
Document revisionInfoXmlMapping = null;
final Class<? extends RevisionListener> revisionListenerClass = getRevisionListenerClass(RevisionListener.class);
if (revisionInfoGenerator == null) {
if (globalCfg.isTrackEntitiesChangedInRevision()) {
revisionInfoClass = globalCfg.isUseRevisionEntityWithNativeId() ? DefaultTrackingModifiedEntitiesRevisionEntity.class : SequenceIdTrackingModifiedEntitiesRevisionEntity.class;
revisionInfoEntityName = revisionInfoClass.getName();
revisionInfoGenerator = new DefaultTrackingModifiedEntitiesRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), modifiedEntityNamesData, metadata.getMetadataBuildingOptions().getServiceRegistry());
} else {
revisionInfoClass = globalCfg.isUseRevisionEntityWithNativeId() ? DefaultRevisionEntity.class : SequenceIdRevisionEntity.class;
revisionInfoGenerator = new DefaultRevisionInfoGenerator(revisionInfoEntityName, revisionInfoClass, revisionListenerClass, revisionInfoTimestampData, isTimestampAsDate(), metadata.getMetadataBuildingOptions().getServiceRegistry());
}
revisionInfoXmlMapping = generateDefaultRevisionInfoXmlMapping();
}
return new RevisionInfoConfigurationResult(revisionInfoGenerator, revisionInfoXmlMapping, new RevisionInfoQueryCreator(revisionInfoEntityName, revisionInfoIdData.getName(), revisionInfoTimestampData.getName(), isTimestampAsDate()), generateRevisionInfoRelationMapping(), new RevisionInfoNumberReader(revisionInfoClass, revisionInfoIdData, metadata.getMetadataBuildingOptions().getServiceRegistry()), globalCfg.isTrackEntitiesChangedInRevision() ? new ModifiedEntityNamesReader(revisionInfoClass, modifiedEntityNamesData, metadata.getMetadataBuildingOptions().getServiceRegistry()) : null, revisionInfoEntityName, revisionInfoClass, revisionInfoTimestampData);
}
use of org.hibernate.envers.Audited in project hibernate-orm by hibernate.
the class AuditedPropertiesReader method readAuditOverrides.
/**
* Recursively constructs sets of audited and not audited properties and classes which behavior has been overridden
* using {@link AuditOverride} annotation.
*
* @param clazz Class that is being processed. Currently mapped entity shall be passed during first invocation.
*/
private void readAuditOverrides(XClass clazz) {
/* TODO: Code to remove with @Audited.auditParents - start. */
final Audited allClassAudited = clazz.getAnnotation(Audited.class);
if (allClassAudited != null && allClassAudited.auditParents().length > 0) {
for (Class c : allClassAudited.auditParents()) {
final XClass parentClass = reflectionManager.toXClass(c);
checkSuperclass(clazz, parentClass);
if (!overriddenNotAuditedClasses.contains(parentClass)) {
// If the class has not been marked as not audited by the subclass.
overriddenAuditedClasses.add(parentClass);
}
}
}
/* TODO: Code to remove with @Audited.auditParents - finish. */
final List<AuditOverride> auditOverrides = computeAuditOverrides(clazz);
for (AuditOverride auditOverride : auditOverrides) {
if (auditOverride.forClass() != void.class) {
final XClass overrideClass = reflectionManager.toXClass(auditOverride.forClass());
checkSuperclass(clazz, overrideClass);
final String propertyName = auditOverride.name();
if (!StringTools.isEmpty(propertyName)) {
// Override @Audited annotation on property level.
final XProperty property = getProperty(overrideClass, propertyName);
if (auditOverride.isAudited()) {
if (!overriddenNotAuditedProperties.contains(property)) {
// If the property has not been marked as not audited by the subclass.
overriddenAuditedProperties.add(property);
}
} else {
if (!overriddenAuditedProperties.contains(property)) {
// If the property has not been marked as audited by the subclass.
overriddenNotAuditedProperties.add(property);
}
}
} else {
// Override @Audited annotation on class level.
if (auditOverride.isAudited()) {
if (!overriddenNotAuditedClasses.contains(overrideClass)) {
// If the class has not been marked as not audited by the subclass.
overriddenAuditedClasses.add(overrideClass);
}
} else {
if (!overriddenAuditedClasses.contains(overrideClass)) {
// If the class has not been marked as audited by the subclass.
overriddenNotAuditedClasses.add(overrideClass);
}
}
}
}
}
final XClass superclass = clazz.getSuperclass();
if (!clazz.isInterface() && !Object.class.getName().equals(superclass.getName())) {
readAuditOverrides(superclass);
}
}
use of org.hibernate.envers.Audited in project hibernate-orm by hibernate.
the class AuditedPropertiesReader method checkAudited.
protected boolean checkAudited(XProperty property, PropertyAuditingData propertyData, String propertyName, Audited allClassAudited, String modifiedFlagSuffix) {
// Checking if this property is explicitly audited or if all properties are.
Audited aud = (property.isAnnotationPresent(Audited.class)) ? property.getAnnotation(Audited.class) : allClassAudited;
if (aud == null && overriddenAuditedProperties.contains(property) && !overriddenNotAuditedProperties.contains(property)) {
// Assigning @Audited defaults. If anyone needs to customize those values in the future,
// appropriate fields shall be added to @AuditOverride annotation.
aud = DEFAULT_AUDITED;
}
if (aud != null) {
propertyData.setStore(aud.modStore());
propertyData.setRelationTargetAuditMode(aud.targetAuditMode());
propertyData.setUsingModifiedFlag(checkUsingModifiedFlag(aud));
if (aud.modifiedColumnName() != null && !"".equals(aud.modifiedColumnName())) {
propertyData.setModifiedFlagName(aud.modifiedColumnName());
} else {
propertyData.setModifiedFlagName(MetadataTools.getModifiedFlagPropertyName(propertyName, modifiedFlagSuffix));
}
return true;
} else {
return false;
}
}
use of org.hibernate.envers.Audited in project CzechIdMng by bcvsolutions.
the class DefaultAuditService method getNameChangedColumns.
@Override
public <T> List<String> getNameChangedColumns(Class<T> entityClass, UUID entityId, Long currentRevId, T currentEntity) {
List<String> changedColumns = new ArrayList<>();
T previousEntity = null;
if (currentRevId == null) {
IdmAudit currentRevision = this.getAuditReader().getCurrentRevision(IdmAudit.class, true);
// current revision doesn't exist return empty list
if (currentRevision == null) {
return Collections.emptyList();
}
currentRevId = Long.valueOf(currentRevision.getId().toString());
}
previousEntity = this.findPreviousVersion(entityClass, entityId, currentRevId);
// previous revision doesn't exist return empty list
if (previousEntity == null) {
return Collections.emptyList();
}
Class<?> clazz = entityClass;
while (!(clazz.equals(AbstractEntity.class))) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getAnnotation(Audited.class) != null) {
Object previousValue;
Object currentValue;
try {
PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(currentEntity, field.getName());
Assert.notNull(propertyDescriptor, MessageFormat.format("DefaultAuditService: read method for audited field {0}, can't be null.", field.getName()));
//
Method readMethod = propertyDescriptor.getReadMethod();
// check if exists readMethod
Assert.notNull(readMethod, MessageFormat.format("DefaultAuditService: read method for audited field {0}, can't be null.", field.getName()));
previousValue = readMethod.invoke(previousEntity);
currentValue = readMethod.invoke(currentEntity);
if (previousValue == null && currentValue == null) {
continue;
}
if (previousValue == null || !previousValue.equals(currentValue)) {
changedColumns.add(field.getName());
}
} catch (IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
throw new IllegalArgumentException(MessageFormat.format("For entity class [{0}] with id [{1}] and revision id [{2}], name of changed columns cannot be found.", clazz, entityId, currentRevId), ex);
} catch (EntityNotFoundException e) {
// TODO: Try to found better solution for get entity that was not found
LOG.info("Audit service entity not found. Method [getNameChangedColumns]", e);
break;
}
}
}
clazz = clazz.getSuperclass();
}
return changedColumns;
}
Aggregations