package fr.postgresjson.entity.mutable import fr.postgresjson.entity.EntityI import org.joda.time.DateTime import java.util.* interface EntityRefI : EntityI { var id: T? } interface UuidEntityI : EntityRefI { override var id: UUID? } interface IdEntityI : EntityRefI { override var id: Int? } abstract class Entity(override var id: T? = null) : EntityRefI open class UuidEntity(override var id: UUID? = UUID.randomUUID()) : UuidEntityI, Entity(id) open class IdEntity(override var id: Int? = null) : IdEntityI, Entity(id) /* Version */ interface EntityVersioning { var versionId: ID var versionNumber: NUMBER? } class UuidEntityVersioning( override var versionNumber: Int? = null, override var versionId: UUID = UUID.randomUUID() ) : EntityVersioning /* Dates */ interface EntityCreatedAt { var createdAt: DateTime? } interface EntityUpdatedAt { var updatedAt: DateTime? } interface EntityDeletedAt { var deletedAt: DateTime? fun isDeleted(): Boolean { val deletedAt = deletedAt return deletedAt != null && deletedAt < DateTime.now() } } class EntityCreatedAtImp : EntityCreatedAt { override var createdAt: DateTime? = null } class EntityUpdatedAtImp : EntityUpdatedAt { override var updatedAt: DateTime? = null } class EntityDeletedAtImp : EntityDeletedAt { override var deletedAt: DateTime? = null } /* Author */ interface EntityCreatedBy { var createdBy: T? } interface EntityUpdatedBy { var updatedBy: T? } interface EntityDeletedBy { var deletedBy: T? } class EntityCreatedByImp( override var createdBy: UserT? ) : EntityCreatedBy class EntityUpdatedByImp( override var updatedBy: UserT? ) : EntityUpdatedBy class EntityDeletedByImp( override var deletedBy: UserT? ) : EntityDeletedBy /* Mixed */ class EntityDeletedImp( override var deletedBy: UserT? = null ) : EntityDeletedBy, EntityDeletedAt by EntityDeletedAtImp() class EntityUpdatedImp( override var updatedAt: DateTime? = null, override var updatedBy: UserT? = null ) : EntityUpdatedBy, EntityUpdatedAt by EntityUpdatedAtImp() class EntityCreatedImp( override var createdAt: DateTime? = null, override var createdBy: UserT? = null ) : EntityCreatedBy, EntityCreatedAt by EntityCreatedAtImp() /* Published */ interface Published { var publishedAt: DateTime? var publishedBy: UserT? } class EntityPublishedImp( override var publishedBy: UserT? ) : Published { override var publishedAt: DateTime? = null } /* Implementation */ abstract class EntityImp( updatedBy: UserT? ) : Entity(), EntityCreatedAt by EntityCreatedAtImp(), EntityUpdatedAt by EntityUpdatedAtImp(), EntityDeletedAt by EntityDeletedAtImp(), EntityCreatedBy by EntityCreatedByImp(updatedBy), EntityUpdatedBy by EntityUpdatedByImp(updatedBy), EntityDeletedBy by EntityDeletedByImp(updatedBy) abstract class UuidEntityExtended( updatedBy: UserT?, publishedBy: UserT? ) : EntityImp(updatedBy), EntityVersioning by UuidEntityVersioning(), Published by EntityPublishedImp(publishedBy)