Skip to content

Commit

Permalink
#2349 Introduce a base type for audit-entity companions
Browse files Browse the repository at this point in the history
  • Loading branch information
homedirectory committed Oct 30, 2024
1 parent 10acafe commit 3518567
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package ua.com.fielden.platform.audit;

import jakarta.inject.Inject;
import ua.com.fielden.platform.dao.CommonEntityDao;
import ua.com.fielden.platform.dao.exceptions.EntityCompanionException;
import ua.com.fielden.platform.entity.AbstractEntity;
import ua.com.fielden.platform.meta.IDomainMetadata;
import ua.com.fielden.platform.security.user.User;

import static org.apache.commons.lang3.StringUtils.substringAfter;
import static ua.com.fielden.platform.audit.AbstractAuditEntity.A3T;
import static ua.com.fielden.platform.error.Result.failuref;

/**
* Base type for implementations of audit-entity companion objects.
*
* @param <E> the audited entity type
* @param <AE> the audit-entity type
*/
public abstract class CommonAuditEntityDao<E extends AbstractEntity<?>, AE extends AbstractAuditEntity<E>>
extends CommonEntityDao<AE>
implements IAuditEntityDao<E, AE>
{

private IDomainMetadata domainMetadata;

@Inject
protected void setDomainMetadata(final IDomainMetadata domainMetadata) {
this.domainMetadata = domainMetadata;
}

@Override
public AE newAudit(final E auditedEntity, final String transactionGuid) {
if (auditedEntity.isDirty()) {
throw failuref("Only persisted and non-dirty instances of [%s] can be audited.", auditedEntity.getType().getTypeName());
}
// TODO Assert that audited entity is valid?

final AE audit = new_();
audit.beginInitialising();

// properties common to all audit-entities
audit.setAuditedEntity(auditedEntity);
audit.setAuditedVersion(auditedEntity.getVersion());
// Alternatively, annotate AbstractAuditEntity.auditDate with @IsProperty(assignBeforeSave = true)
audit.setAuditDate(now().toDate());
// Alternatively, annotate AbstractAuditEntity.auditDate with @IsProperty(assignBeforeSave = true)
audit.setUser(getUserOrThrow());
audit.setAuditedTransactionGuid(transactionGuid);

// specific, audited properties
final var auditEntityMetadata = domainMetadata.forEntity(getEntityType());
for (final var auditProp : auditEntityMetadata.properties()) {
// Audited properties can be identified by their names
final var auditedPropName = substringAfter(auditProp.name(), A3T + "_");
if (!auditedPropName.isEmpty()) {
audit.set(auditProp.name(), auditedEntity.get(auditedPropName));
}
}

audit.endInitialising();
return audit;
}

/**
* Returns the current user, if defined; otherwise, throws an exception.
*/
private User getUserOrThrow() {
final var user = getUser();
if (user == null) {
throw new EntityCompanionException("The current user is not defined.");
}
return user;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ua.com.fielden.platform.audit;

import ua.com.fielden.platform.dao.IEntityDao;
import ua.com.fielden.platform.entity.AbstractEntity;

/**
* A contract for all audit-entity companion objects to implement.
*
* @param <E> the audited entity type
* @param <AE> the audit-entity type
*/
public interface IAuditEntityDao<E extends AbstractEntity<?>, AE extends AbstractAuditEntity<E>>
extends IEntityDao<AE>, IAuditEntityInstantiator<E, AE>
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ua.com.fielden.platform.audit;

import ua.com.fielden.platform.entity.AbstractEntity;

/**
* A contract to instantiate audit-entities.
*
* @param <E> the audited entity type
* @param <AE> the audit-entity type
*/
public interface IAuditEntityInstantiator<E extends AbstractEntity<?>, AE extends AbstractAuditEntity<E>> {

/**
* Returns a new, initialised instance of this audit-entity type.
*
* @param auditedEntity the audited entity that will be used to initialise the audit-entity instance.
* Must be persisted and non-dirty.
* @param transactionGuid identifier of a transaction that was used to save the audited entity
*/
AE newAudit(E auditedEntity, String transactionGuid);

}

0 comments on commit 3518567

Please sign in to comment.