GWT – JSON dates

JSON no tiene un tipo de dato Date, así que cuando transfieres fechas mediante JSON debes convenir un formato de fecha -por ejemplo, yyyy-MM-dd’T’hh:mm:ss.SZ- Un ejemplo de fecha en este formato sería “2013-03-08T16:23:35.000+0000”.

Para facilitar un poco las cosas, decidí utilizar un Overlay Type para la representación de mi objeto y acceder a sus propiedades mediante getter’s y setter’s. Estos métodos realizan la conversión de cadena a fecha, y viceversa, con la ayuda de la clase DateTimeFormat.

    public class Audiencia extends JavaScriptObject {</p><pre><code>    private final static DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM-dd'T'hh:mm:ss.SZ");

    public final native int getId()/*-{
        return this.id;
    }-*/;

    public final Date getInicio(){
        return dateTimeFormat.parseStrict(getInicioNative());
    };

    private final native String getInicioNative()/*-{
        return this.inicio;
    }-*/;

    public final Date getFin(){
        return dateTimeFormat.parseStrict(getFinNative());
    };

    private final native String getFinNative()/*-{
        return this.fin;
    }-*/;

    protected Audiencia() {
    }

    public static void getAudiencias(String idSala,
            final AsyncCallback&lt;Audiencia[]&gt; callback) {
        try {
            String queryParams = "?sala="+URL.encodeQueryString(idSala);
            RequestBuilder rb = new RequestBuilder(RequestBuilder.GET,
                    Consts.REST_AUDIENCIAS + queryParams);
            rb.sendRequest(null, new RequestCallback() {

                @Override
                public void onResponseReceived(Request request,
                        Response response) {
                    if(response.getStatusCode() == 200){
                        JavaScriptObject jso = JSON.decode(response.getText());
                        DSResponse ds = new DSResponse(JSOHelper.getAttributeAsJavaScriptObject(jso, "response"));
                        if(ds.getStatus() == 0){
                            Record[] records = ds.getData();
                            Audiencia[] audiencias = new Audiencia[records.length];
                            for(int i=0;i&lt;records.length;i++){
                                audiencias[i] = (Audiencia) records[i].getJsObj();
                            }
                            callback.onSuccess(audiencias);
                        }else{
                            callback.onFailure(new Exception(ds.getAttributeAsString("data")));
                        }
                    }else{
                        callback.onFailure(new Exception(response.getStatusText()));
                    }
                }

                @Override
                public void onError(Request request, Throwable exception) {
                    callback.onFailure(exception);
                }
            });
        } catch (Exception e) {
            callback.onFailure(e);
        }
    }

}
</code></pre><p>

Esto es necesario porque el método JSON.decode) crea el objeto Javascript con propiedades (inicio y fin) de tipo String.

Anuncios

GWT – Casting Overlay Types Arrays

Para la implementación de un sistema de mensajes utilicé los llamados overlay types de GWT. Declaré una clase de la siguiente manera

    public class SystemMessage extends JavaScriptObject {</p><pre><code>    protected SystemMessage() {
    }

    public final native String getId()/*-{
        return this.id;
    }-*/;

    public final native String getHtml()/*-{
        return this.html;
    }-*/;
}
</code></pre><p>

Agregué a esta clase un método para obtener los mensajes del sistema desde un servicio REST

    public static void getMessages(final AsyncCallback<SystemMessage[]> callback) {
        try {
            RequestBuilder rb = new RequestBuilder(RequestBuilder.GET,
                    URLRESTSYSTEMMESSAGES);
            rb.sendRequest(null, new RequestCallback() {</p><pre><code>            @Override
            public void onResponseReceived(Request request,
                    Response response) {
                if (response.getStatusCode() == 200) {
                    JavaScriptObject jsResponse = JSON.decode(response
                            .getText());
                    DSResponse dsResponse = new DSResponse(JSOHelper
                            .getAttributeAsJavaScriptObject(jsResponse,
                                    "response"));
                    if (dsResponse.getStatus() == 0) {
                        JavaScriptObject[] array = JSOHelper
                            .getAttributeAsJavaScriptObjectArray(dsResponse.getJsObj(),
                                        "data");
                        SystemMessage[] messages = (SystemMessage[]) array;
                        callback.onSuccess(messages);
                    }
                } else {
                    callback.onFailure(new Exception(response.getText()));
                }
            }

            @Override
            public void onError(Request request, Throwable exception) {
                callback.onFailure(exception);
            }
        });
    } catch (Exception e) {
        callback.onFailure(e);
    }
}
</code></pre><p>

El servidor nos regresa una respuesta en JSON parecida a la siguiente

    {"response":{ "status": 0, "data": [{"id":"1", "html": "Mensaje 1 
"},{"id":"2", "html": "Mensaje 2 
"}]}}

El problema es que este código no marca errores, incluso funciona correctamente cuando lo ejecuto en DevMode. Pero cuando hice el deploy en un servidor JBoss e intenté ejecutarlo, simplemente no me mostraba los mensajes pero tampoco registraba algún error en la consola. Después de muchísimas líneas de log.info() llegué a la conclusión que el problema era el casting del array. Intenté hacer un ‘cast’ de un array de tipo JavascriptObject[] a uno de tipo SystemMessage[]

    SystemMessage[] messages = (SystemMessage[]) array;

Para hacer el casting de un array en Java tenemos que hacer el casting elemento por elemento.

    SystemMessage[] messages = new SystemMessage[array.length];
    for(int i=0; i<array.length; i++){
        messages[i] = (SystemMessage) array[i];
    }

Nota: intenté utilizar el método Arrays.copyOf() pero éste no ha sido implementado en GWT. Si intentas utilizarlo te arrojará una error parecido al siguiente

The method copyOf(JavaScriptObject[], int, Class) is undefined for the type Arrays

Ubuntu – Convertir video para HTML5

Recientemente he estado trabajando en un proyecto donde es necesario insertar vídeo en un a página web. Para realizar esta tarea podemos utilizar la etiqueta de HTML5 ‘<video>‘. Bueno, pues para que nuestro vídeo se pueda ver en los navegadores principales -firefox, chrome, ie, opera, safari- es necesario tener al menos 3 fuentes (source) de vídeo en los formatos mp4 (h264), webm (vp8) y ogg (theora).

En Linux podemos utilizar el comando avconv -antes ffmpeg- de la siguiente manera:

avconv -i original.mov nuevo.mp4 nuevo.webm nuevo.ogv

tal vez sea necesario que instales el paquete libavcodec-extra. Con esto, al final tendremos 3 archivos nuevos con los formatos requeridos, ya sólo habría que agregar las fuentes a la etiqueta ‘<video>’

<video style="width: 640px; height: 360px;">
 <source src="videos/nuevo.mp4" type="video/mp4"></source>
 <source src="videos/nuevo.webm" type="video/webm"></source>
 <source src="videos/nuevo.ogv" type="video/ogg"></source>
 <!-- Opcionalmente insertar vídeo en flash para soportar navegadores antiguos -->
 Lo sentimos, tu navegador no soporta la etiqueta de video.
 </video>

Fuentes:
https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
http://paulrouget.com/e/converttohtml5video/

Ubuntu 12.04 – Convertir imágenes a PDF

Para convertir una serie de imágenes a un archivo PDF puedes ejecutar el siguiente comando en una terminal

convert *.jpg file.pdf

Este comando funciona siempre y cuando tengas instalado imagemagick, si no lo tienes, instalalo mediante

sudo apt-get install imagemagick gs

Las imágenes se agregaran al archivo en el mismo orden que aparecen con el comando ls, así que si las tienes numeradas de la siguiente manera

imagen1.jpg
imagen2.jpg

imagen10.jpg
imagen11.jpg

tendrás que renombrarlas a

imagen01.jpg
imagen02.jpg

imagen10.jpg
imagen11.jpg

para que te aparezcan en orden dentro del PDF

Fuentes:
http://www.ubuntu-es.org/node/36187 

GWT – JavascriptObject overlay types Map

Para facilitar el uso de servicios REST utilzamos JavascriptObject overlay types, los cuales nos permiten obtener un objeto a partir de una cadena JSON. Los overlay types sólo permiten ciertos tipos de datos como parámetros o valores de retorno. Entonces, para obtener un Map a partir de una cadena JSON como la siguiente, podemos utilizar la clase JSOHelper del framewrok SmartGwt:

{“id”:”menu1″,”opciones”:{“key1″:”value1″,”key2″:”value2″,”key3″:”value3”}}

tendríamos que hacerlo de la siguiente manera:

public class Menu extends JavaScriptObject{

public final native String getId()/*-{return this.id}-*/;

public final native JavaScriptObject getNativeOpciones()/*-{return this.opciones}-*/;

public final LinkedHashMap<String,String> getOpciones(){

LinkedHashMap<String,String> linkedMap=new LinkedHashMap<String,String>();

Map map=JSOHelper.convertToMap(getNativeOpciones());

Iterator iterator=map.entrySet().iterator();

while(iterator.hasNext()){

Map.Entry item=(Map.Entry)iterator.next();

linkedMap.put((String)item.getKey(),(String)item.getValue());

}

return linkedMap;

}

}

Fedora 15 – Convertir imágenes RAW a JPEG

Estoy muy feliz porque nos entregaron las fotografías de nuestra boda. Sin embargo, algunas imágenes estaban en formato RAW. El visor por default en Fedora 15, Shotwell 0.10.1, no puede abrir este tipo de imágenes. Intenté con Eye fo GNOME 3.0.1 y GIMP pero tampoco tuve éxito.

Para poder abrir las imágenes en GIMP puedes instalar el plugin ufraw

Pero lo que nosotros necesitabamos era convertir unas 1,434 fotografías de RAW a JPEG :-S
Lo bueno es que existe un programa llamado DCRAW que puedes ejecutar desde la línea de comandos para convertir una imagen. Por default convierte las imágenes al formato PPM, pero también existen otras utilidades –Netpbm– para convertir de PPM a JPEG
Bueno, pues lo primero es instalar DCRAW

luego instala Netpbm

ahora si, en una terminal ve al directorio donde tienes las imágenes y ejecuta el siguiente comando

for i in *.CR2; do dcraw -c -a -h $i | ppmtojpeg > `basename $i CR2`JPEG; echo $i done; done

asegurate de poner correctamente la extensión de los archivos -CR2 en el caso de las cámaras Canon– y recuerda que Linux es sensible a minúsculas y mayúsculas 😉

Fuentes:
http://ocaoimh.ie/2005/09/18/converting-raw-to-jpeg-in-linux/
http://www.cybercom.net/~dcoffin/dcraw/dcraw.1.html