Как получить ссылку на объект Lift MetaMapper по имени?

При моделировании таблицы аудита я включил поля, необходимые для поиска исходной проверяемой записи (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.


person Collin    schedule 19.10.2010    source источник


Ответы (1)


Почему не Audited.getSingleton ? Это в каждом экземпляре вашего класса Mapped.....

Oh, ok

Итак, у вас есть таблица аудита, которая проверяет, что изменилось в какой-то другой таблице. Вы должны иметь возможность преобразовать имя класса и использовать тот же механизм, который вы использовали для java. Однако, почему бы просто не иметь сопоставление один ко многим между классом Audited и классом аудита?

person Jim Barrows    schedule 19.10.2010
comment
Audited — это не MetaMapper. Это просто оболочка класса case для хранения некоторых других данных. Например, одним из моих классов Mapper является Client. Я хотел бы получить объект Client, расширяющий MetaMapper. Я хочу сделать это для любого произвольного имени, а не только для клиента. - person Collin; 19.10.2010
comment
Джим, спасибо за ответ. Это более общая проблема, связанная не только с загрузкой класса Mapper для определенного имени класса, но и с тем, как получить ссылку на object, который является синглтоном класса Mapper. - person Collin; 21.10.2010