<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AQuA.it &#187; GWT</title>
	<atom:link href="http://blog.aquait.info/category/gwt/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aquait.info</link>
	<description>Blog técnico de AQuA.it</description>
	<lastBuildDate>Mon, 17 Oct 2011 12:15:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>GWT Reflection</title>
		<link>http://blog.aquait.info/2009/12/gwt-reflection/</link>
		<comments>http://blog.aquait.info/2009/12/gwt-reflection/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 00:32:02 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=188</guid>
		<description><![CDATA[Intro Siguiendo en la linea de la introspección, hoy vamos a ver una simple reflexión que nos va a permitir invocar sobre una instancia de una clase a métodos por su nombre. What for? La reflexión es una característica interesante, que se hace fundamental a la hora de diseñar componentes genéricos. Nos permite crear instancias [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } 		A:link { so-language: zxx } --></p>
<p style="margin-bottom: 0in;">Intro</p>
<p style="margin-bottom: 0in;">Siguiendo en la linea de la introspección, hoy vamos a ver una simple reflexión que nos va a permitir invocar sobre una instancia de una clase a métodos por su nombre.</p>
<p style="margin-bottom: 0in;"><span id="more-188"></span></p>
<p style="margin-bottom: 0in;">What for?</p>
<p style="margin-bottom: 0in;">La reflexión es una característica interesante, que se hace fundamental a la hora de diseñar componentes genéricos. Nos permite crear instancias de determinada clase con el nombre de la clase o también invocar métodos sobre una instancia de una clase teniendo el nombre del método. Esto, por ejemplo, nos simplifica enormemente la implementación del patrón command.</p>
<p style="margin-bottom: 0in;">How? What?!</p>
<p style="margin-bottom: 0in;">En GWT (al menos hasta la 1.7) no hay reflexión. Lo que vamos a hacer en esta implementación de reflexión, es proveer un mecanismo para invocar métodos por nombre. Suponiendo que tenemos una clase llamada <strong>MiClase</strong> que tiene un método llamado <strong>miMetodo</strong> buscamos poder hacer algo así:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">MiClase instancia = new MiClase();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">String nombreMetodo = “miMetodo”;</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">Object[] parametros = new Object[]{...};</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">invocar(instancia, nombreMetodo, parametros);</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Enter generators!</p>
<p style="margin-bottom: 0in;">Lo que vamos a hacer es que GWT genere la clase MiClaseReflection. ¿Cómo? Usando generators. Esta es una característica bien interesante de GWT. El foco de este artículo no está en explicar generators, hay mucha literatura en Internet. Acá va un link: <a href="http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding">http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding</a>. Igual no hay que ser un experto para entender lo que vamos a hacer.</p>
<p style="margin-bottom: 0in;">Básicamente vamos a escribir una clase que genere el código de MiClaseReflection, que tiene un único método -invocar- que es una cadena if..elseif..else que pregunta por cada método de MiClase y si alguna coincide, se lo invoca. Sería algo como esto:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">if (nombreMetodo.equals(“miMetodo1”)) {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    target.miMetodo1(params);  // void</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">} else if (nombreMetodo.equals(“miMetodo2”)) {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    return target.miMetodo2(params); // no void</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">} else {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    throw new Exception(“método no encontrador: ” + nombreMetodo);</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">Obviamente falta chequeos de parámetros.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para no tener que realizar ningún paso previo a la compilación generando la clase con alguna utilidad externa vamos a usar la API que tiene GWT que permite extender el compilador (com.google.gwt.core.ext). NOTA: Los que hayan utilizado APT de Java van ver unas cuantas similitudes (<a href="http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html">http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html</a>).</p>
<p style="margin-bottom: 0in;">Cuando el compilador de GWT encuentra con la instrucción GWT.create(class) –que devuelve una implementación de la interfaz class– invoca al generador asociado a la interfaz class (esta asociación se declara en el gwt.xml del módulo). En este generador se “escribe” el código que implementa la interfaz class. Para escribir este código tenemos la asistencia de la API com.google.gwt.core.ext.typeinfo que recuerda mucho a la API Mirror Reflection de Java.</p>
<p style="margin-bottom: 0in;">Generate</p>
<p style="margin-bottom: 0in;">La instrucción GWT.create() toma una interfaz y devuelve una implementación de la misma. Entonces vamos definir una interfaz de marca y la vamos a llamar Reflectable. Toda clase que queramos tener soporte de reflexión va a tener que implementar esta interfaz:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public interface Reflectable {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Entonces la clase MiClase:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public class MiClase implements Reflectable {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    void miMetodo1();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    int miMetodo2();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Además, tenemos que tener la interfaz de idioma de la reflexión:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public interface Reflection&lt;I extends Reflectable&gt; {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    Object invoke(I target, String methodName, Object... params)</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    throws InvocationException;</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para obtener una reflexión y usarla suponiendo que <strong>miMetodo</strong> no tiene parámetros:</p>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">MiClase objeto = new MiClase();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">Reflection&lt;MiClase&gt; reflection = GWT.create(MiClase.class);</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">reflection.invoke(objeto, “miMetodo”);</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para asociar el generador con la interfaz Reflectable, agregamos el siguiente fragmento al :</p>
<p style="margin-bottom: 0in;">
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    &lt;generate-with class="com.aquait.utils.gwt.rebind.ReflectionGenerator"&gt;</span></span></pre>
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">        &lt;when-type-assignable class="com.aquait.utils.gwt.reflection.Reflectable"/&gt;</span></span></pre>
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    &lt;/generate-with&gt;</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Así, cuando el compilador de GWT encuentra GWT.create(MiClase.class), llama al generador pues la clase MiClase implementa Reflectable. Luego, tenemos una implementación de la interfaz Reflectable para la clase MiClase.</p>
<p style="margin-bottom: 0in;">Para usarlo en un proyecto, hay que agregar esto en el &lt;modulo&gt;.gwt.xml:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">&lt;inherits name="com.aquait.utils.gwt.Reflection"/&gt;</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">El JAR se puede descargar de acá: <a href="http://blog.aquait.info/wp-content/uploads/2009/12/introspection-reflection4gwt.jar_.gz">introspection-reflection4gwt.jar</a></p>
<p style="margin-bottom: 0in;">Nota: Este JAR tiene una versión actualizada de la introspección que elimina los métodos getIntrospectable() y setIntrospectable() de la interfaz Introspection. Por lo tanto, los métodos getProperty() y setProperty() toman como primer parámetro al Introspectable.</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F12%2Fgwt-reflection%2F&amp;title=GWT%20Reflection" id="wpa2a_2"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/12/gwt-reflection/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GWT Introspection</title>
		<link>http://blog.aquait.info/2009/09/introspeccion-en-gwt/</link>
		<comments>http://blog.aquait.info/2009/09/introspeccion-en-gwt/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 18:23:27 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=89</guid>
		<description><![CDATA[Intro Una de las características que más se extrañan a la hora de utilizar GWT es la capacidad de Java de realizar introspección sobre beans. La causa de esta limitación es que GWT no tiene emulación la API reflexión (java.lang.reflect). En este artículo vamos a ver como podemos implementar una suerte de introspección en GWT. [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } 		A:link { so-language: zxx } --></p>
<p style="margin-bottom: 0in;">Intro</p>
<p style="margin-bottom: 0in;">Una de las características que más se extrañan a la hora de utilizar GWT es la capacidad de Java de realizar introspección sobre beans. La causa de esta limitación es que GWT no tiene emulación la API reflexión (java.lang.reflect). En este artículo vamos a ver como podemos implementar una suerte de introspección en GWT. También vamos a explorar algunas aplicaciones de introspección, ya que en principio no es trivial su utilidad.</p>
<p style="margin-bottom: 0in;"><span id="more-89"></span></p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">What for?</p>
<p style="margin-bottom: 0in;">Lo primero que vamos a ver es para qué queremos esto.</p>
<p style="margin-bottom: 0in;">Supongamos que queremos desarrollar un framework de componentes visuales que tenga data binding (capacidad de “enganchar” la propiedad de un objeto a un componente visual). Seguramente a todo aquel que le tocó la “maravillosa” tarea de implementar un CURD (ABM en criollo) se topó con la tediosa tarea de setear y leer de los componentes visuales al objeto y viceversa. Si te tocó hacer esto, algo malo hiciste <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Bueno, esta es una tarea tan aburrida como propensa a errores, sobre todo de Control-C + Control-V. Si pudieramos decir algo como: “este componente UI mira la propiedades tal de cual objeto”, entonces podemos aliviar bastante esta tarea ya que por ejemplo nos ahorramos todo el código de manejo de eventos.</p>
<p style="margin-bottom: 0in;">Entonces si podemos hacer esto, podemos construir un conjunto de componentes a los cuales simplemente le seteamos el bean y la propiedad que “mira” así cuando al componente se le cambia el valor, automáticamente se refleja en el bean y viceversa.</p>
<p style="margin-bottom: 0in;">Pero ¿cómo hacer esto sin introspeccion?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">How? What?!</p>
<p style="margin-bottom: 0in;">Como vimos, en GWT (al menos hasta la 1.7) no hay reflexión, por lo que no nos queda más remedio que buscar otra forma de implementar introspección. Primero vamos a ver qué es la introspección en Java. Según el JavaDoc de la clase java.beans.Introspector:</p>
<p style="margin-left: 0.49in; margin-bottom: 0in;">“The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.”</p>
<p style="margin-bottom: 0in;">En español:</p>
<p style="margin-left: 0.49in; margin-bottom: 0in;">“La clase Introspector  provee una forma estándar para que herramientas descubran propiedades, eventos y métodos soportados por un Java Bean”.</p>
<p style="margin-bottom: 0in;">La parte que más nos interesa es la parte de las propiedades. O sea, queremos poder implementar un mecanismo con el cual se le pueda preguntar a un Java Bean cuales son sus propiedades y cuales son los valores de estas.</p>
<p style="margin-bottom: 0in;">La forma que vamos a implementar es creando una clase que sea la introspección para cada clase que queramos tener introspección.</p>
<p style="margin-bottom: 0in;">Entonces para la clase:</p>
<pre class="brush: java">public class Persona {
    private String nombre;
    private String direccion;
    private Date nacimiento;
    private boolean sexo;

    public Persona() {
    }

    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    // ...más getters y setters...
}</pre>
<p style="margin-bottom: 0in;">Tenemos que implementar la clase de “introspección”:</p>
<pre class="brush: java">public PersonaIntrospection {
    private Persona persona;

    public PersonaIntrospeccion() {
    }

    public Persona getPersona() {
        return persona;
    }

    public Persona setPersona(Persona p) {
        persona = p;
    }

    public List&lt;String&gt; getProperties() {
        List&lt;String&gt; l = new ArrayList&lt;String&gt;();
        l.add(“nombre”);
        l.add(“direccion”);
        l.add(“nacimiento”);
        l.add(“sexo”);
    }

    public Object getProperty(String property) {
        if (“nombre”.equals(property))
            return persona.getNombre();
        else if (“direccion”.equals(property))
            return persona.getDireccion();
        else if (“nacimiento”.equals(property))
            return persona.getNacimiento();
        else if (“sexo”.equals(property))
            return persona.getSexo();
        else
            throw new IllegalArgumentException(property);
    }

    public void setProperty(String property, Object value) {
        if (“nombre”.equals(property))
            persona.setNombre((String)value);
        else if (“direccion”.equals(property))
            persona.setDireccion((String)value);
        else if (“nacimiento”.equals(property))
            persona.setNacimiento((Date)value);
        else if (“sexo”.equals(property))
            persona.setSexo((Boolean)value);
        else
            throw new IllegalArgumentException(property);
    }
}</pre>
<p style="margin-bottom: 0in;">Más allá de las optimizaciones que se le pueden hacer al código (como cachear la lista de propiedades), la idea es que se entienda de por qué esta clase nos da introspección sobre un objeto persona. Como ya se deben estar imaginando, la gracia es no tener que escribir la clase PersonaIntrospection. La gracia es trabajar menos en cosas aburridas y más en cosas “divertidas“ <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Enter generators!</p>
<p style="margin-bottom: 0in;">Lo que vamos a hacer es que GWT genere la clase PersonaIntrospection. ¿Cómo? Usando generators. Esta es una característica bien interesante de GWT. El foco de este artículo no está en explicar generators, hay mucha literatura en Internet. Acá va un link <a href="http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding">http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding</a>. Igual no hay que ser un experto para entender lo que vamos a hacer.</p>
<p style="margin-bottom: 0in;">Básicamente vamos a escribir una clase que genere el código de XxxIntrospection para la clase Xxx según vimos en el ejemplo de Persona. Y (para no tener que realizar ningún paso previo a la compilación generando la clase con alguna utilidad externa) vamos a usar la API que tiene GWT que permite extender el compilador (com.google.gwt.core.ext). NOTA: Los que hayan utilizado APT de Java van ver unas cuantas similitudes (<a href="http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html">http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html</a>).</p>
<p style="margin-bottom: 0in;">Cuando el compilador de GWT encuentra con la instrucción GWT.create(class) –que devuelve una implementación de la interfaz class– invoca al generador asociado a la interfaz class (esta asociación se declara en el gwt.xml del módulo). En este generador se “escribe” el código que implementa la interfaz class. Para escribir este código tenemos la asistencia de la API com.google.gwt.core.ext.typeinfo que recuerda mucho a la API Mirror Reflection de Java.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Generate</p>
<p style="margin-bottom: 0in;">Ahora vamos a ver el generador en si. Pero primero vamos a ver como se utiliza. GWT.create() toma una interfaz y devuelve una implementación de la misma. Entonces vamos definir una interfaz de marca y la vamos a llamar Introspectable. Toda clase que queramos tener soporte de introspección va a tener que implementar esta intefaz:</p>
<pre class="brush: java">public interface Introspectable {
}</pre>
<p style="margin-bottom: 0in;">Entonces la clase Persona:</p>
<pre class="brush: java">public class Persona implements Introspectable {
    // ... atributos y métodos ...
}</pre>
<p style="margin-bottom: 0in;">Además, tenemos que tener la interfaz de idioma de la introspección:</p>
<pre class="brush: java">public interface Introspection&lt;I extends Introspectable&gt; {
    I getIntrospectable();
    void setIntrospectable(I i);
    &lt;T&gt; T getProperty(String propName);
    void setProperty(String propName, Object value);
    Collection&lt;String&gt; getPropertyNames();
}</pre>
<p style="margin-bottom: 0in;">Y para obtener una introspección y usarla:</p>
<pre class="brush: java">Persona persona = new Persona();
Introspection&lt;Persona&gt; instrospection = GWT.create(Persona.class);
instrospection.setIntrospectable(persona);

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

String nombre = instrospection.getProperty("nombre");
String direccion = instrospection.getProperty("direccion");
Date nacimiento = instrospection.getProperty("nacimiento");
Boolean sexo = instrospection.getProperty("sexo");</pre>
<p style="margin-bottom: 0in;">Para asociar el generador con la interfaz Introspectable, agregamos el siguiente fragmento al :</p>
<pre class="brush: xml">&lt;generate-with class="com.aquait.utils.gwt.rebind.IntrospectionGenerator"&gt;
    &lt;when-type-assignable class="com.aquait.utils.gwt.introspection.Introspectable"/&gt;
&lt;/generate-with&gt;</pre>
<p style="margin-bottom: 0in;">Así, cuando el compilador de GWT encuentra GWT.create(Persona.class), llama al generador pues la clase Persona implementa Introspectable. Luego, tenemos una implementación de la interfaz Introspection para la clase Persona.</p>
<p style="margin-bottom: 0in;">Para usarlo en un proyecto, hay que agregar esto en el &lt;modulo&gt;.gwt.xml:</p>
<pre class="brush: xml">&lt;inherits name="com.aquait.utils.gwt.Introspection"/&gt;</pre>
<p style="margin-bottom: 0in;">El módulo GWT se puede descargar de acá: <a href="http://blog.aquait.info/wp-content/uploads/2009/09/introspection4gwt.jar">introspection4gwt</a></p>
<p style="margin-bottom: 0in;">EDIT: se actualizó el archivo debido a un pequeño bug.</p>
<p style="margin-bottom: 0in;">EDIT: se volvió a actualizar debido a un bug que hacía que no se tomaran en cuenta las propiedades de las super clases.</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fintrospeccion-en-gwt%2F&amp;title=GWT%20Introspection" id="wpa2a_4"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/09/introspeccion-en-gwt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

