Introspection GWT

2 septembre 2009 par Enrique Laisser une réponse »

Intro

Une des caractéristiques qui sont manqués lors de l'utilisation de GWT est la capacité de Java pour effectuer une introspection sur les haricots. La raison de cette limitation est que GWT n'a pas d'émulation API de réflexion (java.lang.reflect). Dans cet article nous allons voir comment nous pouvons mettre en œuvre une sorte d'introspection dans GWT. Nous allons aussi explorer quelques-unes des applications de l'introspection, car en principe il n'est pas d'utilité triviale.

Pour quoi faire?

La première chose que nous voyons ce que nous le voulons.

Supposons que nous voulons développer un cadre de composants visuels qui ont la liaison de données (capacité à «crochet» de la propriété d'un objet à un composant visuel). Sûrement quelqu'un qui a touché son "merveilleux" travail de mise en œuvre d'un caillé (ABM créole) a été atteint avec la lecture ensemble de départ et fastidieux des composantes visuelles de l'objet et vice versa. Si vous aviez à faire, vous avez quelque chose de mal :) . Eh bien, c'est une tâche aussi ennuyeux que sujettes à des erreurs, en particulier sur Control-C + Ctrl-V. Si l'on pouvait dire quelque chose comme: "Ce composant IU regarde les propriétés de cet objet que," alors nous pouvons alléger cette tâche aussi bien par exemple nous sauver tous le code de gestion des événements.

Donc, si nous faisons cela, nous pouvons construire un ensemble de composants pour lesquels nous avons mis tout simplement le haricot et la propriété que «regarder» ainsi que les changements de valeur composant sera automatiquement reflétée dans la fève, et vice versa.

Mais comment faire cela sans l'introspection?

Comment? Quoi?!

Comme nous l'avons vu dans GWT (au moins jusqu'à 1,7) il n'ya pas de réflexion, donc nous n'avons aucun autre choix que de trouver un autre moyen de mettre en œuvre l'introspection. D'abord nous allons voir ce qui est une introspection en Java. Selon la JavaDoc java.beans.Introspector classe:

"La classe Introspector fournit un moyen standard pour les outils pour se renseigner sur les propriétés, les événements, et soutenue par une cible de méthodes Java Bean».

En espagnol:

"La classe Introspector fournit un moyen standard pour les outils permettant de découvrir les propriétés, les événements et les méthodes prises en charge par un Java Bean».

La partie qui nous intéresse est la partie de la propriété. En d'autres termes, nous voulons mettre en place un mécanisme par lequel vous pouvez être un Java Bean se demander quelles sont leurs propriétés et quelles sont les valeurs de ces derniers.

La forme va le mettre en œuvre en créant une classe pour chaque classe de l'introspection que nous voulons avoir un aperçu.

Alors, pour la classe:

  public class Personne {
     private String nom;
     String adresse privée;
     Date de naissance privé;
     privés du sexe booléen;

     Personne publique () {
     }

     public String getName () {
         retour nom;
     }
     public void setName (String nom) {
         this.name = nom;
     }

     / / Getters et setters ... plus ...
 } 

Nous avons à mettre en œuvre le genre de "vision":

 Personne publique PersonaIntrospection {personne privée, PersonaIntrospeccion publique () {} getPerson personne publique () {personne return;} Personne setPersona publics (Personne p) {p = personne;} public getProperties <String> Liste () {<String> l Liste <String> = new ArrayList (); l.add ("nom"); l.add ("adresse"); l.add ("naissance"); l.add ("sexe");} public Object getProperty ( propriété String) {if persona.getNombre retour ("nom" est égal à (la propriété.)) (); else if ("adresse" est égal à (propriété). persona.getDireccion retour) ();. else if ("naissance" est égal à ( la propriété)) return persona.getNacimiento (); else if retour ("sexe" est égal à (bien)) persona.getSexo ();. autre throw new IllegalArgumentException (propriété);} public void setProperty (propriété String, Object value) {if (. "nom" est égal à (bien)) persona.setNombre ((String) valeur); else if ("adresse" est égal à (bien).) persona.setDireccion ((String) value);. else if ("naissance" est égal à (propriété)) persona.setNacimiento ((date) valeur); else if ("sexe" est égal à (la propriété.)) persona.setSexo ((Boolean) valeur); ailleurs throw new IllegalArgumentException (propriété);}} 

Au-delà des optimisations que vous pouvez faire pour le code (et cache biens), l'idée est de comprendre pourquoi cette classe nous donne un aperçu d'un objet personne. Comme cela devrait être d'imaginer, la grâce n'est pas d'avoir à écrire le PersonaIntrospection classe. Grace est travailler sur des choses moins ennuyeux et plus "fun" des choses :)

Entrez les générateurs!

Qu'est-ce que nous faisons est que GWT génère la classe PersonaIntrospection. Comment? Utilisation des générateurs. C'est une caractéristique très intéressante de GWT. L'objectif de cet article est d'expliquer les générateurs, il ya beaucoup de littérature sur Internet. Voici une Il suffit de ne pas être un expert pour comprendre ce que nous faisons.

Fondamentalement, nous allons écrire une classe qui génère du code pour le XxxIntrospection Sexe classe comme nous l'avons vu dans l'exemple de la personne. Y (pour éviter d'avoir à faire aucun pas vers la création de la compilation genre avec une certaine utilité externe), nous allons utiliser l'API qui vous permet d'étendre le compilateur de GWT (com.google.gwt.core.ext). NOTE: Ceux qui ont utilisé Java APT verrez quelques similitudes ( http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html ).

Lorsque le compilateur de GWT rencontre le GWT.create déclaration (classe), qui retourne une implémentation de l'interface de classe du générateur invoque l'interface associée à la classe (cette association est déclarée dans le module gwt.xml). Ce générateur est "écrire" le code qui implémente la classe d'interface. Pour écrire ce code ont l'aide de l'API qui est très réminiscent com.google.gwt.core.ext.typeinfo API Java Reflection Mirror.

Générer

Maintenant, voyons si le générateur. Mais d'abord, voyons comment il est utilisé. GWT.create () prend une interface et retourne une implémentation de celle-ci. Puis on définit une interface de la marque et nous allons appeler introspective. Tout type que vous voulez avoir le soutien d'introspection va devoir mettre en œuvre cette interface:

 introspection {} public interface 

Puis la classe Person:

  public class Personne {œuvre introspection
     / / ...  attributs et les méthodes ...
 } 

Nous avons également besoin d'avoir la langue de l'interface d'introspection:

 Introspection <I interface publique s'étend Introspectable> getIntrospectable {I (); setIntrospectable vide (I i) T <T> getProperty (String propName) void setProperty (String propName, Object value); Collection <String> getPropertyName ();} 

Et pour l'introspection et l'utilisation:

  Personne Personne = new Person ();
 Instrospection GWT.create introspection <person> = (Persona.class);
 instrospection.setIntrospectable (personne);

 pour (String prop: instrospection.getPropertyNames ()) {
     System.out.println (prop + "=" + instrospection.getProperty (prop));
 }

 String name = Instrospection.getProperty ("nom");
 String adresse Instrospection.getProperty = ("adresse");
 Date de naissance = instrospection.getProperty ("naissance");
 Instrospection.getProperty sexe = booléen ("sexe"); 

Pour associer le générateur d'interface d'introspection, d'ajouter le code suivant:

  class = "com.aquait.utils.gwt.rebind.IntrospectionGenerator"> <generate-avec
     class = "com.aquait.utils.gwt.introspection.Introspectable" /> <quand type cessible
 </ Génère-avec> 

Ainsi, lorsque le compilateur GWT est GWT.create (Persona.class), a appelé le générateur pour la personne classe implémente introspectif. Ensuite, nous avons une implémentation de l'interface d'introspection pour la classe Person.

Pour une utilisation dans un projet, ajoutez ceci dans le <module> gwt.xml.:

  name = "com.aquait.utils.gwt.Introspection" /> <hérite 

Le module GWT peut être téléchargé ici: introspection4gwt

EDIT: Mise à jour le fichier en raison d'un petit bug.

EDIT: Mise à jour à nouveau en raison d'un bug qui ne prennent pas en compte les propriétés de la super-classes.

Blogger message Digg Reddit Google Reader Partager
Publicité

Laisser un commentaire

Protection contre les spams par WP Captcha-Free