@Serializable
const abstract class Entity {
protected static const Log log := Utils.getLog(Entity#)
static const Entity? defVal := null
const Int id
abstract Str displayName()
virtual Uri? displayIcon() { null }
** Override to add validation
virtual This save() {
datastore.save(this)
eventHub.fireEvent(Events.entitySaved, this)
return this
}
** Override to add validation
virtual This delete() {
datastore.delete(this)
eventHub.fireEvent(Events.entityDeleted, this)
return this
}
virtual Uri toViewUri() {
`${EntityScheme.schemeName}://${typeof.name.decapitalize}/view/${id}`
}
virtual Uri toEditUri() {
`${EntityScheme.schemeName}://${typeof.name.decapitalize}/edit/${id}`
}
override Int hash() {
id.hash
}
override Bool equals(Obj? that) {
if (that == null) return false
if (!that.typeof.fits(this.typeof)) return false
return ((Entity) that).id == id
}
override Str toStr() {
displayName
}
virtual This clone(|Field:Obj|? overridePlan := null) {
plan := Field:Obj[:]
typeof.fields.each {
if (!it.isStatic) {
value := it.get(this)
if (value != null)
plan[it] = value
}
}
overridePlan?.call(plan)
planFunc := Field.makeSetFunc(plan)
return (Entity) typeof.make([planFunc])
}
protected Datastore datastore() {
DatastoreSrc datastoreSrc := Utils.dependencyByType(DatastoreSrc#)
return datastoreSrc.get(this.typeof)
}
private EventHub eventHub() {
Utils.dependencyByType(EventHub#)
}
}