2010-10-19 3 views
2

Lors de la modélisation d'une table d'audit, j'ai inclus les champs nécessaires pour trouver l'enregistrement d'origine en cours d'audit (oid: String, className: String). Je voudrais trouver par programme le MetaMapper pour le nom de la classe Mapper.Comment obtenir une référence à un objet Lift MetaMapper par son nom?

Par exemple, si j'ai:

class Foo extends Mapper[Foo] { 
    def getSingleton = Foo 
} 

object Foo extends Foo with MetaMapper[Foo] { 
} 

Compte tenu de la chaîne « Foo », comment pourrais-je obtenir une référence à l'objet Foo? En fin de compte, je veux une référence à un MetaMapper afin que je puisse faire un findAll. Dans mes jours Hibernate, j'ai peut-être trouvé une classe en utilisant Class.byName (className), puis appelé une méthode statique sur cette classe.

Voici ce que j'utilise en ce moment pour le faire, mais il ne nécessite le maintien d'une liste d'objets MetaMapper et aussi instancier des classes en utilisant # de MetaMapper créer:

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 
    } 
} 

Ce qui fonctionne, mais il est à mon humble avis laid et nécessite la maintenance d'une liste de MetaMappers pris en charge

Répondre

1

Pourquoi pas Audited.getSingleton? Il est dans tous les cas de votre classe mappée .....

Oh, ok

Vous avez une table d'audit, que les vérifications ce qui a changé dans une autre table. Vous devriez être capable de convertir le nom de classe, et utiliser le même mécanisme que vous avez utilisé pour Java. Cependant, pourquoi ne pas avoir un mappage un à plusieurs entre une classe Audited et la classe d'audit?

+0

Audited n'est pas le MetaMapper. C'est juste un wrapper de classe de cas pour contenir d'autres données. Par exemple, l'une de mes classes Mapper est "Client". Je voudrais obtenir l'objet Client qui étend MetaMapper. Je veux le faire pour n'importe quel nom arbitraire, pas seulement "Client". – Collin

+0

Jim, merci pour la réponse. C'est un problème plus général de ne pas simplement charger la classe Mapper pour un nom de classe particulier, mais comment obtenir une référence à l'objet * * qui est le singleton de la classe Mapper. – Collin

Questions connexes