Archive for noviembre, 2010

0 28
11
2010

Reflexión: la gran desconocida en la programación

Domingo, noviembre 28th, 2010

«En informática, reflexión (o reflexión computacional) es la capacidad que tiene un programa de ordenador para observar y opcionalmente modificar su estructura de alto nivel

Esta es la definición que aparece en wikipedia en referencia al concepto de reflexión en el mundo de la informática y la programación.

Es una definición un tanto abstracta, pero que nos permite intuir en qué consiste todo esto de la reflexión.

Siendo más concretos y prácticos, el uso de la reflexión a nivel de programación, nos permitirá, entre muchas otras cosas, crear instancias u objetos de dinámicamente de tipos concretos a partir del nombre de su clase. Podremos además, acceder a la información de los objetos, conociendo y/o ejecutando sus atributos y métodos públicos; y todo ello en tiempo de ejecución.

Vamos a plantear un pequeño ejemplo práctico de introducción al uso de reflexión en el lenguaje de programación Java.

Imaginemos la siguiente estructura de clases definida en el diagrama UML que se muestra a continuación.

Diagrama UML Reflexión

Reflexión en Java

Definiremos en primer lugar una clase abstracta denominada Vehicle. Esta clase padre define 2 métodos abstractos (acelerar/speedUp y frenar/brake) que deberán ser implementados por todas aquellas clases hijas que deseen heredar de Vehicle.

Clase (padre) Vehicle

package es.v3.test.reflection;

/**
 * Clase abstracta padre
 * @author v3rgu1.com
 */
public abstract class Vehicle {

    public String name;

    public abstract void speedUp();

    public abstract void brake();

}//Vehicle

A continuación crearemos 2 clases hijas que implementarán la clase abstracta padre Vehicle

Clase (hija) Car


package es.v3.test.reflection;

/**
 * Clase hija que hereda de Vehicle y representa un vehículo de tipo coche.
 * @author v3rgu1.com
 */
public class Car extends Vehicle {

    @Override
    public void speedUp() {
        System.out.println("Me llamo " + this.name + " y soy un coche que está acelerando");
    }

    @Override
    public void brake() {
        System.out.println("Me llamo " + this.name + " y soy un coche que está frenando");
    }

}//Car

Clase (hija) Motorcycle


package es.v3.test.reflection;

/**
 * Clase hija que hereda de Vehicle y representa un vehículo de tipo motocicleta.
 * @author v3rgu1.com
 */
public class Motorcycle extends Vehicle {

    @Override
    public void speedUp() {
        System.out.println("Me llamo " + this.name + " y soy una moto que está acelerando");
    }

    @Override
    public void brake() {
        System.out.println("Me llamo " + this.name + " y soy una moto que está frenando");
    }

}//Motorcycle

Una vez creadas estas 3 clases con las que llevaremos a cabo nuestros próximos ejemplos relacionados con la reflexión en programación, vamos a crear una clase ejecutable (main) con la que crearemos instancias en tiempo de ejecución de las clases hijas definidas anteriormente. Recuperaremos además la información de cada una de ellas y ejecutaremos sus métodos públicos sin previo conocimiento de ellos.

Pasaremos 2 argumentos a nuestra clase ejecutable por línea de comandos: el nombre de la clase a instanciar («Car» o «Motorcycle») y el nombre de nuestro vehículo.
Vamos a crear una instancia en tiempo de ejecución del tipo indicado en el primer argumento, para utilizar después sus métodos implementados speedUp & brake.

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        String nameClass = args[0];
        String nameVehicle = args[1];
        try {
            Class vehicleClass = Class.forName("es.v3.test.reflection." + nameClass);
            Field[] fields = vehicleClass.getFields();
            Method[] methods = vehicleClass.getDeclaredMethods();
            try {
                Vehicle vehicle = (Vehicle) vehicleClass.newInstance();
                vehicle.name = nameVehicle;
                vehicle.speedUp();
                vehicle.speedUp();
                vehicle.brake();
                for (int i=0; i<fields.length; i++) {
                    Field field = fields[i];
                    System.out.println("Campo '" + field.getName() + "': " + field.get(vehicle));
                }//for i
                for (int i=0; i<methods.length; i++) {
                    Method method = methods[i];
                    System.out.println("Voy ejecutar el método: '" + method.getName() + "'");
                    method.invoke(vehicle);
                }//for i
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }//main

Con la ayuda del API reflect de Java, hemos instanciado una clase sin conocer a priori el tipo de la misma y únicamente a partir de su nombre, pero veamos más en detalle las funciones utilizadas en el ejemplo.

java.lang.Class forName(String className) javadoc
Devuelve el objeto Class asociado a la clase o interface indicada en el nombre que recibe por parámetro.

java.lang.Object newInstance() javadoc
Crea una nueva instancia del objeto representado por la clase actual.

java.lang.reflect.Field[] getFields() javadoc
Retorna un array con todos los atributos con acceso público de la clase o interfaz representada.

java.lang.reflect.Method[] getMethods() javadoc
Devuelve un array que contiene todos los métodos públicos de la clase o interfaz representada.

java.lang.reflect.Method[] getDeclaredMethods() javadoc
Devuelve un array que contiene todos los métodos declarados en la clase o interfaz representada.

En próximo artículos, veremos cómo realizar este mismo ejemplo de reflexión en otros lenguajes de programación, así como el uso técnicas de reflexión más avanzadas.

0 24
11
2010

Incrementar el número de conexiones sobre IIS

Miércoles, noviembre 24th, 2010

A medida que desarrollas tus aplicaciones en .NET sobre el servidor IIS (Internet Information Server) seguramente te habrás encontrado en alguna ocasión con el siguiente error:

«403.9: Access Forbidden: Too many users are connected«

Esto ocurre porque por defecto el número máximo de conexiones concurrentes permitidas se limita a 10 conexiones.

A mí personalmente me ha ocurrido cuando he querido realizar alguna batería de pruebas con un número ligeramente más alto a lo normal.

Pues bien, un pequeño truco para aumentar el número máximo de conexiones concurrentes permitidas sobre IIS es ejecutar el script adsutil.vbs, que normalmente se encuentra en el directorio inetpub, desde la ventana de comandos

>
>cscript c:\inetpub\adminscripts\adsutil.vbs set w3svc/MaxConnections 40
>

De esta forma hemos incrementado el número máximo de conexiones sobre Internet Information Server a 40, recibiendo en nuestro terminal un resultado como el de la siguiente imagen.

adsutil - aumentar número de conexiones sobre Internet Information Server

Sólo nos queda ahora reiniciar el servidor IIS.

>
>iisreset
>
9 11
11
2010

DateDiff en C#

Jueves, noviembre 11th, 2010

Una de las funciones de Visual Basic que más echamos de menos a la hora de programar en C# es DateDiff.

Para aquellos que no la conozcan, la función DateDiff de Visual Basic (probablemente también os sonará de DateDiff de SQL Server) devuelve un valor numérico que especifica el número de intervalos de tiempo entre 2 fechas; o traducido al castellano, nos devuelve la diferencia entre 2 fechas.

Pues bien, ya que la función DateDiff no existe en sí en C#, vamos a proponer a continuación una alternativa a la misma:

/// <summary>
/// Demo DateTime.DateDiff
/// </summary>
public class DateTimeExtension
{

    /// <summary>
    /// Devuelve un valor Long que especifica el número de
    /// intervalos de tiempo entre dos valores Date.
    /// </summary>
    /// <param name="interval">Obligatorio. Valor de enumeración
    /// DateInterval o expresión String que representa el intervalo
    /// de tiempo que se desea utilizar como unidad de diferencia
    /// entre Date1 y Date2.</param>
    /// <param name="date1">Obligatorio. Date. Primer valor de
    /// fecha u hora que se desea utilizar en el cálculo.</param>
    /// <param name="date2">Obligatorio. Date. Segundo valor de
    /// fecha u hora que se desea utilizar en el cálculo.</param>
    /// <returns></returns>
    public static long DateDiff(DateInterval interval, DateTime date1, DateTime date2)
    {
        long rs = 0;
        TimeSpan diff = date2.Subtract(date1);
        switch (interval)
        {
            case DateInterval.Day:
            case DateInterval.DayOfYear:
                rs = (long)diff.TotalDays;
                break;
            case DateInterval.Hour:
                rs = (long)diff.TotalHours;
                break;
            case DateInterval.Minute:
                rs = (long)diff.TotalMinutes;
                break;
            case DateInterval.Month:
                rs = (date2.Month - date1.Month) + (12*DateTimeExtension.DateDiff(DateInterval.Year, date1, date2));
                break;
            case DateInterval.Quarter:
                rs = (long)Math.Ceiling((double)(DateTimeExtension.DateDiff(DateInterval.Month, date1, date2) / 3.0));
                break;
            case DateInterval.Second:
                rs = (long)diff.TotalSeconds;
                break;
            case DateInterval.Weekday:
            case DateInterval.WeekOfYear:
                rs = (long)(diff.TotalDays/7);
                break;
            case DateInterval.Year:
                rs = date2.Year - date1.Year;
                break;
        }//switch
        return rs;
    }//DateDiff
}

/// <summary>
/// Enumerados que definen los tipos de
/// intervalos de tiempo posibles.
/// </summary>
public enum DateInterval
{
    Day,
    DayOfYear,
    Hour,
    Minute,
    Month,
    Quarter,
    Second,
    Weekday,
    WeekOfYear,
    Year
}

Una vez que tengáis implementada vuestra función DateDiff en C#, podéis realizar alguna pequeña prueba comparativa con la función original DateDiff de Visual Basic para verificar que los resultados son los esperados en vuestras operaciones con fechas.

27 09
11
2010

Eliminar acentos y caracteres especiales en Java

Martes, noviembre 9th, 2010

En ocasiones nos puede resultar útil eliminar de una cadena de texto caracteres especiales, acentos o diacríticos (tíldes, diéresis, eñes, cedillas, etc).

Por ejemplo, en algunos sistemas de reservas aéreas o GDSs, como es el caso de Amadeus, necesitamos limpiar todos los textos que hacen referencia a nombres de pasajeros, direcciones y demás, de aquellos caracteres especiales no soportados por el sistema.

Vamos a ver 2 formas diferentes de eliminar estos caracteres especiales y acentos con 2 técnicas distintas:

1. Reemplazando cadenas de caracteres

    /**
     * Función que elimina acentos y caracteres especiales de
     * una cadena de texto.
     * @param input
     * @return cadena de texto limpia de acentos y caracteres especiales.
     */
    public static String remove1(String input) {
        // Cadena de caracteres original a sustituir.
        String original = "áàäéèëíìïóòöúùuñÁÀÄÉÈËÍÌÏÓÒÖÚÙÜÑçÇ";
        // Cadena de caracteres ASCII que reemplazarán los originales.
        String ascii = "aaaeeeiiiooouuunAAAEEEIIIOOOUUUNcC";
        String output = input;
        for (int i=0; i<original.length(); i++) {
            // Reemplazamos los caracteres especiales.
            output = output.replace(original.charAt(i), ascii.charAt(i));
        }//for i
        return output;
    }//remove1

2. Normalización Unicode. Descomposición canónica

Partamos en primer lugar del hecho de que un carácter puede ser representado de formas diferentes.
Visualicemos con un ejemplo estas diferentes formas de representar un mismo carácter:

        // Representación normal
        char c1 = 'í';
        // Representación UNICODE
        char c2 = '\u00ed';
        // Representación UNICODE en forma canónica
        char[] c3 = {'\u0069', '\u0301'};

¿En qué consiste la representación canónica?

La representación o descomposición canónica consiste simplemente (de forma muy resumida) en la descomposición del carácter en 2 partes:

– Parte 1: Letra base
– Parte 2: Acento

De esta forma, hemos podido representar el carácter i compuesto por la letra i (0x0061) y su acento (0x0301).

Una vez entendido el concepto de descomposición canónica, es hora de ponerlo en práctica para nuestro cometido: limpiar un texto de acentos y caracteres especiales obteniendo de esta manera un texto sólo de caracteres ASCII.

    /**
     * Función que elimina acentos y caracteres especiales de
     * una cadena de texto.
     * @param input
     * @return cadena de texto limpia de acentos y caracteres especiales.
     */
    public static String remove2(String input) {
        // Descomposición canónica
        String normalized = Normalizer.normalize(input, Normalizer.Form.NFD);
        // Nos quedamos únicamente con los caracteres ASCII
        Pattern pattern = Pattern.compile("\\p{ASCII}+");
        return pattern.matcher(normalized).replaceAll("");
    }//remove2

Comprobemos el resultado final de nuestras 2 técnicas:

        System.out.println("1. " + RemoveAccents.remove1("Mañana será un día mejor"));
        System.out.println("2. " + RemoveAccents.remove1("Mañana será un día mejor"));
0 03
11
2010

Registros aleatorios en MySQL

Miércoles, noviembre 3rd, 2010
En ocasiones necesitaremos en nuestras aplicaciones obtener un listado de registros aleatorios de la Base de Datos.
Esta opción puede ser útil por ejemplo, a la hora, de tener en nuestro blog una sección de posts o entradas aleatorias.

Para ello, podemos hacer uso de la ordenación aleatoria de MySQL: ORDER BY RAND()

SELECT * FROM wp_posts <strong>ORDER BY RAND()</strong>;

Si además combinamos ORDER BY RAND con LIMIT, podremos limitar el número de resultados aleatorios dentro del conjunto total de registros:

SELECT * FROM wp_posts <strong>ORDER BY RAND()</strong> LIMIT 10;

IMPORTANTE: ¡Ojo!, ten en cuenta que esta opción es factible siempre y cuando la tabla de la que obtendremos los registros no sea muy grande, con la idea de que no afecte de forma negativa al rendimiento de tu base de datos.

0 03
11
2010

Botones compartir en blogger

Miércoles, noviembre 3rd, 2010

Hace algunos meses ya que Blogger añadió la conocida y utilizada funcionalidad de botones para compartir en redes sociales como Facebook, Twitter o Google Buzz; o simplemente a través de Blogger o GMail.

Sin embargo, en algún otro blog que tengo sobre la plataforma blogger, no me había animado todavía a realizar el cambio, ya que disponía de los botones implementados por código puro y duro en la plantilla html directamente.

Así que vamos a realizar el cambio:

  1. 1. Dentro del escritorio de blogger, nos dirigimos a Diseño –> Elementos de la Página –> Entradas del Blog
  2. 2. Una vez en la página de configuración: «Configurar entradas del blog», activamos la opción «Mostrar botones para compartir«
  3. 3. No olvides guardar tus cambios

botones compartir en blogger

Así de fácil, ya deberíamos disponer del bloque de botones para compartir en redes sociales y mail las entradas de nuestro blog alojado en blogger.

¿Y si todavía no veo los botones?

Si ya has activado la opción de «Mostrar botones para compartir» pero sigues sin visualizarlos, lo más probable es que tengas una plantilla modificada, por lo que necesitarás añadir los botones de forma semi-manual.

Para ello realiza los siguientes pasos:

  1. 1. Dentro del escritorio de blogger, dirígete a Diseño –> Edición de HTML
  2. 2. Una vez en la edición de la plantilla, activa la opción de «Expandir plantillas de artilugios
    <div class='post-footer-line post-footer-line-3'>
    <p class='post-footer-line post-footer-line-3'>
    
  3. 3. Busca cualquiera de los 2 códigos siguientes:
  4. 4. Añade el siguiente código:
    <!-- Botones para compartir en blogger -->
    <div class='post-share-buttons'>
        <b:include data='post' name='shareButtons'/>
    </div>
    
0 01
11
2010

Bordes redondeados con CSS

Lunes, noviembre 1st, 2010

Vale, lo reconozco, me encanta plantar bordes redondeados en las páginas que desarrollo.

Sin embargo, es una propiedad la de los bordes redondeados en CSS que todavía no es soportada de forma nativa en todos los navegadores del mercado.

Vamos a ver a continuación un resumen rápido de cómo trabajar con esta propiedad de bordes redondeados con CSS en aquellos navegadores que ejecutan este efecto de forma nativa: border-radius.

¿Qué navegadores lo soportan?

Como siempre, hay un navegador que se queda por el camino, y éste no podía ser otro que Internet Explorer.

El resto de navegadores, Firefox (Gecko), Safari, Chrome o incluso Opera (más recientemente) han incorporado ya el soporte de bordes redondeados con css, aunque bien es cierto que cada uno usando nombres diferentes para la propiedad.

¿Cómo se implementa?

Utiliza border-radius para versiones recientes de Opera y Chrome

Ejemplo:

border-radius: 5px;

Utiliza -moz-border-radius para Firefox (motor Gecko)

Ejemplo:

-moz-border-radius: 5px;

Utiliza -webkit-border-radius para Safari o Chrome

Ejemplo:

-webkit-border-radius: 5px;

¿Qué ocurre entonces en Internet Explorer?

Nada, simplemente volverás al mundo de las esquinas.

¿Todas las esquinas llevan el mismo radio?

No tiene porqué. Al igual que pasa con propiedades como padding o margin, border-radius cuenta también con 4 valores posibles, comenzando por el valor superior izquierdo, y siguiendo según el sentido de las agujas del reloj.

Por lo tanto, podremos generar efectos como estos:

        .sample {
            width: 250px;
            height: 100px;
            background-color: #CDEB8B;
            border: solid 1px #008C00;
            margin-top: 25px;
            margin-bottom: 25px;
        }
        .rounded {
            -moz-border-radius: 50px;
            -webkit-border-radius: 50px;
            -ms-border-radius: 50px;
            border-radius: 50px;
        }
        .rounded2 {
            -moz-border-radius: 50px 50px 0px 0px;
            -webkit-border-radius: 50px 50px 0px 0px;
            -ms-border-radius: 50px 50px 0px 0px;
            border-radius: 50px 50px 0px 0px;
        }
        .rounded3 {
            -moz-border-radius: 50px 0px 50px 0px;
            -webkit-border-radius: 50px 0px 50px 0px;
            -ms-border-radius: 50px 0px 50px 0px;
            border-radius: 50px 0px 50px 0px;
        }

Vaya coñazo

Pues sí, para qué negarlo. Aún así, si te apetece puedes darte una vuelta por el servicio web border-radius.com que te permite de forma visual generar el código CSS que necesites para el resultado que desees.