viernes, 28 de junio de 2013

Reglas propias para validación de formularios con CodeIgniter. Carga de archivos.

En el artículo anterior “Validación de formularios con CodeIgniter”, se comentaba sobre la importancia de validar los datos de entrada por formularios en nuestra aplicación web, así como sanearlos, formatearlos y prepararlos para la inserción en la base de datos, de forma que mantengamos la integridad de la BD y el funcionamiento del servidor y el sitio web.

Comentaba también sobre el uso del FormValidation de CodeIgniter, que nos permite asociar reglas existentes (como required) a los componentes visuales, con lo cual se mostrarán mensajes de errores predefinidos, a los cuales les podemos dar el formato de salida que queramos.

A todo esto, podemos adicionar reglas y mensajes propios, y es sobre esto que quiero compartir mis recientes experiencias.

Parto de la necesidad que tuve de subir al servidor un archivo de imagen (un avatar para los usuarios de mi sistema). Con el siguiente código incorporas el componente visual que te permite escoger un fichero.

<input type="file" name="userfile_pic" >

clip_image001

El input de tipo file permite seleccionar ficheros cuyos datos puedes acceder a través de las variables de php$HTTP_POST_FILES o $_FILESa partir de PHP 4.1.0. Por ejemplo puedes usar:

$HTTP_POST_FILES['userfile_pic']['name'];
//nombre original del fichero en la PC cliente
$HTTP_POST_FILES['userfile_pic']['type'];
//tipomime delfichero, ej. "image/gif"
$HTTP_POST_FILES['userfile_pic']['size'];
//tamaño del fichero


Lo primero que debes notar es que he usado el nombre del componente tipo file dentro del primer corchete. La mayoría de los ejemplos que puedas encontrar toman por defecto el nombre userfile, pero debes tener cuidado de que el nombre coincida con el que has puesto en la vista.

Si pruebas este código es probable que obtengas un mensaje de que no se ha seleccionado ningún fichero. En ese caso seguramente te faltó poner tu formulario comomultipart. Usando CodeIgniter lo pones así:

<?php echo form_open_multipart('direccion_fichero_script');?>

Bueno, si decides continuar con php básico, utilizas el is_uploaded_file(), que te sube el archivo y te retorna el error en caso de haberlo. Pero mi propósito es usar FormValidation para asegurarme de que el fichero es válido, usando el mismo mecanismo de validación que para el resto de los componentes visuales.

Para esto empleamos la clase de subir ficheros de CodeIgniter.En el siguiente ejemplo he indicado la carpeta hacia la que voy a subir el fichero en el servidor, el tipo de fichero que quiero recibir (* para cualquier tipo), el tamaño máximo de fichero y el ancho y alto, pues en mi caso voy a subir imágenes.El overwrite permite sobrescribir los ficheros en el servidor. He cargado la clase upload que trae CodeIgniter en una de sus bibliotecas, y al cargarla le he pasado mi configuración. También he capturado el error en caso de haberlo.do_uploadintentasubir el fichero.

function valid_file()

{

$config['upload_path'] = './uploads/';

$config['allowed_types'] = 'gif|jpg|png';

$config['overwrite'] = TRUE;

$config['max_size'] = '100';

$config['max_width'] = '1024';

$config['max_height'] = '768';

$this->load->library('upload', $config);

if ( ! $this->upload->do_upload()){

$error = array('error' => $this->upload->display_errors());



}

else



}


Hasta ahí el código funciona si el componente visual se llama userfile, que es el que espera CodeIgniter por defecto. Si el nombre es otro, como en mi ejemplo, basta decir:

$this->upload->do_upload('userfile_pic');


Bien, ahora transformaremos la función anterior para combinarla con FormValidation. Te pongo solamente el segmento que cambia:

function valid_file()

{



if ( ! $this->upload->do_upload('userfile_pic'))

{

$error = array('error' => $this->upload->display_errors());

$this->form_validation->set_message('valid_file',$error);

return FALSE;

}

else

{

return TRUE;

}

}

Si se cargó retorno TRUE, sino retorno FALSE y declaro que el mensaje de error para la función valid_file es $error. En lugar de $error puedes poner un mensaje propio, pero aquí reutilizo el que me retorna CodeIgniter que es más informativo.

Ahora creamos la regla para validar el componente userfile_pic. Esto lo pones en la función donde haces la validación de los demás componentes. El detalle está en ponerle callback_ a la función que hace el chequeo.

$this->form_validation->set_rules('userfile_pic', 'Imagen', 'callback_valid_file');

Esta es la manera de crear nuevas reglas, haces una función que revise lo que quieres validar y que retorna verdadero o falso (para que funcione el if ($this->form_validation->run() == FALSE)), y creas una regla poniendo callback_nombre_de_la_funcion.

Si resultó positivo puedes acceder al nombre del fichero, que ya está en el servidor, a través del mismo$_FILES['userfile_pic']['name'], y guardar el nombre en la base de datos.

Si quieres subir varios ficheros desde un mismo formulario, puedes ponerle a todos los input files el mismo nombre con corchete (ej. file_name[]), y accedes a ellos a través de:

$_FILES['filename']['name'][0];

$_FILES['filename']['name'][1];



O puedes ponerles nombres distintos y usar

$this->upload->do_upload('filename1');

$this->upload->do_upload('filename2');



Bueno, como puedes ver no es complicado crear nuevas reglas de validación. A la vez, hemos usado otra clase de CodeIgniter que nos permite cargar ficheros, demostrando así sus potencialidades para desarrollar sitios seguros, funcionales y con un código organizado, necesario para posteriores mantenimientos.

{ Leer Más }


jueves, 27 de junio de 2013

Sugerencias para usar ZK 6.5.x en dispositivos móviles.

clip_image002

A partir de la versión 6.5 del Framework ZK, los desarrolladores pueden aprovechar el poder de ZK para crear una aplicación web, que funcione correctamente en dispositivos móviles como una tableta (Tablet, en inglés).

Como ya sabemos, existen diferencias entre el hardware de una tableta y un PC, debemos pensar diferente en la fase de diseño, teniendo en cuenta cada detalle que necesita ser ajustado para que se vea como esperamos en todos los dispositivos, y por lo tanto consigamos proveer de una buena experiencia al usuario en ambos. A continuación mostraremos como puedes controlar y usar ZK 6.5 para hacer el mejor uso de él.

Diferentes estilos

En una tableta, los usuarios operan con sus dedos, mediante interacciones de tipo táctiles, por lo tanto el tamaño de los componentes en los que tiene que hacer clic (por ejemplo botones) no puede ser muy pequeño, 24px x 24px es el límite.

Por otra parte, si el tamaño del componente es pequeño, el espacio entre componentes debe ser grande, para evitar que el usuario pulse los botones cercanos por error.

ZK ha ajustado los componentes de acuerdo a este principio, por ejemplo Combobox,Timebox y Colorbox, los desarrolladores ahora pueden usarlos en un dispositivo móvil directamente. Para más detalles, te recomendamos que leas: UI Enhancements.

Diferentes eventos:
Eventos de Ratón

Como no hay ratón o cursor en las tabletas, los eventos relacionados con el ratón son diferentes que en el escritorio tradicional.

Primero de todo, onMouseOver no está soportado, tooltip y autodrop tampoco funcionan en una tablet. Segundo, onRightClick no está soportado directamente por el browser nativo como evento, pero ZK simula este evento del siguiente modo "pulsar y aguantar pulsado un momento", por lo tanto la propiedad context (que muestra el menú contextual) y onRightClick pueden ser usados en una tablet.

Por otra parte, si a Image o Div se les añade la propiedad onClick, los desarrolladores deben añadir el CSS cursor: pointer; en el atributo sclass o style, para que el navegador del tablet pueda gestionar la propiedad onClick correctamente.

ClientInfoEvent

Los usuarios pueden cambiar fácilmente la orientación de la tablet, por lo tanto los desarrolladores tienen que poder identificar cual es la orientación que los usuarios están usando y aplicar los cambios necesarios al tamaño y diseño. ZK 6.5 añade esta información sobre la orientación en el objeto ClientInfoEvent, simplemente añadimos atributo de evento onClientInfo para obtener el objeto ClientInfoEvent y accedemos a su método getOrientation(), isPortrait() o isLandscape().

Por ejemplo:

<tabbox id="tbx" height="400px" width="600px">
<attribute name="onClientInfo"><![CDATA[
ClientInfoEvent oe = (ClientInfoEvent) event;
lbl.setValue(oe.getOrientation());
if (oe.isPortrait()) {
tbx.setHeight("600px");
tbx.setWidth("400px");
} else {
tbx.setHeight("400px");
tbx.setWidth("600px");
}
]]></attribute>
<tabs>
<tab label="tab 1" />
</tabs>
<tabpanels>
<tabpanel>
Current Orientation:
<label id="lbl" />
</tabpanel>
</tabpanels>
</tabbox>


Otras consideraciones acerca del scrolling

En el artículo Scrolling on Tablet se realizó un análisis sobre el principio básico de scroll en tablets.

A continuación, discutiremos a cerca de algunos componentes muy comunes que puede que uses en tu implementación.

· Para crear un nuevo text area, puedes usar <textbox multiline="true" />cuando el contexto es grande, puedes hacer scroll en el componente Textbox. Este comportamiento lo maneja directamente el navegador, nada que ver con ZK, por lo tanto, su comportamiento será diferente de otros componentes en los que es ZK quien controla el scroll.

· Si el sistema contiene un Image, el desarrollador debe especificar el tamaño para o activar la precarga mediante el atributo a tal efecto, de cualquier otro modo, el scroll no funcionará como se espera. Veamos un ejemplo a continuación.

<zk>
<window contentStyle="overflow:auto" height="300px" border="normal">
<image src="http://www.zkoss.org/resource/img/index/src/top_bannerimage3.png" />
<div>bottom</div>
</window>
</zk>

En este caso, Window no producirá una barra de scroll, el usuario final de la aplicación no podrá ver la imágen entera, puesto que no podrá hacer scroll de la misma.

Esto se soluciona de 2 formas, 1. Activando el atributo de preload como en el siguiente ejemplo.

<zk>
<window contentStyle="overflow:auto" height="300px" border="normal">
<custom-attributes org.zkoss.zul.image.preload="true"/>
<image src="http://www.zkoss.org/resource/img/index/src/top_bannerimage3.png" />
<div>bottom</div>
</window>
</zk>

2. O indicando el tamaño de la imagen, como en el siguiente ejemplo:

<zk>
<window contentStyle="overflow:auto" height="300px" border="normal">
<image height="500px"
src="http://www.zkoss.org/resource/img/index/src/top_bannerimage3.png" />
<div>bottom</div>
</window>
</zk>

Nuestra recomendación es activar el atributo de precarga en el fichero de configuración zk.xml para evitar tener que hacerlo en todas las imágenes, una a una.

· No te recomendamos que asignes el número de filas en el componente Listbox, es decir que no establezcas ningún valor en el atributo rows, como en el siguiente ejemplo.

<zk>
<zscript> String[] s = new String[100]; </zscript>
<listbox id="lbx1" height="300px">
<zk forEach="${s}">
<listitem label="${forEachStatus.index + 1}" />
</zk>
</listbox>
<listbox id="lbx2" rows="8">
<zk forEach="${s}">
<listitem label="${forEachStatus.index + 1}" />
</zk>
</listbox>
</zk>

En el iPad, solo una pequeña parte de los 10 elementos del componente lbx1 es visible, el usuario final verá que es incompleto y hará scroll de forma natual. Este efecto no es el mismo en el componente lbx2, puesto que hemos establecido el número de filas "rows" a un valor. Esto sucede de igual modo en los componentes Grid y Tree.

Tan simple como sea posible

Como hemos mencionado antes, el tamaño de la pantalla en tablets o teléfonos móviles es mucho más pequeño y los componentes crecen respectivamente para facilitar al usuario final la interacción con ellos. Por lo tanto, no es prudente crear un diseño complejo para que los usuarios interactuen con él meticulosamente.

La potencia de procesar es mucho menor en un tablet que en un PC tradicional. El tiempo de renderizado en un ordenador de escritorio, puede ser lo suficientemente breve como para ignorarlo, pero puede ser un problema en una tablet. Por lo tanto el diseño de websites para tableta siguiendo el concepto "Tan simple como sea posible" es muy importante.

Otra forma de mejorar la velocidad de rendimiento es activar el atributo ROD de los componentes de tipo Listbox, Grid y Tree.

Conclusión

ZK 6.5 provee de la habilidad de crear aplicaciones web para el escritorio y la tableta desde el mismo código de base. Pero teniendo en cuenta a la hora de desarrollar algunas de las diferencias a las que hemos apuntando.

Envíenos sus comentarios.

{ Leer Más }


miércoles, 26 de junio de 2013

Fortalezas de ZK

clip_image002

Desde hace algunos días en nuestro blog se han publicado artículos relacionados con el Framework de código abierto ZK. Hoy queremos retomar algunos temas iniciales de este Framework, para profundizar luego en otros elementos.

Para comenzar podemos decir que ZK constituye una de las opciones más eficientes para desarrollar aplicaciones web dinámicas con Java. Los desarrolladores de ZK se han propuesto que la implementación de interfaces de usuario (GUI) en Ajax sea mucho más fácil de realizar.

Uno de los elementos más interesantes del Framework es que el desarrollador no tiene que preocuparse del JavaScript en su capa de presentación. ZK permite desarrollar aplicaciones web AJAX similar a como se desarrollaba en las aplicaciones de escritorio.

Profundizando un poco más en el tema podemos decir que ZK es un Framework basado en componentes de interfaz de usuario. Te permite crear aplicaciones ricas de internet (RIA) y aplicaciones móviles sin tener que aprender JavaScript o Ajax. Puedes construir aplicaciones altamente interactivas y hacerlas responsive mediante Ajax únicamente programando en Java. ZK pone a tu disposición miles de componentes que están diseñados para varios propósitos, algunos para manejar grandes cantidades de datos y otros para recoger los datos que el usuario introduce. Además puedes usar nuestro lenguaje XML para crear las interfaces: ZUL.

Toda interacción que un usuario realice sobre una página, como hacer clic y escribir puede ser manejada en un Controlador de forma muy simple. Puedes usar los componentes para que respondan a la interacción del usuario en un controlador y estos cambios serán actualizados en los navegadores automáticamente. No necesitas preocuparte sobre los detalles de la comunicación entre el navegador y el servidor, ZK lo maneja por ti.

Adicionalmente para el manipular directamente componentes, como requiere el patrón MVC (Modelo-Vista-Controlador), ZK también pone a tu disposición otro patrón de diseño MVVM (Modelo Vista VistaModelo) que permite mayor separación entre el controlador y la vista. Estos 2 enfoques son totalmente intercambiables, únicamente siendo tú quien eliges en función de tu arquitectura

Arquitectura de ZK

clip_image003

La imagen anterior es la arquitectura de ZK simplificada.

Cuando un navegador visita una página de una aplicación hecha con ZK, ZK crea los componentes que definan el fichero ZUL y los renderiza en el navegador. Puedes manipular los componentes directamente desde el controlador para implementar la lógica de la vista. Todos los cambios que hagas en los componentes será automáticamente reflejado en el navegador del usuario y ZK se encarga de abstraerte de la comunicación.

En próximas entradas continuaremos abordando nuevos elementos de ZK, pero de momento le sugerimos revisar las demostraciones (ver en: ZK Demo) que han creado sus desarrolladores.

Envíenos sus comentarios.

{ Leer Más }


martes, 25 de junio de 2013

Introducción a Vaadin. Un framework JAVA para RIA.

clip_image002

Ya en el blog hemos visto varias entradas sobre ZK, un framework RIA muy usado para el desarrollo en aplicaciones empresariales basadas en JAVA.

En esta entrada queremos introducir otro framework que tiene el mismo objetivo aunque un enfoque y arquitectura diferente. Se trata de Vaadin.

Cuando revisamos el sitio de Vaadin hay una frase que nos engancha al momento: “Vaadin es un framework JAVA para la construcción de aplicaciones web modernas que lucen genial, tiene un buen rendimiento y te hacen a ti a tus usuarios felices”.

Al referirnos a aplicaciones web modernas no hablamos de JSP + JavaScript, hablamos de aplicaciones RIA, o sea Rich Internet Applications, que no son otra cosa que aplicaciones enriquecidas con facilidades que las hacen similares a las aplicaciones de escritorio pero con la ventaja de estar colgadas en la web.

Algunas de las características de este framework son las siguientes:

  • Java-only programming: solo hay que saber java, nada de html ni javascript.
  • No JavaScript programming
  • Custom application theme support: nos permite customizer nuestras UI
  • Partial page updates: las actualizaciones de las páginas son parciales.
  • Template based HTML layouts
  • Event-listener model: tiene un modelo basado en eventos y listener.
  • Embed to a HTML or JSP page: se puede embeber en HTML o páginas JPS.
  • Supported Web Browsers:
    • Internet Explorer releases 6, 7, and 8
    • Mozilla Firefox 3o
    • Safari 3 and 4
    • Opera 9.6
    • Chrome.
  • Single Jar-file deployment: el despliegue solo requiere un jar, el war de ejemplo solo tiene el jar de vaadin.
  • Compatible with Fire bug debugger
  • Server-side application state management
  • Application logic executed in server: todo se ejecuta del lado del servidor.
  • Java Servlet API 2.3 Compatible
  • Rn as portlet in a JSR-168 compatible portal: nos permite desplegar portlets de Vaadin en portales como LIFERAY.

A estas habría que sumarte que se apoya en GWT lo que implica que disponemos de un gran número de componentes.

Enlaces interesantes:

  • Si quieren ver un tutorial paso a paso pueden entrar aquí. Si prefieren un libro igual lo tienen.
  • Si quieren ver un ejemplo pues van a este otro enlace.
  • Si quieren descargar el framework pues pincha aquí.
  • Revisando me he encontrado este otro enlace para el libro.

clip_image003

Otros temas interesantes son que:

  • Tiene plugins para los principales IDEs: Eclipse y Netbeans.
  • Presenta facilidad relativa para integrarse con Spring, es algo que está cocinándose aún pero ya hay sus iniciativas como pueden ver aquí y aquí.
  • Ofrece un amplio abanico de componentes y recientemente han lanzado un appmarket donde están disponibles componentes gratis y bajo pago a su disposición.
  • Está siendo usado para el desarrollo de soluciones BPM combinado con Activiti, una herramienta que ya hemos tocado en otras entradas y que dentro de poco veremos nuevamente.

Para terminar:

Aquí les dejo algunas buenas entradas donde se explican ejemplos de uso de vaadin en español e inglés para aquellos que se quieran iniciar. Dentro de poco también estaremos incluyendo ejemplos prácticos del uso de Vaadin.

{ Leer Más }


lunes, 24 de junio de 2013

Introducción al diseño e implementación de un proceso con la herramienta BPMS Bonita.

Como ya se ha visto en otras entradas del blog existen varias herramientas BPMS en el mundo Open Source que están a la altura de muchas de las herramientas propietarias del mercado.

En algunos casos aún les falta un camino por delante como es el caso de Activiti y en otros casos ya pueden ser usadas en ambientes de desarrollo como la herramienta Bonita que nos ocupa en esta entrada y en varias más.

Comenzaremos con el diseño de un proceso que nos dará pie a ir mejorando su diseño, implementación, simulación y pruebas hasta desplegarlo en un entorno real.

Descripción del proceso:

El proceso se encarga de permitir que un cliente de una tienda pueda acceder al sitio online de la tienda, seleccionar varios artículos los cuales deben ser aprobados por un empleado de forma manual, esto puede llevar a que el cliente compre los artículos con su tarjeta de crédito, o a que rechace la compra o a que se pida más información sobre los artículos a comprar. Si se ejecuta el pago entonces los artículos serán enviados al cliente en 3 días hábiles y la transacción será archivada, en caso de que se rechace la compra también se archiva la transacción. En cualquier caso se da por terminado el proceso.

En esta entrada veremos como diseñar este simple proceso usando la herramienta Bonita.

Lo primero es descargar la herramienta Bonita, lo cual pueden hacer desde este enlace www.bonitasoft.com/products/download/ si ya tienes una cuenta creada, si no la tienes aun pues la creas y listo, es gratis.

En nuestro caso hemos descargado:

BonitaBPMCommunity-6.0.0-x86.exe que será la herramienta con la que trabajaremos hoy y también BonitaBPMCommunity-6.0.0-Tomcat-6.0.35.zip que es el servidor tomcat donde podremos correr nuestras aplicaciones.

Luego de instalar la herramienta Community podemos ejecutarla y verán la siguiente pantalla al inicio.

clip_image001

Una vez abierta la herramienta se les mostrará esta pantalla donde podrán tener acceso a múltiples recursos online que van desde documentación, ejemplos, y video tutoriales que los ayudarán a comprender como usarla.

clip_image003

Para este ejemplo crearemos un proceso que es uno de los tutoriales básicos de la herramienta y que nos permitirá ir viendo paso a paso como usarla.

Así que crearemos un diagrama nuevo y agregaremos una actividad de inicio “Inicio1” usando la paleta de componentes a nuestra izquierda y luego dando clic encima de ella veremos que en la esquina superior derecha nos aparece u pequeño rectángulo, damos clic en él y lo sostenemos y lo arrastramos hacia la derecha de esta manera habremos creado una nueva tarea como se aprecia en la siguiente imagen. Si damos clic sobre esta nueva tarea podemos introducir información general sobre la misma. Como se puede apreciar hemos cambiado su nombre, descripción y tipo de tarea. Esta tarea recibe una solicitud de una compra la cual debe ser revisada de forma manual por un empleado de ventas.

clip_image005

Si volvemos a realizar el paso anterior pero esta vez resaltando la tarea recién creada podremos crear una nueva tarea, “Pagar”, donde se completa la información del pago por la compra que se está realizando.

clip_image007

Puede darse el caso de que la información introducida de la tarjeta de crédito no sea válida o que no se desee terminar la compra así que damos la opción de otra tarea “Rechazar” la cual es creada a partir de la primera actividad.

clip_image009

Llegados a este punto hemos visto que de forma muy fácil podemos ir creando tareas conectadas entre sí y modificar su información general para lograr un diseño adecuado y entendible del proceso.

Ahora podemos editar el pool sobre el que estamos trabajando y cambiamos su nombre y descripción.

Deben ver un pool como ese rectángulo horizontal que delimita la zona donde hemos puesto las tareas hasta el momento.

clip_image011

Par realizar la edición solo tienen que marcar el nombre del pool y luego en General -> Pool darle al botón “Editar”.

Después de terminada esta acción debemos agregar otras tareas más:

  • Entrega express que nos permite una vez realizada la compra entregarle sus artículos al cliente en el plazo de 3 días.
  •  Más Información para el caso en que el empleado de ventas requiera más detalles sobre la compra que se desea realizar.
  •  Archivar que nos permite guardar la transacción realizada cualquiera sea su terminación. Por eso es que tanto el pagar como el rechazar como la entrega express llevan a “Archivar”.

clip_image013

Llegado este punto nos damos cuenta que la tarea de “Más Información” nos permite recopilar la información pero no es devuelta al empleado que está revisando la compra, así que para ello introducimos un nuevo elemento. En este caso un XOR, que en BPMN no es otra cosa que el mecanismo que nos permite crear una compuesta con múltiples entradas que la conectan.

Para seleccionar el elemento pueden ir a la paleta de componentes.

clip_image014

La cual aparece a la izquierda en la herramienta y seleccionar el ícono correspondiente y arrastrarlo al proceso. Deben entonces eliminar la conexión de “Inicio1” con “Revisión por ventas”, agregar el componente XOR y reorganizar las conexiones tal y como se ve en la siguiente imagen. De esta manera ya el empleado de ventas se puede enterar de la nueva información.

clip_image016

Y eso esto, de una forma bastante rápida hemos diseñado un proceso en BONITA y estamos listos para el siguiente paso que será agregar las variables que nos permitirán manejar la información de cada tarea y del proceso de forma global, lo cual estaremos realizando en la siguiente entrada.

{ Leer Más }


jueves, 20 de junio de 2013

Introducción a Qt Quick Layouts.

clip_image001

Si usted quiere crear una aplicación QML donde la UI (interfaz de usuario) responda bien cuando se redimensiona la ventana, las herramientas que ofrece Qt Quick son algo limitadas. Con la llegada de Qt 5.1 los programadores contaran con una nueva versión de Qt Quick que ofrece novedosas herramientas como RowLayout, ColumnLayout y GridLayout que serán muy útiles para alcanzar este propósito [1].

Introducción

Antes de la llegada de Qt 5.1, Positioners y Anchors eran las únicas herramientas disponibles en Qt Quick para ordenar elementos en las UI.

Positioners eran adecuados para adicionar muchos elementos, pero no siempre eran útiles para crear una UI que fuera posible redimensionarla, pues ellos solo posicionan los elementos (el ancho y el largo se mantenían iguales).

Anchors permitían un poco más de flexibilidad, a costo de la claridad del código. Con anchors usted puede hacer que un elemento se estreche vinculando uno de sus bordes con el correspondiente borde del padre, y estableciendo un vínculo similar con los elementos en el borde opuesto. Sin embargo, usted no puede hacer que muchos elementos se distribuyan ellos mismos si la ventana se redimensiona.

La última opción es que usted mismo haga un posicionamiento en capas manual. Esto ofrece gran flexibilidad, pero se necesita mucho código, es difícil y propenso a errores. Durante el desarrollo de Qt Quick Controls, para la nueva versión de Qt 5.1 se tuvieron en cuenta estos elementos y se decidió proveer a los desarrolladores un sistema de capas (layout system) más eficiente.

import QtQuick.Layouts 1.0

Incluyendo el import de arriba usted tendrá disponibles en sus herramientas a los componentes RowLayout, ColumnLayout y GridLayout. Estos componentes de tipo layouts, funcionan de forma similar a sus homólogos que encontramos en el módulo QtWidgets: QHBoxLayout, QVBoxLayout y QGridLayout. Ellos además tratan de combinar con el API de otros elementos QML como: Row, Grid and Column. De esta forma si usted está familiarizado con alguna de estas APIs, usted encontrara a Qt Quick Layouts fácil de usar.

La alineación (Alignment) de los elementos dentro de una celda puede ser especificada con la propiedad Layout.alignment.

El espaciado (Spans) dentro de las filas y las columnas puede ser especificado con las propiedades the Layout.rowSpan y Layout.columnSpan.

Las coordenadas de la cuadricula (Grid coordinates) pueden ser especificadas con las propiedades Layout.row y Layout.column.

Los elementos que pueden ser redimensionados (Resizable items) se pueden especificar con las propiedades Layout.fillWidth y Layout.fillHeight. Esta fue la meta principal de Qt Quick Layouts.

Los tamaños mínimos, preferidos y máximos (Minimum, Preferred and Maximum) pueden ser especificados con las propiedades Layout.minimumWidth, Layout.preferredWidth y Layout.maximumWidth (“Width” puede ser reemplazado con “Height” para especificar restricciones similares en el alto)

Este conjunto de características sumadas parecería no ser de gran impacto, pero el hecho de que usted pueda tener en un mismo layout elementos que se estiran y otros que no se estiran, puede facilitar muchos las cosas y permite trabajar de forma intuitiva con los componentes.

Ejemplo

clip_image002

Suponga que usted necesita crear una barra de herramientas (ToolBar) con dos botones (buttons) y un deslizante (slider) que ocupe el espacio restante. Cuando cambie la dimensión, el espacio extra será ocupado por el deslizante (slider).

Sin usar Qt Quick Layouts, la solución con menos código seria usar una mezcla entre una fila (Row) y el uso de anchors:

ToolBar {

Row {

id: row

spacing: 2

anchors.verticalCenter: parent.verticalCenter

ToolButton { iconSource: "images/go-previous.png" }

ToolButton { iconSource: "images/go-next.png" }

}

Slider {

anchors.left: row.right

anchors.leftMargin: 2

anchors.verticalCenter: parent.verticalCenter

anchors.right: parent.right

}

}


Con Qt Quick Layouts, todos los elementos pueden ser adicionados en un mismo layout:

ToolBar {

RowLayout {

anchors.fill: parent

spacing: 2

ToolButton { iconSource: "images/go-previous.png" }

ToolButton { iconSource: "images/go-next.png" }

Slider { Layout.fillWidth: true }

}

}


Note que la declaración es mucho más corta para el elemento Slider. También note que cuando usa Qt Quick Layouts, el espaciamiento solo necesita ser especificado una vez. El código se reduce de 288 a 172 caracteres (excluyendo los espacios en blanco), lo que representa un 40% de reducción.

Resumen

En este ejemplo, haciendo uso de Qt Quick Layouts, hemos obtenido un 40% menos de código, mejorando la legibilidad (no solo porque el código sea más corto sino también porque la estructura del código se parece más a la estructura de la UI).

Si usted quiere redimensionar la UI, usted probablemente encontrara que Qt Quick Layouts es mucho más fácil de usar que anchors, posicioner y posicionamiento manual.

Quedamos en espera de sus comentarios.

{ Leer Más }


miércoles, 19 de junio de 2013

Un ejemplo de combinación de la Computación en la Nube y las Bases de Datos No SQL.

clip_image001

La computación en la Nube y el software como servicio están siendo muy populares desde hace un más de años. Lo cierto es que todo el mundo habla de estas cosas pero muy pocos pueden mostrar escenarios reales positivos. Claro, esto no significa que no sea una apuesta 100% a considerar en el mundo tecnológico de hoy.

Por solo hacer una mención WSO2, la empresa de Sri Lanka que tanto está dando de qué hablar en el mundo de software libre por su suite de herramientas también tiene componentes desarrollados pensados para la Nube, como es el caso del Stratos.

Esta herramienta permite la creación de nubes privadas, hibridas o públicas y tiene su presencia en internet con stratoslive.

Otro de los temas de estos días son las soluciones No-SQL que pretenden solucionar muchos de los problemas a los que se enfrentan las BD relacionales con el crecimiento y procesamiento desmesurado de la gran cantidad de datos que se manejan hoy, el problema con esta tecnología es que al igual que con la computación en la Nube no existe un conocimiento generalizado de su funcionamiento y no muchos saben cómo realizar despliegues en producción de forma adecuada. Ejemplos de trabajos No-SQL como Cassandra me vienen a la meten también de la mano de WSO2 que empezó a usarla como medio de almacenamiento para su herramienta BAM junto con Hadoop y Apache Hive para el procesamiento masivo de los datos.

La combinación de estas 2 tecnologías y paradigmas se pueden ver primero en la solución del BAM de WSO2 que trataremos en otras entradas, y además en una solución No SQL brindada como servicio: Redis. Redis es una BD No-SQL con una gran cantidad de casos de éxito, fundamentalmente en el cacheo de los datos. El problema que tiene es que al ser open source carece de varias características que le impiden comportarse adecuadamente cuando el conjunto de datos crece más allá de la capacidad del nodo maestro. Si a eso le sumamos que su mantenimiento es complejo y que el rendimiento se degrada con el tiempo pues no es una muy buena propuesta a tener en cuenta.

Esto se soluciona si pensamos que una empresa pueda tomar este tipo de solución, resolver los problemas que tiene y exponer la solución como un servicio. Este es el enfoque que muchas empresas están siguiendo en la actualidad con sus soluciones.

En este caso en particular la empresa es garantía y permite que los clientes ya no tengan que preocuparse más por la clusterización de sus BD, actualizaciones de software, el parcheo de los problemas encontrados, la administración de los servidores y muchas otras cosas más. La idea es la de siempre, pagar por lo que estás usando y no preocuparte por su mantenimiento y gestión.

{ Leer Más }


martes, 18 de junio de 2013

Introducción a Spring Roo para el desarrollo rápido de aplicaciones.

clip_image002

Cuando los desarrolladores JAVA se enfrentan a un nuevo proyecto por lo general tienden a reutilizar buenas prácticas, frameworks de diferentes niveles, patrones de diseño y de arquitectura que en su conjunto les ayudan a no reinventar la rueda y a reutilizar cosas ya hechas en trabajos previos.

Esto lleva mucho copy/paste, cambio en las configuraciones y tiempo invertido que se podría utilizar en implementar cosas nuevas. Cuando esto sucede existe un framework que nos puede quitar mucho trabajo de encima: Spring Roo.

Spring Roo es una herramienta RAD (Rapid Application Development) para JAVA y basada en Spring Framework. A partir del uso de este framework se puede comprobar que es un generador avanzado de código que se puede ir utilizando desde una línea de comandos similar a Maven donde a través de una guía vamos configurando todo un proyecto a lo largo de su ciclo de vida.

Importante es que al no contener ningún componente en tiempo de ejecución no interfiere en el despliegue de las soluciones ni crea dependencias con el producto final, de forma tal que resulta transparente para el despliegue en producción.

Su desarrollo está enfocado en una serie de plugins como pasa con Maven y se usan scripts relacionados con estos plugins para ejecutar las tareas.

Entre sus características básicas se pueden identificar:

  • Permite desarrollar una aplicación Web en minutos. Genera un war. Construye dos capas: la de persistencia y la de presentación. Para agregar la capa de negocio, se pueden agregar las clases manualmente a los controladores generados con Roo.
  • Permite generar un modelo de datos complejo, incluyendo validaciones.
  • La aplicación Web es RESTful y tiene soporte para internacionalización en varios idiomas.
  • Tiene soporte de seguridad out-of-the-box.
  • La presentación usa Dojo (incorporar otro, por ejemplo JQuery, se hace a mano y es costoso).

Entre los frameworks que usa podemos listar los siguientes:

  • AspectJ
  • Java Persistence API: Hibernate, OpenJPA, EclipseLink
  • Java Server Pages
  • JUnit
  • Log4J
  • Maven
  • Selenium
  • Spring Framework
  • Spring MVC
  • Spring Security
  • Spring Web Flow

Los requisitos para su uso son bastante sencillos:

1. Tener JAVA instalado.

2. Tener MAVEN instalado.

Para descargar el framework pueden ir a su sitio oficial http://www.springsource.org/roo/ y obtener la versión más actualizada así como ejemplos de su uso.

Revisando la web podemos encontrar los siguientes puntos a su favor:

Usabilidad.

El primer punto a favor de Spring Roo es su interfaz, un intérprete de comandos con autocompletado, muy similar a las shells de *nix con readline.
Esto nos va a permitir crear scripts propios para generar el esqueleto o partes de la aplicación con la flexibilidad y la productividad propia de los intérpretes de comandos. Además el intérprete es realmente intuitivo. Basta pulsar [tab] para ver las opciones que disponemos o introducir el comando 'hint' para obtener indicaciones sobre el próximo paso a seguir. Por supuesto, podemos seguir usando nuestro IDE favorito para el desarrollo. Spring Roo vigila los cambios que hacemos en el código y toma las medidas oportunas en caso de que deba hacerlo.

Funcionalidad.

Spring Roo está basado en una arquitectura modular que permite construir distintos tipos de aplicaciones según los módulos que utilicemos. Sin embargo, en principio, está bastante orientado a la creación de aplicaciones web basadas en Spring MVC en la capa de presentación y una capa de modelos del dominio persistentes mediante JPA.

Los modelos del dominio encapsulan tanto lógica de negocio como la lógica de persistencia, un patrón de ORM, Active Record, descrito por Martin Fowler en P of EAA como:
"An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data."

Representa una simplificación importante sobre la clásica arquitectura de tres capas donde se han suprimido la capa de servicios (Service Layer) y la capa de acceso a datos (DAO, Repository) que suelen ser una sobrecarga innecesaria en proyectos web de tamaño medio o pequeño.

La productividad de la arquitectura basada en registros activos ha sido probada considerablemente en el pasado, por ejemplo en frameworks como Ruby on Rails.

Otra ventaja a tener en cuenta es que suele ser bastante más asequible para equipos de desarrollo con un porcentaje alto (o muy alto) de programadores con poca experiencia, como por ejemplo, las factorías de software. El lanzamiento de la aplicación es un auténtico relámpago y la herramienta se hace cargo de muchas de las tareas que, a pesar de ser monótonas para programadores experimentados, suelen ser barreras difíciles de pasar para los nuevos por la cantidad de conceptos que manejan.

Spring Roo incluye las siguientes funcionalidades:

  • Lanzamiento de una aplicación nueva (aunque también puede aplicarse a una aplicación existente).
  • Configurar el sistema de compilación (actualmente soporta Maven2).
  • Instalar un proveedor de JPA.
  • Configurar la base de datos que se va a utilizar.
  • Configurar Log4Java.
  • Crear entidades JPA y manejar automáticamente las inyecciones de dependencias (Spring) y los métodos de persistencia.
  • Añadir campos a las entidades (Active Records) incluyendo las anotaciones de JPA como del nuevo estándar de validación de Beans JSR 303.
  • Manejar test de integración JUnit automáticos incluso cuando existen relaciones entre entidades o restricciones en las validaciones de los beans.
  • Crear y mantener controladores de Spring MVC que cumplen las convecciones REST, incluyendo la creación y el mantenimiento de las páginas JSP.
  • Crear esqueletos de controladores de Spring MVC que pueden ser terminados por el programador, ahorrando el trabajo de buscar las anotaciones y los métodos que normalmente se utilizan en dichos controladores.
  • Creación dinámica de métodos finders sin necesidad de escribir consultas en JPA QL.
  • Instalación y configuración simple de Spring Security
{ Leer Más }


lunes, 17 de junio de 2013

Validación de formularios con CodeIgniter

Una cuestión de suma importancia en toda aplicación web es la seguridad, tanto del propio sistema (que no produzca errores por sí mismo) como contra ataques de usuarios. Los usuarios pueden ser malintencionados o no y a veces los peores atacantes son los que no saben lo que están haciendo. Quizás para muchos internautas sea costumbre que si te piden una edad escribes un número, pero, ¿y si alguien pone letras?

La seguridad con los tipos de datos se logra a varios niveles. Primeramente, en el diseño de la base de datos, donde debes ajustar cada tipo de dato a lo que realmente necesitas. Una vez establecido esto, se deben validar los datos de entrada de usuarios para que coincidan con los de la base de datos, evitando así dos cosas, primero, el mensaje de error de base de datos, que como no supimos capturar nos sale de momento y rompe con todo nuestro diseño; y segundo, mantenemos la integridad de nuestra base de datos.

También debes hacer un diseño correcto de las vistas. Es muy recomendable utilizar cajas de selección (combobox) donde se despliegan las opciones posibles, y así evitamos que el usuario inserte valores ajenos. Si tiene que entrar Sí o No, pues es mejor utilizar un combobox con los dos valores, o una caja de chequeo (checkbox) donde marcado es Sí y no marcado es No. Hay maneras de evitar que el usuario escriba “sí”, “si”, “Sí”, “SI”, “s”, “yes”, “y”, etc. Debes indicar qué datos del formulario son obligatorios (suele usarse un asterisco), y de qué tipo son.

Queda entonces validar que no entren campos vacíos, y que los entrados sean válidos (números, fechas, direcciones web, direcciones http, etc.). Es pertinente validar los datos del lado del cliente (PC donde está el usuario), es decir, usando java script (una opción de moda es el jquery validate). Esta validación en el cliente permite que el usuario conozca sus errores antes de hacer el envío o submit de la página, lo que permite además conservar sin mucho trabajo los datos entrados en los componentes visuales.

Pero como hay diversos navegadores en los que las cosas se comportan a veces de formas diferentes, y porque el usuario puede tener deshabilitado el java script, es necesario validar los datos también en el lado del servidor: el php no depende de qué navegador se esté usando en los clientes, por lo que estamos trabajando en un entorno más controlado.

Cuando recibas el formulario puedes usar el tradicional $var = $_POST['component_name'] (recuerda que en el servidor se obtiene el valor del componente a través de su nombre, en el cliente se trabaja también con el ID del componente), y revisar los valores de tu variable. Aquí estoy asumiendo el envío de datos por POST, en vez de por GET.

Sin embargo, CodeIgniter brinda una excelente aproximación a la validación de datos, con la clase de validación de formularios. Esta clase permite especificar las reglas que le vas a aplicar a los datos enviados desde el cliente, así como los mensajes de error para cada una. Además permite especificar los delimitadores que le darán formato a tu mensaje, y da la posibilidad de mostrar los errores nuevamente en el cliente.

function X() //en el controlador

{

$this->load->library('form_validation');

$this->form_validation->set_rules('username', 'Username', 'required');

$this->form_validation->set_error_delimiters('<div class="error">', '</div>');

if ($this->form_validation->run() == FALSE) {

$this->load->view('myform');

}
else {

$this->load->view('formsuccess');

}

}
<?php echo validation_errors(); ?> //en la vista

 


En este ejemplo he cargado la clase form_validation; he especificado que el componente llamado username, que tiene adelante una etiqueta con el texto Username[1], es obligatorio (required); he configurado que el mensaje de error salga dentro de un <div> en vez de dentro de un <p> como está por defecto, y de paso he indicado una clase propia para el div, que responde a un estilo de css para mis mensajes de error. Finalmente verifico, si la validación da FALSE es que hubo error y cargo nuevamente la vista donde estaba mi componente username, sino cargo otra vista cualquiera.

En la vista “myform”, donde está el componente que se está validando, tendrías que poner echo validation_errors() para que muestre los mensajes de error. Lo usual es ponerlo antes de abrir tu formulario. Lógicamente si no hay errores no se muestra nada. También se puede mostrar los errores de forma independiente para cada componente, usando echo form_error('username'), en este caso puedes mostrar el mensaje al lado del componente.

El tipo required viene predefinido con CodeIgniter como otros tantos. CodeIgniter usa el segundo parámetro de la regla para completar el mensaje, en este caso se muestra algo así como “El campo Username es obligatorio”.

CodeIgniter permite también concatenar reglas usando “|” y preparar o formatear los datos. En el siguiente ejemplo se eliminan los espacios en blancos de los tres campos con trim, se marcan como obligatorios, se especifica que el campo username debe tener entre 5 y 12 caracteres y que el password y el passconf confirmado deben ser iguales. Finalmente se encripta la contraseña con md5.

$this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[5]|max_length[12]');

$this->form_validation->set_rules('password', 'Password', 'trim|required|matches[passconf]|md5') ;

$this->form_validation->set_rules('passconf', 'Password Confirmation', 'trim|required');


Además se pueden crear reglas propias con sus respectivos mensajes, sobre lo cual comentaré mis experiencias en un próximo artículo.

Recuerda siempre que cuando hagas un submit debes validar tus datos, sanearlos de datos maliciosos, preformatearlos (trim, html encoded) y finalmente prepararlos para la inserción en la base de datos de forma que se mantenga su integridad, garantizando así esta parte de la seguridad de tu sistema.




[1] No tiene que ser necesariamente el nombre de la etiqueta, aquí usas un texto que le sea más entendible al usuario, de forma que cuando llegue el mensaje de error sepa de cual componente se le está hablando. Así que lo usual es que tenga el mismo texto de la etiqueta del componente.

{ Leer Más }


viernes, 14 de junio de 2013

Desarrollo de una aplicación web MVC en JAVA con ZK, Spring e Hibernate.

Ya en otras entradas hemos visto los temas introductorios a ZK como framework JAVA para el desarrollo de la capa de presentación y también hemos visto el uso de Spring e Hibernate para el desarrollo de la capa de negocio y de persistencia.

En esta entrada veremos a través de un ejemplo práctico como combinar estos frameworks para implementar un CRUD (Patrón de caso de uso con las funcionalidades de añadir, modificar, eliminar, listar).

El proyecto será una aplicación web en Maven por lo que comenzaremos por el fichero pom.xml donde pondremos los repositorios que usaremos y las dependencias a incluir en el proyecto. De esta forma Maven las gestionará por nosotros.

El pom lo pueden ver aquí.

<pre class="brush:xml;">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>GestUsuariosZK</groupId>
<artifactId>GestUsuariosZK</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>GestUsuariosZK</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.version>3.2.0.RELEASE</org.springframework.version>
<zk.version>6.5.0</zk.version>
<zkel.version>1.1.0</zkel.version>
</properties>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<wtpversion>2.0</wtpversion>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>


<!-- dependencias de ZK -->

<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zk</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zul</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zhtml</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zcommon</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zkforge.el</groupId>
<artifactId>zcommons-el</artifactId>
<version>${zkel.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zweb</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkplus</artifactId>
<version>${zk.version}</version>
</dependency>


<!-- dependencias comunes -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>



<!-- dependencias de Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<!-- dependencias para el acceso a datos -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.9.Final</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>zk repository</id>
<url>http://mavensync.zkoss.org/maven2</url>
</repository>
</repositories>
</project>
</pre>

Básicamente la aplicación es una implementación del patrón de arquitectura MVC o Modelo Vista Controlador.

· Tendremos las vistas que serán las páginas .zul.

· Tendremos los modelos que serán las clases encargadas del modelado de las entidades de nuestro sistema, tal y como vimos en las entradas relacionadas con la persistencia.

· Tendremos los controladores que son las clases que se encargan de coordinar las acciones entre las vistas y los modelos. Básicamente recibe eventos de las vistas y actualiza los modelos así como obtienen datos de los modelos y cambian la representación de dichos datos en las vistas.

De esta manera se logra una separación de responsabilidades eficiente. La idea general la pueden ver en la siguiente imagen.

clip_image001

La estructura del proyecto es la siguiente:

clip_image002

En el paquete org.desarrollo.ejemplo1.web se tiene la clase controladora.

En el paquete org.desarrollo.ejemplo1.servicio se tiene la interfaz que me enlaza con el modelo y su implementación así como un localizador del servicio que se encarga de obtener una sesión y cargar el bean de la implementación del modelo.

En el paquete org.desarrollo.ejemplo1.modelo se tiene la clase modelo con su mapeo a hibernate en este caso usando un fichero de configuración y no anotaciones como habíamos visto hasta ahora.

En el paquete org.desarrollo.ejemplo1.dao tengo la implementación del DAO genérico con todo el código de acceso a los datos que puede ser reutilizable.

La interfaz de la aplicación refleja las acciones de caso de uso típico CRUD:

clip_image004

Pueden usar el editor gráfico de ZK como se explica en esta entrada para que puedan visualizar la UI.

Como pueden ver tiene operaciones para:

· adicionar una persona,

· actualizar los datos a partir de la selección de la persona en el listado,

· buscar una persona a partir de uno de sus datos,

· borrar una persona previa selección de la misma en el listado.

La interfaz se diseña en un XML que es el formato usado por ZK para representar sus componentes UI (user interface) o Interfaz de Usuario en español.

La pueden ver aquí:

<pre class="brush:xml;">

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<window id="win" apply="org.desarrollo.ejemplo1.web.PersonasController" width="1024px" title="gestion de datos" border="normal">

<groupbox>
<caption label="Operaciones CRUD:" width="580px" />
<label id="label1" value="sdsd"/>
<grid>
<columns sizable="true">
<column width="100px"/>
<column width="370px"/>
</columns>
<rows>
<row>
<label value="Nombre:"/>
<textbox id="nombre" value="@{win$composer.current.nombre}" width="350px"/>
</row>
<row>
<label value="1er Apellido:"/>
<textbox id="apellido1" value="@{win$composer.current.apellido1}" width="350px"/>
</row>
<row>
<label value="2do Apellido:"/>
<textbox id="apellido2" value="@{win$composer.current.apellido2}" width="350px"/>
</row>
</rows>
</grid>
<button id="add" label="Adicionar" />
<button id="update" label="Actualizar" />
<button id="search" label="Buscar" />
<button id="delete" label="Borrar" />
</groupbox>
<listbox id="box" multiple="true" selectedItem="@{win$composer.current}" emptyMessage="No hay personas a mostrar">
<listhead>
<listheader label="Nombre:"/>
<listheader label="1er Apellido:"/>
<listheader label="2do Apellido:"/>
</listhead>
<template name="model">
<listitem width="680px">
<listcell label="${each.nombre}" />
<listcell label="${each.apellido1}" />
<listcell label="${each.apellido2}" />
</listitem>
</template>
</listbox>
</window>
</pre>

Como pueden observar lo primero es definir un grupo donde pondré varios componentes, para eso uso el componente “groupbox”.

Dentro de este componente pongo un “grid” que me permite tal como si usara un listbox ubicar columnas (columns) y filas (rows) para mostrar la primera parte de la UI.

Luego pongo una serie de botones usando el componente “button”.

Al salir del “groupbox” utilizo otro componente para mostrar el listado de las personas, que representan las tuplas en la BD, se trata de “listbox” lo más importante de este componente es el uso de otro componente dentro que se llama “template” y es el que me permite visualizar automáticamente los resultados en función de las acciones sobre la vista y la respuesta de la controladora.

NOTA: es importante que se fijen que todos los componentes tienen un id que me permite referenciarlos en la clase controladora.

Los principales atributos de la clase controladora reflejan los componentes en la UI, como pueden ver en la siguiente imagen.

clip_image005

Como ven uso una anotación Wire para obtener los componentes con esos nombres en la UI.

Igual uso la anotación @Listen para los métodos que se enlazan con los botones de la UI.

clip_image007

Vean como utilizo el evento onClick sobre el componente para relacionarlo con la operación en la clase controladora. Es como si dijera: cada vez que se genere el evento onClick sobre el componente “update” se debe llamar al método update.

Lo demás es muy típico del trabajo con Spring e Hibernate así que les dejo el código fuente  del proyecto para que lo compilen con Maven y lo desplieguen en el servidor de su preferencia.

La tabla que se usó es realmente sencilla y este es su DDL:

CREATE TABLE public.persona (

id BIGINT NOT NULL,

nombre VARCHAR NOT NULL,

apellido1 VARCHAR NOT NULL,

apellido2 VARCHAR NOT NULL

) WITHOUT OIDS;

Para crear el .war de esta aplicación deben pararse en la raíz del proyecto, suponiendo que tengan Maven ya instalado y configurado.

Bastan con ejecutar este comando “mvn clean package”, verán cómo se descargan todas las dependencias del proyecto, se compila, se ejecutan las pruebas, en este caso no hay, y en la carpeta target del proyecto se les creará un .war que deben desplegar en un servidor como tomcat y listo.



.
{ Leer Más }


jueves, 13 de junio de 2013

Liberado Qt 5.1 Beta.

clip_image001

Por estos días muchas empresas y desarrolladores de software están nuevamente motivados a desarrollar en C++, por la reciente noticia de la liberación de la versión Beta de Qt 5.1. Con la versión Beta, tendremos disponibles los instaladores binarios para Qt 5.1, por lo que es más fácil usar el Framework Qt. Ahora veamos las grandes mejoras que aporta esta versión con explicaciones detalladas que dieron sus desarrolladores [1].

Funcionalidad clave

El principal motor de Qt 5.1 ha sido el aumento de la madurez de las nuevas características introducidas con Qt 5.0. Hemos mejorado la funcionalidad y el rendimiento sobre la base de la información recibida de los casos de uso del mundo real de Qt 5.0 y aplicaciones de portabilidad de Qt 4.x Estamos en condiciones de satisfacer sus necesidades con Qt 5 debido a la retroalimentación y contribuciones de nuestra creciente ecosistema de alrededor de 500.000 desarrolladores en más de 70 industrias que utilizan Qt en numerosas plataformas y configuraciones.

Las nuevas características clave de Qt 5.1 Beta incluyen:

  • Qt Quick Controls módulo de proporcionar un conjunto de componentes de interfaz de usuario reutilizables especialmente para aplicaciones de escritorio creados con Qt Quick
  • Qt Quick Layouts módulo que permite diseños rápidos de forma más intuitiva, una forma fácil de gestionar interfaces de usuario escalables al asegurar que los artículos están dispuestos constantemente, y que la interfaz de usuario como un conjunto sigue siendo utilizable a través de diferentes tamaños de pantalla.
  • Qt Serial Port módulo de puerto serie que proporciona una interfaz multiplataforma para utilizar el hardware y los puertos serie virtuales en aplicaciones Qt
  • Posibilidad de usar Qt Quick y Widgets juntos en la misma ventana de la aplicación
  • Qt Creator 2.7.1 incluido en el paquete, proporcionando, por ejemplo, Qt Designer que permite una rápida creación de prototipos, así como las mejoras en la edición de código para C ++ 11.
  • El soporte a la compilación estática de QT hace posible la solución frente a los casos de uso que no pueden utilizar el enlace dinámico.
  • Introduce Qt Sensors como un módulo con apoyo oficial.

Instaladores binarios

Para la mayoría de los usuarios lo mejor de Qt 5.1 Beta comparado con Qt 5.1 Alpha es que incorpora instaladores binarios que proporcionan una forma conveniente de instalar todo lo que necesita para comenzar a desarrollar con Qt sin necesidad de que usted compile Qt. Con Qt 5.1 estamos introduciendo algunas nuevas configuraciones como VS2012 64 bits con OpenGL, que ya está disponible con la versión beta. Poco después de la Beta estamos actualizando MinGW a la versión 4.8 y el objetivo es lograr también VS2012 32 bits con la configuración ANGLE.

Qt 5.1 Beta viene como un instalador fuera de línea, pero también proporcionará instaladores en línea antes del lanzamiento de Qt 5.1.0 final. El instalador offline contiene todo lo necesario para empezar con Qt - herramientas, documentación, ejemplos y bibliotecas Qt pre-compiladas. Los paquetes fuente están disponibles para aquellos que desean construir Qt (o tienen la necesidad de utilizar una configuración que no está disponible como un binario pre-construidos). Además de instaladores binarios para sistemas de escritorio, Qt 5.1 Beta viene con los binarios pre-compilados para Android que pueden ser empaquetados con su aplicación.

Nuevas plataformas

Qt 5.1 Beta ofrece una vista previa a la tecnología del soporte a los dispositivos Android y iOS. Además en la versión definitiva de Qt 5.1.0 está previsto reintroducir el soporte para Windows Embedded Compact 7. Hemos añadido todas estas nuevas plataformas en el sistema de CI de modo que cada cambio que va en Qt se verifica para trabajar en estos, así como las otras plataformas y configuraciones ya en el CI. Por el momento, el CI para Android y iOS sólo las pruebas para la construcción, pero estamos poco a poco añadiendo también las pruebas automatizadas que se ejecutan en estas nuevas plataformas, para disminuir la posibilidad de regresiones.

Hay un montón de rumores en torno a los nuevos Ports (Soporte) para dispositivos móviles y muchos están interesados ​​en saber lo que es posible hacer con el Qt 5.1 Beta. En general, se puede afirmar que se pueden crear aplicaciones impresionantes que se ejecutan sin problemas en las dos nuevas plataformas, pero con limitaciones en la funcionalidad soportada.

Con Android las siguientes funcionalidades trabajan bien en el Qt 5.1 Beta:

  • Widgets, Graphics View, Qt Quick 1 y Qt Quick 2.
  • OpenGL, redes y otras funcionalidades básicas de Qt
  • Algunas partes de Qt Multimedia, por ejemplo QML media player
  • Un conjunto de sensores comúnmente utilizados con Qt Sensors.
  • Desplegar tus aplicaciones a un dispositivo usando el IDE Qt Creator.
  • Depurar la aplicación usando el IDE Qt Creator
  • Qt 5.1 Beta viene con los binarios pre-construido para Android que puede ser incluido con su aplicación.

Con iOS el principal problema es que Qt Quick 2 no está disponible, ya que necesita un nuevo motor QML, pero las siguientes funcionalidades funcionan bien en el Qt 5.1 Beta:

  • Widgets, Graphics View y Qt Quick 1.
  • OpenGL, redes y otras funcionalidades básicas de Qt
  • Un conjunto de sensores comúnmente utilizados con Qt Sensors.
  • Despliegue de la aplicación a un dispositivo desde Xcode / iTunes.

Próximos pasos

Con el lanzamiento de Qt 5.1 Beta estamos un paso más cerca de la versión final 5.1.0 Qt, que debemos tener antes de verano. Con base en la retroalimentación que recibamos de la Beta, habrá una versión Release Candidate creada en unas pocas semanas. Recuerden que la versión beta de Qt 5.1 se puede descargar desde aquí.

Envíenos sus comentarios.

{ Leer Más }


miércoles, 12 de junio de 2013

Manipular componentes ZK dentro de un componente macro.

Introducción

El uso de Componente macro es una técnica útil para modularizar páginas ZUL complejas [1], y permite mejorar la forma en que usamos el Framework ZK para el desarrollo de aplicaciones web dinámicas. En la mayoría de los casos de uso, los componentes macro constan de varios elementos fijos. Sin embargo, es posible que desee agregar más componentes dentro de un componente macro basado en algún tipo de acción. En este artículo mostraremos cómo se puede agregar componentes adicionales a un componente cableado dentro de un componente macro. Aquí vamos a utilizar un componente macro de tipo breadcrumb como ejemplo y crear dinámicamente componentes en su interior.

Escenario de ejemplo

En este ejemplo, hay un menú de la barra lateral con un componente de árbol, el componente macro de tipo breadcrumb va a cambiar la ruta de acceso de acuerdo con el evento clic sobre un treeitem.

Componente macro Breadcrumb

En primer lugar, crear un breadcrumb.zul como el siguiente para definir un componente macro.

<zk>

<hlayout id="m_hlayout" hflex="1" height="20px"

sclass="breadcrumb" spacing="10px">

</hlayout>

</zk>

Página principal zul

A continuación, utilice el componente macro en la página principal de zul.

<?component name="breadcrumb" macroURI="/WEB-INF/macro/breadcrumb.zul" class="demo.macro.BreadCrumb"?>

<zk xmlns:n="native">

<div vflex="1">

<borderlayout hflex="1" vflex="1" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('demo.macro.MacroSampleVM')">

<north border="none">

<div>

<label value="Blog Title" />

</div>

</north>

<east width="280px" border="none">

<div>

<tree model="@bind(vm.menuModel)">

<template name="model" var="node">

<treeitem label="@load(node.data.label)" onClick="@command('loadArticle', node=node)" />

</template>

</tree>

</div>

</east>

<center autoscroll="true" border="none">

<vlayout>

<breadcrumb hflex="1" path="@bind(vm.path)" />

<vlayout>

article list

</vlayout>

</vlayout>

</center>

</borderlayout>

</div>

</zk>

View Model

En View Model, registrar un evento de clic para el comando loadArticle y notificar el cambio de ruta de acceso al componente macro.

public class MacroSampleVM {

private DefaultTreeModel<ArticleLabel> menuModel;

private TreeNode<ArticleLabel> path;

public MacroSampleVM() {

// generate tree

TreeNode<ArticleLabel> root = new DefaultTreeNode<ArticleLabel>(null, generateYears());

menuModel = new DefaultTreeModel<ArticleLabel>(root);

}

@Command("loadArticle")

@NotifyChange("path")

public void loadArticle(@BindingParam("node") DefaultTreeNode<ArticleLabel> node) {

path = node;

}

}

La clase del componente macro Breadcrumb

Por último, definir API setPath en BreadCrumb.java para añadir un nuevo componente dentro del componente macro

public class BreadCrumb extends HtmlMacroComponent {

@Wire

private Hlayout m_hlayout;

//other member fields

public BreadCrumb() {

compose();

}

public TreeNode<ArticleLabel> getPath() {

return _node;

}

public void setPath(TreeNode<ArticleLabel> node) {

_node = node;

_paths.clear();

m_hlayout.getChildren().clear();

generatePaths(node);

//create components here and set parent to wired Hlayout

A[] links = new A[_paths.size() - 1];

for (int i = links.length - 1; i >= 0; i--) {

TreeNode<ArticleLabel> n = _paths.pollLast();

String label = n.getData().getLabel();

links[i] = new A(label);

links[i].setParent(m_hlayout);

}

_paths.clear();

}

private LinkedList<TreeNode<ArticleLabel>> generatePaths(TreeNode<ArticleLabel> node) {

//skip

}

}

Comunicar los componentes internos con la Vista Modelo (View Model)

Como podemos ver en el ejemplo anterior, podemos crear componentes en el interior de un componente macro con un evento de clic definido en la Vista Modelo. Ahora le mostraremos cómo registrar un evento de un componente que acaba de agregar y pasarlo en la Vista Modelo.

En primer lugar, agregue un evento de interés el componente que acaba de agregar el componente de destino es el propio componente macro.

public class BreadCrumb extends HtmlMacroComponent {

//omitted

public void setPath(TreeNode<ArticleLabel> node) {

//...

A[] links = new A[_paths.size() - 1];

for (int i = links.length - 1; i >= 0; i--) {

TreeNode<ArticleLabel> n = _paths.pollLast();

String label = n.getData().getLabel();

links[i] = new A(label);

links[i].setParent(m_hlayout);

links[i].addForward(Events.ON_CLICK, this, "onPathClick", n);

}

//...

}

}


Entonces, podemos escuchar evento onPathClick en el .zul y se unen con MVVM.

<!-- omitted -->

<vlayout>

<breadcrumb hflex="1" path="@bind(vm.path)"

onPathClick="@command('loadArticle', node=event.data)" />

<vlayout>

article list

</vlayout>

</vlayout>

<!-- omitted -->

Quedamos en espera de sus comentarios

{ Leer Más }


IconIconIcon