sourceafQuickFlux::Entity.fan


@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#)
    }
}