При моделировании таблицы аудита я включил поля, необходимые для поиска исходной проверяемой записи (oid: String, className: String). Я хотел бы программно найти MetaMapper для имени класса Mapper.
Например, если у меня есть:
class Foo extends Mapper[Foo] {
def getSingleton = Foo
}
object Foo extends Foo with MetaMapper[Foo] {
}
Учитывая строку «Foo», как мне получить ссылку на объект Foo? В конечном счете, мне нужна ссылка на MetaMapper, чтобы я мог сделать findAll. В мои дни Hibernate я мог бы найти класс, используя Class.byName(className), а затем вызвать статический метод для этого класса.
Вот то, что я использую прямо сейчас, чтобы сделать это, но это требует ведения списка объектов MetaMapper, а также создания экземпляров классов с помощью MetaMapper#create:
case class Audited(name: String, url: Box[String])
def getAudited : Box[Audited] = {
// OBJECT_OID and OBJECT_TYPE are for the audited record we are trying to find
(OBJECT_OID.is, OBJECT_TYPE.is) match {
case (ooid, otype) if List(ooid,otype).forall(s => StringUtils.isNotBlank(s)) => {
// maintain a list of objects that are metamappers
val metas = List(Client)
(for {
// create a new instance and check its class name
meta <- metas.find(meta => meta.create.getClass.getName == otype)
mapper <- meta.find(By(meta.primaryKeyField, ooid))
} yield {
val nameFieldNames = List("NAME")
val name = mapper.allFields.find(f => nameFieldNames.contains(f.name)) match {
case Some(field) => tryo(field.is.toString).openOr("")
case _ => mapper.getClass.getName.split(".").last
}
Full(Audited(name, Empty))
}) openOr Empty
}
case _ => Empty
}
}
Что работает, но ИМХО некрасиво и требует ведения списка поддерживаемых MetaMappers.