Genexus 9 - Curso Internet

March 25, 2018 | Author: thapotenza | Category: Web Application, Html, World Wide Web, Technology, Internet


Comments



Description

Curso Desarrollo de aplicaciones para Internet con GeneXusVersión 9.0 Enero 2007 www.genexus.com/training Curso No presencial “Desarrollo de aplicaciones para Internet con GeneXus” Bienvenido al curso “Desarrollo de aplicaciones para Internet con GeneXus” Este curso - actualizado a la versión GeneXus 9.0 - lo va a capacitar en el desarrollo de aplicaciones para Internet utilizando los objetos web GeneXus. Para poder realizar el curso debe contar con la versión 9.0 de GeneXus. El curso consta de los conceptos teóricos necesarios para el desarrollo de una aplicación web, así como la puesta en práctica de los mismos en una aplicación ejemplo. El desarrollo de esta aplicación podrá ser visualizado paso a paso a lo largo del curso mediante videos incluidos en el mismo. La idea es que Ud. vaya realizando esta aplicación en paralelo (a medida que avanza capítulo por capítulo en forma ordenada). En caso de estar interesado en consultar a un docente del curso las dudas que le vayan surgiendo, y/o dar un examen final de forma tal de obtener (en caso de aprobación) un certificado de haberlo realizado en modalidad no presencial, diríjase a nuestro sitio de capacitación a distancia: http://www.gxtechnical.com/capacitacionadistancia donde podrá informarse y contratar estos servicios. INTRODUCCIÓN En este capítulo intentamos ofrecer una orientación básica sobre el curso y su logística. Incluye información acerca de la estructura del curso, cómo navegar a través del mismo, cómo comunicarse con un instructor y cómo obtener información de interés para el correcto desarrollo del mismo. Metas y objetivos Este curso lo va a capacitar en el desarrollo de aplicaciones para Internet utilizando GeneXus 9.0. El curso está dividido en capítulos, cada uno de los cuáles tiene una introducción que establece los temas que serán abordados dentro del mismo y en algunos casos sugerencias acerca de cómo leerlo. Para facilitar el aprendizaje, los conceptos teóricos van acompañados de ejemplos prácticos y de videos demostrativos, que complementan lo explicado, de manera tal que el alumno pueda obtener una profunda comprensión de los temas tratados. A medida que se avanza en los capítulos se va desarrollando una aplicación bien simple que pone en práctica los conceptos más importantes que se van estudiando y que permite que el alumno pueda comenzar a interactuar con la herramienta reproduciendo lo realizado en los videos primeramente, y realizando los ejercicios prácticos propuestos, luego. Al finalizar el curso Ud. será capaz de desarrollar aplicaciones para Internet de la vida real utilizando la metodología GeneXus y haciendo uso de la potencia que ofrece la herramienta. Asimismo este material podrá ser utilizado como manual de consulta en una etapa posterior, de manera de poder refrescar algún tema en particular, o profundizar en detalles no considerados en una primera instancia. Los primeros ocho capítulos constituyen el corazón del curso, y deben ser seguidos con detenimiento. Estos capítulos transmiten la esencia del desarrollo de aplicaciones para Internet con GeneXus. Los demás capítulos tienen distintos grados de importancia, pero podrían ser eventualmente omitidos en una primera lectura si lo que se busca es comenzar rápidamente a desarrollar este tipo de aplicaciones. Cualquier sugerencia que desee realizar, con gusto la recibiremos en la siguiente dirección de correo electrónico [email protected]. Prerrequisitos Existen dos requisitos fundamentales que es necesario satisfacer antes de comenzar este curso. Ellos son tener conocimientos de GeneXus (preferentemente la versión 9.0) y conocimientos de Internet. El primero de los requisitos es excluyente: el curso está dirigido a personas con conocimientos de GeneXus que hayan desarrollado aplicaciones con la herramienta. De no contar con estos conocimientos, la dificultad para alcanzar un nivel de comprensión aceptable será importante. Las diferencias inherentes a las versiones de GeneXus pueden dificultar también la comprensión del curso por lo que se recomienda realizar una actualización previa a la versión 9.0. El segundo de los requisitos, si bien no es excluyente, debe alcanzarse antes de comenzar el curso. Para ello se incluye un capítulo como anexo, de Introducción a Internet que establece la terminología y conceptos necesarios para entender este ambiente. Quién no cuente con dichos conocimientos, deberá comenzar por ese capítulo y no continuar hasta no haber asimilado todos los conceptos allí vertidos. Requerimientos computacionales Debe contar con GeneXus versión 9.0 full. En el presente curso desarrollaremos una aplicación de ejemplo generando para una plataforma .NET, utilizando como DBMS (DataBase Management System) el SQL Server 2005 Express Edition. Está disponible en nuestro sitio todo el software necesario para poder desarrollar la aplicación de entrenamiento en la plataforma mencionada. No obstante ello, si Ud. cuenta con otra plataforma de desarrollo de las soportadas por GeneXus y desea realizar la parte práctica del curso utilizándola en lugar de la que ofrecemos, puede hacerlo. Deberá tener en cuenta que en tal caso pueden haber diferencias con lo que verá en los videos, pues cada plataforma tiene características propias, y habrán configuraciones particulares que deberá realizar de forma distinta a la mostrada. En el manual de instalación de GeneXus 9.0 encontrará los requerimientos de hardware y software para generar en todas las plataformas soportadas por GeneXus. Por tanto, si Ud. no desea desarrollar la aplicación de ejemplo del curso en .NET, pues cuenta con otro generador, podrá referirse a este manual para obtener los requerimientos computacionales particulares a su caso. El manual de instalación se encuentra disponible para ser bajado de nuestro Download Center: http://www2.gxtechnical.com/portal/hgxpp001.aspx?15,8,77,O,S,0,,1924;4;4;;/%20%20/;/%20%20/; M A continuación se presenta una lista del hardware y software necesario para ejecutar GeneXus y las aplicaciones generadas en una plataforma .NET contra SQL Server 2005 Express Edition: Hardware Requirements Procesador: 500 MHz Intel Pentium class Memoria: al menos 128 MB de RAM (recomendada 512 MB) Disco duro: al menos 50 MB de espacio libre en disco para instalar el Development Environment más 10 MB para el generador. Para generar aplicaciones GeneXus necesitará espacio adicional o una unidad de disco compartida para crear las bases de conocimiento. Video: resolución 800x600 o mayor, con 256 colores Software Requirements Microsoft Windows con tecnología NT; Microsoft Windows 2000 o superior. Si Ud. está utilizando Windows NT, debe instalar el service pack 6a o superior. Microsoft .NET Framework 1.1 o 2.0 Redistributable Package 1 Microsoft Visual J# Distribution Package 2 Microsoft SQL Server 2005 Express Edition 3 ADO.NET Microsoft Internet Explorer 6.0 SP1 o superior 4 1 El .NET Framework 1.1 Redistributable Package puede ser bajado del sitio web de Microsoft: http://msdn.microsoft.com/netframework/downloads/framework1_1redist/ 2 El Visual J# Distribution Package 1.1 puede ser bajado del sitio web de Microsoft: http://msdn.microsoft.com/vjsharp/downloads/howtoget/default.aspx 3 Se recomienda tener instalado el "Microsoft SQL Server Management Studio Express", el cual puede ser bajado del sitio web de Microsoft: http://www.microsoft.com/downloads/details.aspx?FamilyId=C243A5AE-4BD1-4E3D-94B85A0F62BF7796&DisplayLang=en 4 Puede bajarlo de nuestro Download Center: http://www.gxtechnical.com/main/hdcenter.aspx?2,5,36,1183 Necesitará contar con algún reproductor de archivos multimedia para poder ver los videos incluidos en el curso, que son archivos de extensión AVI. El video debe reproducirse con el mismo tamaño del original (size 100%) pues de lo contrario la imagen puede degradarse y no verse con nitidez. Asimismo, antes de reproducir la primera de las demos, deberá haber ejecutado en su máquina el archivo TSCC.EXE que viene junto con el curso. TSCC es el codificador que se utilizó al producir los videos de este curso, para compactar los videos sin perder calidad de imagen. Debe estar instalado en toda máquina en la que se vayan a visualizar los videos del curso. En el documento Problemas con la reproducción de los videos tiene la solución a algunos de los problemas que se le podrían presentar al intentar reproducir los videos incluidos en el curso. Allí se indica también de dónde se pueden bajar reproductores en forma gratuita. Recomendamos una resolución de pantalla de 800x600, para poder ver los videos correctamente. Comunicación con un docente y examen final En caso de estar interesado en contar con la ayuda de un docente a quien se le podrán consultar las dudas que vayan surgiendo, y dar un examen final de forma tal de obtener, en caso de aprobación, un certificado de haberlo realizado en modalidad no presencial, diríjase a nuestro sitio de capacitación a distancia: http://www.gxtechnical.com/capacitacionadistancia donde podrá contratar estos servicios e informarse acerca de los mismos. Cómo utilizar este curso Elaboramos este curso intentando por un lado no aburrir al alumno con detalles innecesarios en una primera lectura, pero por otro brindando información completa de los temas tratados. Una forma de alcanzar estos objetivos sería postergar la complejidad y/o los detalles para capítulos más avanzados dentro del curso. Si bien de esta manera lograríamos los dos objetivos anteriores, un mismo tema estaría desperdigado en muchos capítulos, dificultando así una consulta posterior. Con la intención de que el material sea utilizado tanto en la etapa de aprendizaje como en una etapa de consulta posterior -a modo de libro de referencia- aparece pues un tercer objetivo: que los temas estén tan auto-contenidos como sea posible, de modo de facilitar la consulta posterior. En la mayoría de los casos estos objetivos se tornan contrapuestos, por lo que buscamos una solución de equilibrio. Intentamos dejar los temas lo más encapsulados posible en capítulos, sin perder de vista los aspectos didácticos. Para ello, establecimos una simbología que incluimos en los documentos para orientar visualmente al lector discriminando qué partes de la documentación pueden excluirse en una primera lectura, qué partes son de fundamental importancia y deben convocar toda su atención, etc. Asimismo establecimos una simbología análoga a nivel del índice –árbol- del curso. En las tablas que aparecen al final de esta página listamos estos símbolos y sus significados. Es así que el curso se divide en capítulos, cada uno de los cuales contiene una introducción que resume los puntos que se tratarán dentro del mismo, brindando sugerencias al lector acerca de cómo leerlo. Los capítulos contienen documentos de distintos tipos, así como subcapítulos. Este curso está pensado para ser seguido fundamentalmente de manera secuencial. Algunas veces se podrán producir desviaciones a ese orden, tanto por decisión del lector, como por alguna sugerencia explícita dentro del curso. Normalmente se comienza con la introducción de un capítulo, y luego se pasa a leer el documento que le sigue en orden dentro del índice. Si bien los documentos están ordenados de modo de ser leídos secuencialmente, pueden, no obstante, contener links que los relacionen con otros documentos de otras partes que están más adelante o más atrás en el curso. Aconsejamos seguir los links “hacia adelante” solo cuando se está realizando una “referencia posterior”, es decir, cuando ya se ha dado una primera lectura a todo, y se está consultando un tema específico. La razón es que el lector ya llegará a esos temas cuando siga secuencialmente con el curso, y de hacerlo en el momento en que encuentra el link corre el riesgo de perder el foco de lo que estaba estudiando. Los que son “hacia atrás” sí pueden utilizarse en la primera lectura, pues posibilitan refrescar o recordar temas, conceptos, ideas, etc. vistos recientemente y aún no suficientemente afianzados. Del texto que se despliega al pasar el mouse sobre del link se desprenderá claramente el tipo del link -si es “hacia adelante” o “hacia atrás”. Lea las tablas de símbolos que figuran a continuación para entender el significado de los símbolos que aparecerán a lo largo de todo el curso. Tabla de símbolos de los documentos Símbolo Significado Denota que lo que se encuentra en esa sección es de fundamental importancia y debe prestarse especial atención a lo que allí se dice. Generalmente se trata de conceptos de gran relevancia. Si el símbolo se encuentra al principio del documento, aplica a todo el documento. Si por el contrario aparece delimitado por líneas, aplica solo a lo delimitado por ellas. Es una referencia a un “pie de página”. Se incorpora en la mitad de un texto para establecer un link a dicho pie de página. Representa una nota en alguna parte del documento. Sugerimos tener GeneXus abierto mientras se está siguiendo el curso, de manera tal de poder ir viendo en la herramienta los elementos que se van mencionando e ir probando en la aplicación de ejemplo. Desarrollo de una aplicación Como el propósito de este curso es que el alumno pueda desarrollar aplicaciones de la vida real para Internet utilizando GeneXus, elegimos una aplicación de ejemplo bien simple para ir poniendo en práctica a lo largo del curso los conceptos que se vayan incorporando. En el Capítulo 2 se presenta el primer paso en el desarrollo de la aplicación, que irá creciendo a lo largo de los capítulos subsiguientes de forma tal de ir incorporando los nuevos elementos que vayan apareciendo. El desarrollo se presenta mediante videos demostrativos que el alumno deberá observar primeramente, para luego intentar reproducir. A menos que se indique lo contrario, a continuación de un video demostrativo el alumno deberá reproducir lo visto. En algunas ocasiones se le indicará explícitamente al alumno luego de un video alguna variante al mismo, para que no lo repita exactamente, sino con alguna modificación. La aplicación que hemos elegido es una simplificación de una aplicación real: un sistema para una agencia de viajes que permite la búsqueda de pasajes y servicios turísticos. A grandes rasgos: la agencia contará con un sitio en Internet donde permitirá a los clientes realizar búsquedas de destinos, los vuelos existentes y los diferentes servicios brindados. Incluirá también todo el back-end para el mantenimiento de la información relacionada. Convenciones para la documentación En los documentos de este curso se utilizan algunas convenciones tipográficas:     Todos los nombres de atributos y variables aparecerán en cursiva. Los nombres de objetos GeneXus aparecerán entrecomillados, con la primer letra en mayúscula y el resto en minúscula. Los nombres de tablas aparecerán sin comillas y en mayúscula. Los nombres de índices estarán también sin comillas y en mayúscula. Utilizamos las convenciones de sintaxis de los comandos, reglas, eventos, etc. del lenguaje que se utilizan en el Help de GeneXus, por lo que recomendamos leer el documento “Syntax Conventions” del Help. Algunos links de interés Con el objetivo de brindar a los desarrolladores una fuente única de información potenciada con una “ingeniería de búsqueda” que les permita acceder rápida y fácilmente a la información técnica (release notes, manuales, tips, whitepapers, etc.) sobre los diferentes productos que desarrolla ARTech, se creó la GXDL, GeneXus Developer Library, una biblioteca que centraliza toda esta información técnica. Puede ser consultada online o puede ser utilizada en forma local mediante una sencilla instalación. http://www.gxtechnical.com/gxdl Podrá crearse un usuario en nuestro sitio web GxTechnical, http://www.gxtechnical.com, y bajar del Download Center todo el material permitido según el nivel de su usuario. En el Download Center encontrará productos, cursos, ejemplos, manuales, release notes, GXDL, utilitarios, technical papers, etc. Temas que no serán abordados en este curso A continuación mencionaremos los temas que están relacionados con el curso para que el lector pueda recurrir a la GXDL en caso de tener interés en abordarlos por su cuenta. Ellos son:   Introducción a “Business Intelligence” (Data Warehousing) “GXFlow” (Aplicaciones de workflow) Problemas con la reproducción de los videos Los videos son archivos con extensión .avi. Debe configurar su máquina para que los abra siempre con el reproductor con el que cuente. ¿Por qué mis videos no se ven? Los videos que se utilizan en este curso son producidos utilizando un codificador, TSCC, que permite comprimir los archivos sin degradar la calidad de la imagen. Este codificador debe estar instalado en toda máquina en la que se vayan a visualizar los videos. El archivo TSCC.EXE que incluimos junto con el curso, debe ser ejecutado en su sistema de manera de instalar el codificador TSCC en su máquina. Esta acción solo debe realizarse una vez. Para Windows NT/2000/XP los usuarios deben tener permisos de administrador para realizar la instalación. También puede ser descargado del sitio web: http://www.techsmith.com/download/studiodefault.asp Si aún así no se ven, pruebe utilizar el Media Player en modo v6.4. ¿Por qué mis videos se ven borrosos? Si se escala el video en la aplicación que lo está reproduciendo el video se verá borroso. Los videos deben reproducirse con su tamaño original, sin ser escalados. Problemas con la reproducción con Media Player Si el video se está reproduciendo en Media Player 7, 8 o 9 y ud. no logra ver la imagen nítidamente, el problema probablemente sea de que el video no se está reproduciendo al 100% del tamaño original. Es un problema que tienen estas versiones del Media Player en sus “skins” mode predeterminados. Por defecto escalan los videos durante la reproducción a un tamaño menor, dando como resultado la degradación de la calidad de la imagen. Muchas veces el seleccionar View/Video Size/100% no tiene el menor efecto. La solución es configurar el Media Player para que no escale las imágenes. Hay varias formas de hacerlo: 1. 2. 3. Configurar Media Player para que utilice “Classic skin”. Presionar el botón “Skin Chooser” y seleccionar “Classic”. Correr el player en “Compact mode”. En Media Player seleccionar View/Skin Mode. Correr Media Player en modo 6.4. Uso de Media Player 9 en modo v6.4 1. 2. Localizar y ejecutar el archivo MPLAYER2.EXE que está ubicado en Program Files/Windows Media Player. Esto correrá MP9 en modo v6.4. Cuando v6.4 está corriendo seleccionar View/Options/Formats, presionar Select All/Apply/OK. Esto configurará las asociaciones del shell de Windows para usar Media Player 6.4 cuando se hace doble clic sobre un video en Windows Explorer, o en otras aplicaciones que usan las asociaciones del shell de Windows para ejecutar un reproductor. Seleccionar View/Options/Playback y configurar el nivel de Zoom en 100% 3. Si desea utilizar v6.4 puede bajarlo de: http://www.microsoft.com/windows/windowsmedia/en/download/default.asp Otra opción es utilizar el TechSmith Camtasia AVI Player, que puede bajarse libremente de: http://www.techsmith.com/products/studio/player.asp. En este caso no habrán problemas de escalado. INTRODUCCIÓN En este capítulo comenzaremos a introducirnos en el desarrollo de aplicaciones Web con GeneXus. Veremos la arquitectura en general de estas aplicaciones y las alternativas disponibles en GeneXus. Crearemos una base de conocimiento para implementar una aplicación para una agencia de viajes que iremos desarrollando gradualmente a lo largo del curso. Además, entraremos a GeneXus para dar los primeros pasos en el desarrollo de una aplicación Web y comenzaremos a trabajar con el editor GeneXus para estos objetos. Veremos las barras de herramientas. Arquitectura de las aplicaciones Web En la imagen que mostramos a continuación se puede observar un esquema simplificado de la topología de Internet. Por un lado se tiene la red de la empresa (Intranet), donde se tiene un Servidor Web en el cual se publican las páginas Web. Este servidor puede ser también el servidor de base de datos, o se puede tener un servidor específico para realizar esta tarea. Los usuarios de Internet tendrán acceso a las páginas que sean públicas y podrán acceder a los datos almacenados en la empresa a través de páginas dinámicas. Por otro lado, los usuarios de la empresa (Intranet) podrán acceder a las páginas públicas y a las páginas privadas de la empresa. Alternativas para el desarrollo de aplicaciones Web con GeneXus Java y .NET son los generadores disponibles en GeneXus para desarrollar aplicaciones Web. Las aplicaciones podrán ejecutar con un servidor Web Windows, UNIX o ISeries y podrán usar cualquier manejador de base de datos, dentro de las plataformas soportadas por cada uno de los generadores GeneXus. Dependiendo del sistema operativo del servidor de Base de Datos y del servidor Web a utilizar, es el generador GeneXus que puede seleccionarse. En varias plataformas se plantean varias alternativas. La decisión del generador a utilizar se tomará principalmente por los requerimientos adicionales o interacciones con otras aplicaciones, ya que el ‘look and feel’ de la aplicación será el mismo independientemente del generador que se utilice. Servidor de Base de datos Windows Windows Unix Unix ISeries ISeries Servidor Web Windows Unix Windows Unix Windows ISeries Generador .NET SI NO SI NO SI NO Generador Java SI SI SI SI SI NO Desarrollo de Aplicaciones Web con GeneXus Como es sabido, la primera tarea cuando se comienza a desarrollar una aplicación con GeneXus es crear la base de conocimiento que representará e implementará al sistema. Lo mismo ocurre cuando la aplicación a desarrollar es Web. Puede ocurrir, que la base de conocimiento ya exista (por ejemplo con interfaz Win) y lo que deba crearse en ese caso es solamente un nuevo modelo en esa base de conocimiento. Puede ocurrir también, que se quiera agregar en un modelo existente algunos objetos Web. En ese caso, deberá definirse solamente un ambiente Web. Lo importante es que la interfase elegida (en File / Edit Model / Environment / User Interface) sea Web form. De esta manera se podrán definir en GeneXus los objetos para desarrollar aplicaciones Web (Web Panels y Transacciones Web). En modelos de Prototipo o Producción con ambiente Web, el tipo de objeto que se propone al crear un nuevo objeto es Web Panel. Práctico: Creación de una base de conocimiento 1. Entraremos a GeneXus y crearemos una base de conocimiento para comenzar el desarrollo del sistema para la Agencia de viajes. Le sugerimos que utilice la versión de GeneXus 9.0 y cree su propia base de conocimiento en el directorio que estime conveniente. Esta base de conocimiento será la que utilizará a lo largo del curso, tanto para reproducir las demos, como para hacer los ejercicios prácticos que se vayan indicando. 2. 3. Luego de crear la base de conocimiento, consolide el archivo KBInicialAgency.xpz. En este momento, crearemos un modelo de Prototipo utilizando el generador .NET y la base de datos SQL Server 2005 Express. Le sugerimos que utilice el Wizard para la creación del modelo. Deberá elegir un nombre para el modelo. El nombre elegido en el desarrollo de la aplicación que Ud. verá en los videos es AgencyNet pero Ud. puede elegir el que desee. Además, deberá elegir Web como User Interface. También deberá asignar el Language y DBMS que desee utilizar. Consulte el documento Propiedades de .NET donde se detallan las principales propiedades que debe configurar en este modelo. En caso de querer utilizar el generador Java, recomendamos que consulte el documento Propiedades del modelo Java para más información. 4. 5. 6. 7. 8. Al realizar el impacto, GeneXus nos informará de las nuevas tablas que creará en la base de datos. Confirme y ejecute dicha creación. Ahora, está en condiciones de copiar los datos que se encuentran en Agency.bak del cd1. Ahora, deberemos especificar y generar todos los objetos. Para confirmar que todas las propiedades del modelo quedaron bien configuradas, conviene ejecutar un objeto del modelo. Compile el Developer Menu2 y ejecute por ejemplo la transacción Country. Se recomienda utilizar un directorio virtual específico para el práctico. Por ejemplo: http://localhost/practico. De esta forma estamos definiendo un directorio virtual específico para nuestra aplicación y evitando tener un único directorio virtual para distintas bases de conocimiento activas. Se entiende que el alumno cuenta con conocimientos en GeneXus por lo cual los pasos aquí descriptos son sencillos y no requieren del apoyo de un video para llevarlos a cabo. El archivo Agency.bak, es un Back up de la base de datos. Para poder copiar los datos deberá realizar un Restore de la base de datos Agency. 2 El Developer Menu implementado para aplicaciones Web, al ejecutarlo desde el menú de GeneXus Build/Run (F5), abrirá una página en el navegador: <VirtualDirectory>/execute.xml. La misma tiene links a todos los objetos Web, estos son: Web Panels, Transacciones con Web form, Procedimientos con call protocol = http y Reportes con call protocol = http. 1 Editor de Objetos Web Para editar los objetos Web se cuenta con un editor “WYSIWYG” (What you see is what you get) similar al Front Page de Microsoft, que fue diseñado siguiendo el estándar de las herramientas Microsoft Office, lo que permite que los usuarios puedan utilizarlo rápidamente y en forma intuitiva. Es un editor orientado a páginas, lo que significa que la posición de los controles que se encuentran dentro del form en diseño es relativa al tamaño de la ventana que contenga la página. Este editor provee el manejo de tablas, característica fundamental a la hora de diseñar páginas Web. Esta facilidad habilita al usuario a diseñar mejores páginas, así como le permite manipular la alineación de los controles dentro de los objetos Web. Complementando este editor, existe el Editor de Temas (que veremos más adelante), que permite configurar de una forma sencilla las propiedades de estos controles (definiendo clases para los mismos), simplificando así el desarrollo y mantenimiento de las aplicaciones Web. Podemos clasificar los controles que se pueden utilizar dentro de los objetos Web en dos grupos: 1. Aquellos que pueden ser usados en todos los objetos GeneXus:    Atributos Variables Botones 2. Los que son propios de los objetos Web, o tienen un comportamiento diferente que en el resto de los objetos:        Imágenes Grid Texto Text Block Tabla Grid Free Style Error viewer   Web Components Embedded Pages Más adelante se detallan estos tipos de controles. Para trabajar con objetos Web se dispone de dos barras de herramientas: una habilita las funcionalidades del editor, mientras que la otra permite la inserción de los controles. A continuación se documentan las operaciones que se pueden realizar con cada una de ellas, así como las características de los controles disponibles en objetos Web. Barra de herramientas Pallete Para insertar controles en el form del objeto Web se puede utilizar la opción Insert del menú de GeneXus o la barra de herramientas denominada Pallete. Select Habilita la selección de uno o más controles. Attribute Text Hyperlink Inserta un hipervínculo en el Web form. Se despliega un diálogo, desde el cual se podrá configurar el hipervínculo. Opción deshabilitada en ambiente Web Opción deshabilitada en ambiente Web Line Rectangle Table Grid Free Style Grid Button Image Inserta una imagen en el Web form. Se despliega un diálogo, desde el cual se selecciona la imagen a insertar. Tab Control Print Block ActiveX Web Component Embedded Page Opción deshabilitada en ambiente Web Solo habilitada en objeto Reporte Opción deshabilitada en ambiente Web Barra de herramientas Formating Esta barra de herramientas permite realizar las operaciones estándares de edición y formateo de texto. Una de las opciones destacables relacionada con objetos Web es , que permite visualizar los bordes de las tablas cuya propiedad Border esté con valor 0. De esta forma, se pueden ver en diseño los bordes de las tablas aún cuando éstos no se vean en ejecución. Otra opción interesante es que facilita el trabajo con controles de tipo Text Block. Design vs. Source Cuando se visualiza el form de un objeto Web, se pueden observar varias secciones en el borde inferior de la pantalla, entre ellas el ‘Web Form’. Cuando el objeto es una transacción las secciones disponibles son: Cuando el objeto es un Web panel, las secciones son: Al hacer clic sobre esta sección se puede diseñar la pantalla del objeto Web, es decir se insertan los controles y se visualiza el aspecto que va a tener en ejecución el mismo. Si se presiona el botón derecho del mouse dentro del formulario del objeto Web, además de la opción Properties (que permite configurar las propiedades del form) se visualizan dos opciones: ‘View Source’ y ‘Edit HTML Source’. Al seleccionar la opción ‘View Source’ se abre una ventana donde se puede visualizar el código HTML que se va a generar al ejecutar dicho objeto. Al cerrarla, se vuelve al formulario del objeto Web. Si se selecciona la opción ‘Edit HTML Source’, se puede modificar el código HTML o agregar código, de forma tal que el cambio se mantiene en el objeto y se genera posteriormente. En este caso, el código se visualiza dentro de la ventana del objeto Web y para volver al formulario, es necesario volver a presionar el botón derecho del mouse y seleccionar la opción ‘Edit Web Form’. La opción “Edit HTML Source” se usa para cualquier caso en el que sea necesario agregar código HTML manualmente, por ejemplo, agregar código javascript (si bien esto se puede hacer de otras formas). Todo el HTML que se agregue queda entre los Tags <Body></Body> del objeto generado. Normalmente, se diseña el objeto Web sin requerir editar el código HTML, pero en caso de necesitarse esta es la forma de hacerlo. Controles y sus propiedades En este capítulo iremos viendo los diferentes controles de los objetos Web y las propiedades de cada uno de ellos. Es importante resaltar que la asignación de las propiedades puede hacerse directamente en el control o en una clase de un Tema. En ambos casos, se asigna el valor a la misma, pero lo que varía es el costo de mantenimiento posterior. En el caso de asignar las propiedades directamente en el control, estas solamente aplicarán al mismo. Esta asignación puede hacerse en tiempo de diseño y para algunas de las propiedades pueden modificarse en tiempo de ejecución (programando los eventos del objeto). Cualquier cambio, requerirá generar y compilar el objeto. En el caso de asignar las propiedades en la clase de un tema, cualquier cambio de diseño, se realizará en el Tema, sin necesidad de generar/compilar absolutamente nada. En este capítulo se verá una introducción al objeto Tema y el Editor de Temas, y más adelante en el curso, se verá en detalle el funcionamiento de ambos. Por detalles de la forma de asignar las propiedades de los controles, referirse a: Orden de precedencia de las propiedades ¿Qué es un Tema? Un Tema es un objeto GeneXus, mediante el cual se pueden definir clases para los diferentes controles Web GeneXus, y asignar propiedades a dichas clases. Una vez asociado un Tema a un objeto (mediante la propiedad “Theme”), los controles de ese objeto podrán ser asociados a alguna clase del Tema. Al asociar una clase a un control éste pasa a heredar la configuración de las propiedades dada en la clase. Los Web Panels y las Transacciones son los objetos a los que se les puede asignar un Tema. Cómo asociar un tema a un objeto Las formas de asociar un tema a los objetos GeneXus son tres: asignarla a nivel de la base de conocimiento, del modelo o específicamente del objeto. Este es el orden también para la precedencia: si está asignada a nivel de objeto, se considera ese valor, sino el del modelo y si no está asignado, el de la base de conocimiento. Para asociarlo al objeto directamente, se debe configurar la propiedad Theme perteneciente a las “Object Properties”. Para asociarlo al modelo, se debe configurar la propiedad “Theme” disponible en el grupo “Web Information” (File / Edit Model / Properties). Para asociarlo a la base de conocimiento, se debe configurar la propiedad Theme del modelo de diseño (File / Edit Model / Properties / Theme) Este mismo orden de precedencia se utiliza para determinar los valores por defecto de la propiedad “Theme”: el valor por defecto de la propiedad de un objeto es el valor de la propiedad del modelo y el del modelo es el valor de la misma propiedad de la base de conocimiento. La propiedad Theme del modelo, está asociada por defecto al Tema “Default”, por lo cual, por defecto los objetos de la base de conocimiento están asociados al mismo Tema. Cómo asociar una clase a un control La forma de asociar una Clase de un Tema a un control, es a través de la propiedad “Class”. La propiedad Class es una propiedad del control, y es posible también cambiarla en tiempo de ejecución. Cómo modificar un tema Los temas se modifican utilizando un Editor especial, que es de libre distribución y puede ser ejecutado independientemente de GeneXus. Esto permite a los diseñadores del sitio Web trabajar en el diseño del sitio en forma independiente al ambiente GeneXus. En el siguiente documento se describen las Generalidades del Editor de Temas. Text Block Los controles ‘Text Block’ pueden ser vistos como texto insertado directamente en el form, con la ventaja que en forma dinámica (en ejecución) se puede modificar el mismo. Para insertar un Text Block, se puede presionar el botón de la barra de controles disponibles. Edición del control Text Block Los text blocks no pueden ser editados directamente desde el form y tienen que ser modificados desde las propiedades del Menú contextual (botón derecho, properties). que facilita el trabajo con En la barra de herramientas para el form HTML se incluye un botón controles de tipo Text Block. Al presionar el botón mencionado, se visualizan los TAG’s que lo definen permitiendo detectar cualquier problema en diseño. Propiedades del control Text Block en diseño Las propiedades de este tipo de control son:       Caption ControlName Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. Format: El valor por defecto para Text Blocks es Text, y se puede cambiar a través de la propiedad “Default HTML Format(Textblocks only)” del modelo de diseño. Fill ForeColor    Font OnClickEvent ReturnOnClick Propiedades del control Text Block en ejecución Además de las propiedades detalladas anteriormente, se pueden modificar las siguientes propiedades de los Text Blocks en tiempo de ejecución:       BackColor Visible Enabled Link LinkTarget Format Propiedades del control textblock en los Temas Además de estas propiedades mencionadas, en la clase Textblock (o alguna clase derivada de ella) de un Tema, se pueden configurar otras propiedades para los Text blocks. Ver Clase Textblock. Demo: Creación del primer Web Panel Comenzaremos creando un Web Panel donde el usuario deberá registrarse. El nombre del objeto será Login. En este objeto, le pediremos que ingrese un usuario y una contraseña y validaremos la información con la base de datos donde se almacenan los usuarios registrados en el sitio. Para que pueda ingresar un valor para el usuario y la contraseña, definiremos dos variables en el form. Para que no se visualice lo que escribe mientras ingresa la contraseña, es decir, que aparezcan asteriscos, se debe utilizar la propiedad “IsPassword” asociada a las variables. Si se programa Variable.IsPassword = 0 se puede visualizar lo que el usuario digita sobre la variable. Si por el contrario, programamos Variable.IsPassword = 1, al ejecutar aparecen asteriscos (*******) mientras el usuario digita sobre la variable.Definiremos también un botón que tendrá asociado el evento “Login” donde más adelante se realizará la lógica de validación del usuario. Vea la demostración aquí Ahora, especificaremos, generaremos y compilaremos el Developer Menu para poder ejecutarlo. En ejecución, el Web Panel se verá como lo siguiente: Si observamos bien el Web Panel, las variables de ingreso de datos no están alineadas. Para alinear controles (por ejemplo: que todas las variables donde el usuario va a ingresar los datos queden alineadas a la izquierda), se deben usar Tablas. Vale la pena destacar que si las dos variables se insertan al mismo tiempo (desde el diálogo correspondiente) GeneXus automáticamente incluye una tabla para alinear los controles. En el próximo punto veremos cómo alinear los controles del Web Panel insertándolos dentro de una tabla. Pero antes de eso, realicemos algunos cambios en el Tema para verificar los conceptos aprendidos recientemente. Demo: Trabajando con Temas Observe que en la base de conocimiento que Ud. ha creado para realizar los ejercicios prácticos, existe un Tema de nombre “Default”. Este Tema se crea automáticamente al crear una nueva base de conocimiento. Observe también que la propiedad “Theme” del modelo, está asociada por defecto al Tema “Default”, por lo cual, por defecto los objetos de la base de conocimiento están asociados al mismo Tema. Observe lo dicho anteriormente, en el Web Panel creado. Ahora, modificaremos el Tema “Default”, de forma de ejemplificar como se trabaja con los Temas. Haremos las siguientes modificaciones   Darle un valor a la propiedad BorderStyle y ForeColor de la clase Attribute A la clase Button, le asignaremos un BackColor y un Height En la siguiente demostración veremos los pasos seguidos para modificar el Tema “Default” y el efecto de esos cambios sobre el Web Panel que hemos creado en este capítulo. Es posible también definir la configuración de los HTML Tags involucrados en el HTML de la Web Page. En el curso, a medida que se vayan realizando los ejercicios prácticos, se explicarán más detalles del objeto Tema y su funcionalidad, incluyendo casos de uso de los HTML Tags, y las ventajas que presenta a la hora de realizar el diseño estético del sitio Web. Tablas Cuando se trabaja con objetos web, es necesario utilizar tablas para poder alinear los controles dentro del formulario para mejorar el diseño de los mismos. Agregar tabla Para insertar una tabla se debe utilizar el botón de la barra de controles. Una tabla está compuesta por filas y celdas, dentro de las que se encuentran los controles. Propiedades de las tablas Las propiedades varían dependiendo de la selección realizada, es decir que las propiedades disponibles para una celda tienen alguna variación con respecto a las disponibles para la tabla o la fila. A continuación se documentan las propiedades a nivel de tabla, fila y celda. Para editar las propiedades de una tabla se debe marcar la tabla (el puntero del mouse cambiará al posicionarse en los bordes de la misma y en la barra de status se indicará el nombre del control seleccionado) y presionar el botón derecho del mouse. Seleccionar la opción Properties del menú pop-up que se despliega. Otra forma de editarlas es presionando el botón derecho del mouse estando posicionado en cualquier celda de la tabla, y después ir a la sección de Table. En este caso, se podrán editar además de las propiedades de la tabla, las de la fila a la que pertenezca la celda y las propias de la celda.   ControlName Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. Tooltiptext Align Background Backcolor BorderWidth: 0 indica que no tendrá borde en ejecución, pero podrá verse en diseño usando el botón de la barra de herramientas. El valor por defecto es 1.            BorderColor Cellpadding Cellspacing Height Width Rules PROPIEDADES DE LAS FILAS DE UNA TABLA Como se puede observar en el diálogo de propiedades –sección ROW-, se pueden asignar valores a propiedades para una fila particular dentro de las tablas. Estos valores tendrán preferencia a los asignados para la tabla en general. Las propiedades de las filas, son algunas de las propiedades de las tablas, más una propiedad adicional: Vertical Align.       Identifier TooltipText Align Vertical Align Backcolor BorderColor PROPIEDADES DE LAS CELDAS DE UNA TABLA Las propiedades de una celda de una tabla son las que se muestran a continuación:            Identifier Tooltiptext Align VerticalAlign Background Backcolor Bordercolor Height Width Colspan Rowspan Propiedades de tablas en los Temas Además de estas propiedades, en la clase Table (o derivadas de ella) de un Tema, se pueden configurar otras propiedades que permiten definir otras características a las tablas. Ver Clase Table Demo: Creación de una Tabla Como decíamos anteriormente, para alinear los controles debemos definir una tabla en el form. Podríamos definir una nueva tabla de 3 x 2 y arrastrar los controles a la misma. Podríamos también, seleccionar nuevamente las variables para que GeneXus automáticamente agregue la tabla con las variables y las descripciones correspondientes. Luego, debemos posicionar el Mouse en la última celda y con el botón derecho seleccionar la opción Insert Row para agregar una nueva fila donde incluiremos el botón. Vea la demostración aquí Ahora, compruebe en ejecución la alineación de los controles. Más adelante, veremos más casos prácticos del uso de las tablas. Demo: Cómo darle un mensaje al usuario En este momento ya tenemos implementada nuestra pantalla donde el usuario final va a ingresar su usuario y contraseña. Tenemos que verificar en el evento Enter del botón “Login” si existe en nuestra tabla de usuarios (Users) un usuario con dicho Nick Name. Si existe, verificar que la password ingresada sea correcta y en caso de no existir darle un mensaje al usuario final informándole que se debe registrar como nuevo usuario. En un Work Panel normalmente lo haríamos utilizando el comando msg(), y se abriría una nueva ventana con el mensaje. En los objetos Web utilizamos el mismo comando msg(), la diferencia está en dónde se mostrará dicho mensaje, en una caja de texto y/o en el control Error Viewer (como veremos más adelante) ya que contamos en Web con las facilidades que nos brinda Ajax. Volvamos entonces a nuestro ejemplo para hacer el control del usuario y password en el evento Enter del botón “Login” y agregar el comando msg() para desplegarle al cliente el mensaje que corresponda. Haga clic aquí para ver la demostración Orden de precedencia de las propiedades Las propiedades de un control se pueden configurar en:   Ejecución (cambiando el valor de la propiedad mediante código GeneXus). Diseño (en las propiedades del control mismo, seleccionando el control y con botón derecho haciendo clic en “Properties”). El Tema En este último caso se configuran las propiedades en una clase del Tema. La clase se asocia al control, a través de la propiedad “Class” del mismo. La propiedad “Class” se puede asignar a un control tanto en tiempo de diseño como en ejecución. Para poder asociar una clase determinada a un control en tiempo de diseño, es necesario que el Tema en el cual está definido la clase se asocie al objeto que contiene el control. La asociación de un Tema a un objeto se hace a través de la propiedad “Theme” del objeto.  El orden de precedencia que se tiene en cuenta para que el control adopte las propiedades configuradas, es el siguiente: 1. 2. 3. Ejecución Diseño Tema Es decir que si una propiedad de un determinado control está configurada en el Tema, y también en diseño; la configuración dada en diseño tiene precedencia sobre la del Tema; y la dada en ejecución sobre la de diseño. Se recomienda en general configurar las propiedades a nivel de los Temas, ya que de esta forma se reduce el costo de mantenimiento del sitio. Cuando se trabaja con objetos Tema de la base de conocimiento, el Editor de Temas, salva en el directorio Web un archivo con extensión .CSS (Cascading Style Sheet). Cambiando el Tema asociado al objeto que se desea modificar, basta con llevar el CSS a producción y no es necesario generar/compilar nuevamente la aplicación. Esto último sí resulta necesario de hacer en caso de configurar las propiedades en tiempo de diseño. Nota: Observar que si un control está asociado a una clase de un Tema, el valor default de las propiedades del control se corresponde a los valores configurados en la clase. En el diálogo de propiedades, el valor default se puede identificar con un asterisco negro al lado de la propiedad: En el siguiente ejemplo, el control tiene una clase asociada (“Attribute”), sin embargo, la propiedad “ForeColor”, está configurada a nivel de diseño. En este caso, el asterisco al lado de la clase se visualiza en color gris (valor no default). Propiedades del Form Al form de los objetos Web se le pueden asignar propiedades haciendo clic y seleccionando la opción Properties del menú. Esta asignación de propiedades, puede hacerse en un objeto tema o directamente en el control. En el caso de asignar propiedades en el control solamente aplicará al mismo y puede hacerse en tiempo de diseño y algunas de ellas también pueden modificarse en tiempo de ejecución (programando los eventos del objeto). Propiedades en Tiempo de Diseño Las propiedades del form que pueden asignarse son las que se muestran en el siguiente diálogo.  Class: La propiedad Class solo se encuentra disponible si el form pertenece a un objeto que tiene un Tema asociado. BackColor TextColor Background Background Properties TooltipText WordWrap       Propiedades para el color de los Links    ActiveLinkColor VisitedLinkColor NotVisitedLinkColor Propiedades para los márgenes  TopMargin    BottomMargin LeftMargin RightMargin Propiedades del form HTML en tiempo de ejecución En ejecución se pueden modificar las siguientes propiedades del Form:    BackColor Background Caption: El caption del form se transforma en el título de la ventana. Por defecto, tiene el nombre del objeto Web. Esta propiedad solamente puede modificarse en tiempo de ejecución. Propiedades del Form en los Temas Es posible configurar en la Clase Form (o derivadas de ella) en el objeto tema, varias de las propiedades de los forms disponibles en GeneXus y otras que no están en GeneXus. En el caso de que una propiedad esté asignada en el control (en diseño o en ejecución) ese valor tiene precedencia respecto al asignado en el tema. Ver Orden de precedencia de las propiedades. Por detalles de propiedades del Form en los Temas, referirse a Clase Form. Atributos y Variables Al seleccionar un control y presionar el botón derecho del mouse aparecen sus propiedades para ser modificadas. Esta modificación se considera realizada en tiempo de diseño. Para modificar las propiedades de estos controles en ejecución, es necesario programarlo en algún evento del objeto. La sintaxis es normalmente <nombredecontrol>.<propiedad> = valor. Un ejemplo puede ser &pwd.IsPassword = 1 Recuerde que muchas de estas propiedades pueden asignarse en el objeto Tema en la clase Attribute, permitiendo así mayor dinamismo a la aplicación. Si en el diálogo de selección de atributos o en el diálogo de selección de variables se seleccionan varios a la vez, éstos se insertan en el formulario dentro de una tabla, simplificando así la tarea de alineación. Propiedades del control Edit en diseño Las variables y atributos son controles de tipo Edit, que tienen las siguientes propiedades:   Attribute Class  Control Type: Las propiedades que se aplican sobre atributos y variables, dependen del tipo de control que se seleccione. (Ver propiedades según el tipo de control). Dentro del grupo Appearance se encuentran todas las propiedades que aplican al aspecto del control. Se detallan a continuación: Auto Resize: Esta propiedad aplica a controles edit que NO tengan la propiedad Read-Only con el valor ‘True’, ya que en este caso se ignora el ancho especificado. Fill BackColor ForeColor Font Format Tooltiptext ReturnOnClick OnClickEvent            Dentro del grupo Behavior se encuentran todas las propiedades que aplican al comportamiento del control. Se detallan a continuación: ReadOnly EnableHistory EmptyAsNull IsPassword InputType: Esta propiedad permite sustituir lo que el usuario digita en un atributo por un valor más amigable. Si esta propiedad toma el valor ‘Descriptions’, permite que el usuario digite la descripción de otro atributo y se habilitan las siguientes propiedades: ItemValues, ItemDescription, InstantiedAttributes, Conditions. Esto se puede realizar a nivel del atributo para que aplique por defecto en todos los forms en donde este atributo esté presente como control, o también, es posible definirlo en forma particular, para un control atributo en concreto de un form determinado. En este último caso se definirá en el control info de ese control en particular. Suggest: Posibilita al usuario que elija entre un conjunto de valores posibles (una lista de posibles valores que se despliega debajo del control) y no tenga que recordar exactamente el valor a digitar. La lista de sugerencias puede ser calculada de un modo incremental (la lista es actualizada con las entradas del usuario) o haciendo pedidos explícitos (el usuario manualmente hace un pedido para que se calculen las sugerencias y se le muestren). La actualización de la lista es asincrónica y los tiempos de cálculo dependen de la calidad de la conexión. Al tomar los valores Incremental u OnRequest, se habilitan las siguientes propiedades: ItemValues, InstantiedAttributes, Conditions, FilterOperator, SortDescriptions, CaseSensitive, SuggestMaxItems. Esto se puede realizar tanto a nivel del atributo como del control. Conditions: Permite condicionar los valores sugeridos y/o los valores que puede tomar el atributo edit. InstantiedAttributes: Permite filtrar el conjunto de valores dependiendo de otros atributos que no pueden ser inferidos directamente.         Propiedades del Control Edit en Tiempo de Ejecución Además de las propiedades vistas anteriormente, existen otras que permiten modificar en tiempo de ejecución los controles de tipo edit. Las propiedades son:                Backcolor BackStyle Enabled FontBold FontItalic FontName FontSize FontStrikethru FontUnderline ForeColor Format InternalName IsPassword Link LinkTarget   Visible Class Propiedades según el Tipo de Control Hay otras propiedades, específicas según el tipo de control que se utilice. COMBO BOX Las propiedades a nivel de diseño que aplican son:       Attribute BackColor ForeColor Fill Font ReadOnly Las propiedades a nivel de ejecución son:             Backcolor BackStyle Enabled FontBold FontItalic FontName FontSize FontStrikethru FontUnderline ForeColor InternalName Visible NOTA: Alineación de un combo box/dynamic combo box en grids. Siempre se alinea a la izquierda independientemente del tipo de datos. Esto se hace así porque aún cuando el combo sea sobre un atributo numérico los valores que se muestran en el combo son de tipo carácter. RADIO BUTTON, CHECK BOX Las propiedades a nivel de diseño que aplican son:      Attribute BackColor ForeColor Fill Font Los radio button tienen también la propiedad Radio Direction que permite indicar si las opciones del radio button se desplegarán en forma vertical u horizontal. Las propiedades a nivel de ejecución son:                    BackColor BackStyle Caption Class Enabled FontBold FontItalic FontName FontSize FontStrikethru FontUnderline ForeColor Height ImeMode InternalName IsPassword Left Tag ToolTipText    Top Visible Widht Propiedades de atributos/variables en el Tema Las propiedades se pueden configurar también en el Tema. La clase predefinida “Attribute” del Editor de Temas reúne las propiedades para todos los controles en los cuales se puedan representar atributos/variables en el form, a saber:  Edit  Combo Box  List Box  Radio Button Obviamente se pueden derivar clases de la clase predefinida “Attribute”, por más información referirse a Clase Attribute. Propiedades de variables de tipo bitmap en diseño Las propiedades que se detallan a continuación aplican únicamente a variables de tipo bitmap.          Class Autoresize Borderwidth AlternateText Tooltiptext Hspace Vspace ReturnOnClick OnClickEvent Propiedades de variables de tipo bitmap en tiempo de ejecución A las variables de tipo bitmap se le pueden modificar las siguientes propiedades en tiempo de ejecución:            AlternateText Borderwidth Class Enabled InternalName Link LinkTarget Tooltiptext Visible Vspace HSpace NOTA: La propiedad Enabled de Runtime permite habilitar (Enabled=1)/deshabilitar (Enabled=0) la ejecución del evento asociado a la variable bitmap. Propiedades de variables de tipo bitmap en el Tema Las propiedades de las variables bitmap (y controles imagen), se pueden configurar en los Temas. Referirse a Clase Image. Métodos de los Controles Los métodos que aplican a los controles combo box, dynamic combo box, listbox y radio button son:        AddItem Clear Removeitem Repaint Setfocus Text Value Picture de los tipos de datos Date y Datetime Se formatea lo digitado por el usuario en campos de tipo Date y Datetime. Esto permite, por ejemplo, que el usuario final digite una fecha u hora sin los separadores ('/', ':', etc.) y se mejore la "visualización". El formateo ocurre cuando el usuario "sale" del campo y controla únicamente que el formato sea correcto. No se controla que la fecha y/o hora sea válida: esto lo hacen los programas. En caso de que el formato no sea correcto, se emite un mensaje de error (una ventana con el mensaje 'Date or time format is not correct') y se vuelve el foco al campo incorrecto. Botones Para insertar un botón en el formulario se puede seleccionar el disponibles. de la barra de controles En los objetos Web se pueden usar varios botones y asociarles eventos (predefinidos de GeneXus o definidos por el usuario). Al presionar el botón derecho del mouse se visualiza el siguiente diálogo que habilita al usuario a editar las propiedades del mismo o a editar el evento que el botón tiene asociado. Propiedades de botones Las propiedades de los controles de tipo Button que pueden modificarse en diseño son:   ControlName Class        OnClickEvent Caption Font ForeColor BackColor BorderWidth BorderColor En ejecución se pueden modificar todas estas propiedades (excepto la control name) del botón y además las siguientes:  Enabled  Internal Name  Visible Propiedades de botones en temas Además de estas propiedades, en la clase Button de un tema se pueden setear otras propiedades que permiten definir otras características a los botones. Ver Clase Button. Tamaño de botones El tamaño del botón queda determinado por el texto ingresado en la propiedad Caption del mismo. Si se desea que los botones tengan un tamaño fijo, se deben asociar mediante la propiedad Class a una clase de un tema que tenga un tamaño definido (propiedades Heigth y Width). En este caso, el tamaño quedará fijo independientemente del caption. Cómo asignar un evento a un botón Para asignar un evento a un botón se puede ingresar directamente el nombre del evento (entre comillas . Al utilizar este selector de eventos se visualiza el siguiente diálogo, con simples) o hacer clic al botón los eventos disponibles, habilitando al usuario la creación un nuevo evento (mediante el botón New). INTRODUCCIÓN Los web panels al igual que los work panels son objetos GeneXus que permiten al usuario en tiempo de ejecución, realizar interactivamente consultas a la base de datos a través de una pantalla. El término interactivamente se refiere a que el usuario podrá ingresar en la pantalla de un web panel, una y otra vez distintos valores de filtros, y consultar a continuación los datos que concuerden con los mismos. Además, sobre los datos consultados, el usuario podrá realizar distintas acciones, como veremos. Los web panels no permiten la actualización de la base de datos, sino sólo consultarla. El objetivo primordial de los web panels es la definición de consultas interactivas a la base de datos, sin embargo se trata de un objeto muy flexible por lo que se presta para diversos usos más. En este capítulo estudiaremos todos los detalles acerca de los web panels y los compararemos con los work panels para establecer las similitudes y diferencias. Opciones para definir filtros en Web Panels Cuando un Web Panel es invocado desde otro objeto, y se requiere que reciba uno o más parámetros para filtrar por igualdad por los mismos, la forma más directa y sencilla de resolverlo es declarando en la regla parm del objeto, a dicho(s) parámetro(s) por los cuales se necesita filtrar por igualdad, como atributo(s). (PIE 1) Es decir, si por ejemplo un web panel exhibe las facturas de un cliente, y se requiere que reciba por parámetro el código del cliente del cual se deben mostrar sus facuras, la opción más directa y sencilla para definir el filtro es en la regla parm, recibiendo al código de cliente en el atributo mismo: parm(CliCod); De esta forma, GeneXus entenderá automáticamente que el atributo CliCod actuará como filtro por igualdad en todo el objeto (es decir, que será un filtro global). Otra alternativa posible, es recibir en la regla parm a una variable y luego definir una condición de filtro: CliCod=&CliCod; Recordemos que cuando se reciben variables en la regla parm, GeneXus no hace nada automáticamente con ellas, por lo tanto el analista deberá definir condiciones de filtro explícitamente utilizando a las variables como desee. Cuando en cambio, se trata de web panels que no reciben parámetros, y que las condiciones de filtro deben definirse explícitamente (por ejemplo involucrando a variables cuyos valores son ingresados por el usuario en tiempo de ejecución en la parte fija del web panel) habrá que decidir si definir condiciones globales o condiciones a nivel de un grid en particular. (PIE 2) Las opciones para definir filtros son las mismas en web panels y en work panels Recomendamos acceder al material del Curso No Presencial de GeneXus donde encontrará información específica de este tema. Eventos en Web Panels En los web panels se utiliza la programación dirigida por eventos, que es un estilo de programación en el cuál se define código que permanece ocioso, hasta que suceden eventos provocados por el usuario o por el sistema, que provocan que el código definido se ejecute. Los eventos son acciones reconocidas por un objeto que pueden suceder o no. A cada evento se le puede asociar código, que se ejecutará solamente si el evento se produce. El código que se le puede asociar a un evento, se escribe con estilo procedural; y cuando el evento se produce, el código asociado al mismo se ejecutará secuencialmente. Eventos existentes en Web Panels Los eventos existentes en los web panels, son:       Evento Start Evento Refresh Evento Load Evento Enter Eventos de Usuario Evento clic asociado a un control En primera instancia explicaremos cada uno de estos eventos conceptualmente y en qué momento exacto se ejecutan, y a lo largo del curso veremos varios ejemplos de utilización de los mismos. Orden de los datos en un Web Panel Para definir en un web panel que una consulta se efectúe ordenando por cierto(s) atributo(s), y por ende que los datos extraídos de la consulta se muestren ordenados con dicho criterio, se debe hacer clic con el botón derecho del mouse sobre el grid, y seleccionar el ítem Order en el siguiente menú pop up: A continuación, se presentará el siguiente diálogo para que se ingrese por qué atributo(s) se desea ordenar: Definir esto es equivalente a definir la cláusula order en el comando for each , por ejemplo: que para ordenar en forma descendente por un atributo se debe encerrar al atributo entre paréntesis (), o que se crean índices temporales cuando no existe un índice físico por los atributos por los cuales se indica ordenar. Solamente si el form del web panel no tiene ningún grid, y se necesita definir un orden específico para la consulta, se contará con la posibilidad de definir en la sección de reglas del web panel, la regla de sintaxis: order(att1, att2, attN); siendo att1, att2, attN: la lista de atributos que define el orden de la consulta. Recomendamos acceder al material del Curso No Presencial de GeneXus donde encontrará información específica de este tema. Reglas en Web Panels En el objeto work panel, las reglas más utilizadas son las siguientes: Order, Noaccept, Search, Hidden, Workfile_lines y default. En los web panels, hay algunas diferencias en el uso de las mismas. Order, Naccept, Hidden Estas tres reglas se utilizan de la misma forma en los work panels que en los web panels. Cuando se quiere usar la regla Hidden para atributos de un grid, se recomienda en lugar de eso, utilizar la propiedad de Visible. El valor de los atributos / variables de la regla hidden se "guarda" para cada línea de cada grid que exista en la pantalla. Los atributos con Visible en False, no se ven en el grid final pero también se "guardan" aunque solamente para cada línea del grid en el que fueron definidos. Se sugiere que se promueva el uso de los atributos con Visible en False para el desarrollo de aplicaciones en lugar de la regla hidden. La causa de esto es que los hiddens se mandan en todos los grids mientras que los otros sólo para el grid en que fueron definidos. Esto redunda en menos código HTML a enviar al Browser y, en consecuencia, mejor performance. Algo similar ocurre con la regla Order, ya que en caso de tener múltiples grids definidos en el objeto se recomienda usar la propiedad a nivel del grid y no la regla ya que se estará indicando concretamente a cual de los grids deberá aplicarse el orden. Workfile_lines Esta regla no aplica a los web panels ya que no existe una tabla temporal para almacenar el resultado de una consulta a la base de datos. La forma de hacer esto en web panels es usando la propiedad Rows del grid. Default Esta regla asigna un valor por defecto a una variable (definida en el objeto). El valor puede ser un literal entre comillas, un número o una de las funciones Today(), Date() o SysDate(), debiendo coincidir el tipo de datos del valor con el tipo de datos de la variable. El valor por defecto se asignará a la variable al principio de la ejecución del programa. Comandos en Objetos Web A continuación se detallan los comandos soportados por los Web Panels y las transacciones con interfaz Web. Call El comando Call no presenta grandes diferencias con respecto al resto de los objetos GeneXus. Es importante tener en cuenta que los objetos web ejecutan en el servidor y por consiguiente no pueden realizar llamadas a programas que tengan salida en pantalla, ya que la ejecución de dicha llamada cancelaría por time-out. En resumen, desde un objeto web, se puede llamar a otro objeto web, a un procedimiento o reporte que no tengan salida en pantalla. Link El comando link es equivalente al comando call para llamar a páginas estáticas o redireccionar a una URL. Este comando puede ser utilizado dentro de cualquier evento de un objeto web con excepción del evento Load. El resultado de la utilización de este comando es el redireccionamiento en forma automática a la URL especificada dentro del mismo. Sintaxis: Link( usr-pgm | ’url’ [{, parm}…] ) Donde: usr-pgm Es el nombre del web object al que se va a redireccionar url Es el nombre de la URL a la que se va a redireccionar parm Son los parámetros que recibe la URL. El pasaje de parámetros es opcional. Ejemplo: Event ENTER Link(‘http://www.ARTech.com.uy’) Endevent Load El comando Load es análogo al resto de los objetos GeneXus. Refresh El comando Refresh vuelve a cargar la página, teniendo el mismo efecto que presionar la tecla de función F5 del browser. La página se cargará manteniendo los últimos valores sometidos para las variables ingresadas por el usuario. Return Incluir el comando return en un objeto web, es equivalente a hacer un CALL al objeto que lo invocó. En consecuencia no equivale a presionar el botón ‘Back’ del browser, ya que si se ingresaron valores en variables del objeto web llamador, los mismos no son mantenidos al ejecutar el comando Return. Este comando Return puede ser ejecutado en cualquier evento o subrutina del objeto, salvo el evento Load y los métodos Load de las grillas. Tampoco puede ser ejecutado en subrutinas llamadas directa o indirectamente por el evento Load o métodos Load de las grillas. En caso que se ejecute en las mencionadas situaciones los resultados son impredecibles. En el caso del primer objeto web, el return intentará cerrar el navegador. Si se utiliza el método Set en un tipo de datos WebSession y luego se ejecuta el comando Return el valor de la(s) cookie(s) se establece correctamente. Comparación entre Web Panels y Work Panels Se puede decir que los objetos Web Panel y Work Panel de GeneXus son similares ya que ambos permiten definir consultas interactivas a la base de datos. Son objetos muy flexibles que se prestan para múltiples usos, cuya programación está dirigida por eventos. De todos modos, hay algunas diferencias causadas principalmente por el esquema de trabajo en Internet. Tabla Base La determinación de la tabla base de los Web Panels es análoga a la determinación de los Work Panels. Eventos Los eventos de los Web Panels son los mismos que en los Work Panels, es decir evento Start, Refresh, Load, Enter y los definidos por el usuario. La diferencia con los Work Panels es el orden de disparo de estos eventos. Esto está relacionado con el esquema de trabajo en Internet. Variables Como se menciona en el documento Esquema de trabajo en Internet, las variables adquieren los valores ingresados por el usuario después de presionar algún botón en el objeto web. Por ejemplo, cualquier link a otro objeto web especificado en el evento Start con una variable que se ingresa en un Web Panel no va a tener ningún valor cuando se haga clic sobre el link. Si en un evento se usa una variable que se carga en otro evento, entonces esa variable debe estar presente en el form. Si no está en el form, la variable no tendrá valor cuando se disparan los otros eventos (esto es por el “orden” en que ocurren los eventos). Además, deberá estar en el form después del control en el que se carga la variable. Por ejemplo, si la variable se carga en el Evento Load de una grilla entonces la variable tiene que estar en pantalla después de la grilla. Disparo de fórmulas stand alone En un Web Panel existen fórmulas que pueden ser gatilladas antes del evento Start y otras que deben gatillarse luego del mismo evento. Las fórmulas que se gatillan antes del evento Start son aquéllas que sólo dependen de los parámetros que llegan al programa (mediante la regla parm()) Las fórmulas que se gatillan después del evento Start son aquéllas que dependen de atributos o variables instanciados (vía asignación, Call, etc.) en el evento Start. Propiedades En los Work Panels las propiedades más utilizadas son las correspondientes al grupo Loading (Load Records, Load at Startup, Automatic Refresh y When to Refresh) para manipular la visualización de grandes cantidades de registros. En los Web Panels no se dispone de estas propiedades. En los Web Panels con tabla base la carga de los registros se realiza de una sola vez (lo que se corresponde con el valor Load all records de la propiedad Load Records) y la grilla se carga por primera vez inmediatamente a continuación de la apertura del form en tiempo de ejecución (lo que se corresponde con el valor Yes de la propiedad Load at Startup). En las grillas de los objetos Web para resolver la visualización de grandes cantidades de registros se dispone de la paginación automática. Determinación de la Tabla Base en Web Panels Web Panel con tabla base (a lo sumo un grid) El Web Panel es “con tabla base” cuando a lo sumo tiene un grid y GeneXus puede determinar un for each implícito asociado a él. Para determinar si un Web Panel tiene tabla base y en caso afirmativo cuál será, al momento de especificarlo GeneXus analiza los atributos incluidos en:      form: en la parte fija form: en el grid (visibles o no visibles) el order del grid las condiciones del grid (no en las condiciones globales) los eventos fuera de comandos for each GeneXus no toma en cuenta para determinar la tabla base de un Web Panel:   los atributos recibidos por parámetro los atributos mencionados en las condiciones globales del Web Panel Éstos actúan como filtros una vez determinada la tabla base. Web Panel con N tablas Cuando un Web Panel contiene más de un grid en su form, GeneXus no determina una única tabla base asociada, sino una tabla base asociada a cada grid. Atributos que participan en la determinación de la tabla base de cada grid:   Los incluidos en el grid (se tienen en cuenta tanto los atributos visibles como los no visibles) Los referenciados en Order y Conditions locales al grid Los atributos de la parte fija del Web Panel no participan en la determinación de la tabla base de ninguno de los grids, pero deberán pertenecer a la tabla extendida de alguno de ellos (para que sea posible inferir sus valores). De no respetarse esto, al especificar al Web Panel, se mostrará en el listado de navegación resultante, un warning advirtiendo de esta situación. Los atributos utilizados en los eventos del Web Panel tampoco participan en la determinación de la tabla base de ninguno de los grids. Los atributos que se incluyan en los eventos fuera de comandos for each, deberán pertenecer a la tabla extendida de alguno de los grids (al igual que los de la parte fija). Demo: Web Panel Principal del Sitio Comenzaremos a desarrollar el Web Panel principal del sitio donde el usuario va a poder buscar las atracciones turísticas y los servicios provistos de una ciudad como también los vuelos que arriban a la misma. El nombre del objeto será MainSearch y como será el punto principal de entrada de nuestro sitio lo definiremos como objeto Main asignando a la propiedad “Main” en “True”. Las Transacciones que ya están definidas en este sistema son las siguientes (se describen solo los principales atributos de las mismas) Country CityAttraction ServiceProvider CountryId* CountryName (CityId* CitiName) CountryId* CityId* (TouristAttractionId* TouristAttractionCatId) TourismServiceProviderId* TourismServiceProviderName TourismSerivceCatId CountryId CityId (TourismServiceCatTypeId* TourismServiceCatTypePrice) Flights TourismServiceCategory TouristAttractionCategory FlightId* DepartureCountryId DepartureCityId ArrivalCountryId ArrivalCityId (FlightCategory TourismServiceCatId* TourismServiceCatDsc TourismServiceCatImage (TourismServiceCatTypeId* TourismServiceCatTypeDsc) TouristAttractionCatId* TouristAttractionCatDescription TouristAttractionCatImage FlightPrice) Users UserId* UserNickName UserPwd UserLastName UserFirstName UserName UserEmail UserAddress UserPhone CountryId CountryName CityId CityName El objeto en ejecución deberá verse como el siguiente: En estos capítulos iremos adquiriendo los conocimientos necesarios para implementarlo. Nos centraremos primero en la parte principal de búsqueda. Allí programaremos la paginación a pedido en los grids, cargando 5 registros a la vez y pudiendo filtrar por país y ciudad. En cada grid, pondremos links a otros Web Panels con información más detallada. Para hacer esto crearemos dos variables en la parte fija del Web Panel, donde el usuario indicará los filtros correspondientes para el país y la ciudad (&CountryId y &CityId). Estas variables las definiremos basadas en los atributos para que “hereden” los tipos de datos de los mismos. Buscando que la interfaz sea amigable para los usuarios, se sugiere que el ingreso de datos sea simple y rápido. Para esto, se recomienda que los usuarios no deban ingresar (¡ni recordar!) códigos sino que puedan ingresar los nombres y que el diálogo les sugiera valores posibles a medida que digitan. Para esto, definiremos las variables como dynamic combo box con filtros. Definiremos que &CountryId sea un combo dinámico. Los valores posibles serán el atributo CountryId y las descripciones serán el nombre del país (CountryName). Además, utilizaremos un valor vacío que indique que no está seleccionado ningún país. Para esto, asignaremos a la propiedad “EmptyItem” el valor “Yes” y el texto será “Select a Country…” (se configura en la propiedad EmptyItemText). Lo mismo haremos con la ciudad. Para eso definiremos &CityId también como combo dinámico con un valor vacío de texto “Select a City…”. Recordar que al seleccionar más de un atributo, GeneXus crea una Tabla para alinear los controles. Sin embargo, el orden elegido no será el deseado por lo que deberán moverse los controles. Para que el combo muestre las ciudades del país elegido previamente, es necesario definirle una condición por el país. La condición será: CountryId = &CountryId; Agregaremos también un botón para realizar la búsqueda de los datos. Vea la demostración aquí Podemos ejecutar el Web Panel que hemos desarrollado para ir probando la funcionalidad. Primero lo especificaremos y generaremos. En la navegación vemos que: GeneXus navega la tabla COUNTRIES ordenada por nombre de país, para realizar la carga del combo dinámico &CountryId. Mientas que para la carga de &CityId, recorre la tabla COUNTRIES1 ordenado por el nombre de la ciudad y filtrando por el país seleccionado en la variable &CountryId. Como el objeto es main, podremos compilarlo y ejecutarlo directamente ya que aparece en el diálogo de ejecución. Cuando se desea que todos los combos dinámicos de la base de conocimiento muestren el mismo valor en ejecución para el valor vacío, se deja el valor GX_EmptyItemText propuesto en la propiedad EmptyItem. Este texto aparecerá como código en el Objeto Lenguaje para que pueda ser traducido. El texto propuesto es “(None)” cuando el idioma lenguaje es inglés. Lo mismo ocurrirá si se asigna un valor específico a esta propiedad a nivel del control o del atributo. En este caso, ese texto será una nueva entrada en los códigos del objeto Lenguaje. Recuerde que es necesario especificar el objeto antes de que aparezcan los códigos en el objeto Language. Evento Start (de Web Panels) El evento Start es un evento del sistema, que ocurre automáticamente. ¿En qué momento se ejecuta? Cuando comienza la ejecución del programa asociado a un web panel, es decir, ni bien se abre un web panel en tiempo de ejecución. ¿Cuántas veces se ejecuta? Una vez cuando comienza la ejecución del web panel y tantas veces más como ejecuciones de eventos de usuario se realicen que no incluyan una invocación a otro objeto web. En el evento Start no se conocen valores de atributos, salvo los recibidos por parámetro. Esto se debe a que aún no se ha efectuado la consulta. Generalmente se suelen incluir asignaciones de valores a variables, para inicializarlas. El Evento Start de un work panel se ejecuta una vez sóla cuando comienza la ejecución del mismo. Evento Refresh (de Web Panels) Cuando el usuario presiona el botón Refresh en un web panel se ejecuta el evento Refresh. A su vez, cuando el usuario pasa de la parte fija del web panel al grid, también se ejecuta el evento Refresh. Y cuando se ejecuta el comando Refresh incluido por el analista GeneXus en algún evento, también se ejecuta el evento Refresh. Se ejecuta cada vez que se realiza un Get o Post.. El evento Refresh es un evento del sistema que a continuación de ejecutarse, causa que se ejecute la consulta a la base de datos. Es decir, al ejecutarse el evento Refresh, se ejecuta el código asociado al mismo, y a continuación se ejecuta la consulta a la base de datos. Seguidamente, se ejecutará el evento Load. El Evento Start de un work panel se ejecuta una vez sóla cuando comienza la ejecución del mismo. Evento Load (de Web Panels) Cada vez que se ejecute el evento Refresh en un web panel, seguidamente a la ejecución del mismo, se ejecutará el evento Load. ¿Cuántas veces se ejecutará el evento Load? La cantidad de veces que se ejecutará el evento Load, dependerá de si el web panel tiene tabla base o no tiene tabla base. SI EL WEB PANEL TIENE TABLA BASE Si el web panel tiene tabla base, el evento Load se ejecutará N veces: una vez por cada registro leído en la consulta efectuada a la base de datos, justo antes de cargar los datos del registro en una línea en el grid. De modo que por cada registro leído en la consulta efectuada a la base de datos, se ejecutará el evento Load (ejecutándose el código incluido en el mismo, y cargándose a continuación una línea en el grid con los datos del registro). SI EL WEB PANEL NO TIENE TABLA BASE Si el web panel no tiene tabla base, el evento Load se ejecutará solamente una vez. Que el web panel no tenga tabla base, significa que no tiene un for each implícito asociado; por lo tanto, cuando se ejecute el evento Refresh, no comenzará a ejecutarse ninguna consulta; se ejecutará el código asociado al evento Refresh, y a continuación se ejecutará el código asociado al evento Load, una sola vez. Evento Enter (de Web Panels) Cuando se inserta un nuevo botón en el form de un Web Panel, por defecto aparece con el Caption “Confirm” y aparece asociado al evento del sistema Enter. El evento Enter puede asociarse a cualquier botón, atributo, imagen, text block, en la propiedad de los controles: OnClickEvent. De modo que si se necesita ejecutar acciones cuando el usuario final haga clic en el control asociado, en este evento deberán codificarse. Eventos de usuario (de Web Panels) Además de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por él, los cuales reciben el nombre de eventos de usuario. Cada evento de usuario debe asociarse a un control insertado en el form del web panel de los que soportan el OnClickEvent (botones, text blocks, imágenes, atributos). En tiempo de ejecución, el evento de usuario ocurrirá luego de que el usuario haga clic sobre el control asociado al mismo. Se consigue de dos maneras distintas: 1. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad OnClicEvent. De esta manera GeneXus define la siguiente sintaxis automáticamente: Event ‘Nombre Evento de Usuario’ [key] EndEvent … 2. Dándole un nombre al control y en la sección de Eventos programando: Event nombreControl.click … Endevent Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos programando el evento clic del control. Esquema de trabajo en Internet Es importante entender que en Internet, cuando el usuario accede a una página del servidor Web para visualizarla, el Browser baja la página al cliente. Por lo tanto, no existe forma de detectar lo que realiza el usuario: el Servidor Web volverá a tener el control cuando se dispare el evento Enter o algún evento de usuario. En ese momento se envía (o se somete, se hace un post) el resultado al servidor para continuar con su procesamiento. Es decir, una vez que el objeto web finaliza la ejecución en el servidor, no queda en memoria. Como consecuencia, la forma en que programamos este tipo de aplicaciones presenta algunas diferencias con respecto a lo acostumbrado en ambientes no web. Es por esta razón importante destacar el orden en que se disparan los eventos y el momento en que las variables adquieren el valor ingresado por el usuario. Orden de ejecución de los eventos El orden de ejecución de los eventos en web panels es diferente si se trata de la primera llamada al mismo (GET) o si se disparó algún evento de usuario o enter (POST). PRIMERA EJECUCIÓN DE LOS WEB PANELS La primera vez que se ejecuta el web panel (se conoce también como el momento en que se hace el “GET” de la página) los eventos que se disparan son los siguientes y en el siguiente orden: 1. 2. 3. Evento Start Evento Refresh Evento Load Luego de esto, cuando se ejecuta el evento Enter o un evento de usuario que no llame a ningún otro web panel (ya sea porque el usuario presionó un botón o dió clic en algún control del form con el evento Clic programado), se ejecutará nuevamente éste y el orden de disparo de los eventos será diferente. RESTO DE LAS EJECUCIONES DE LOS WEB PANELS En el resto de las ejecuciones (momento que se conoce también como el “POST” de la página) los eventos se dispararán en el siguiente orden: 1. 2. Evento Start (nuevamente se dispara el evento Start) Nueva lectura de las variables de la pantalla. Esto se realiza porque el usuario puede haberlas modificado (por ejemplo las variables de la parte fija del web panel que están involucradas en las conditions) Código correspondiente al evento asociado al botón seleccionado. Evento Refresh Evento Load 3. 4. 5. Relacionado con esto es importante destacar el momento en que las variables adquieren los valores ingresados por el usuario: solamente lo harán después de ejecutar un evento (presionar un botón), que es cuando el servidor Web tiene el control del procesamiento. Esto implica algunos cambios importantes en la forma de programar los objetos. Por ejemplo, cualquier link a otro web panel especificado en el Evento Start con una variable que se ingresa en el web panel no va a tener ningún valor cuando se haga clic sobre el link. Si en un Evento se usa una variable que se carga en otro evento, entonces esa variable debe estar presente en el form. Si no está en el form, la variable no tendrá valor cuando se disparan los otros eventos (esto es por el “orden” en que ocurren los eventos). Además, deberá estar en el form después del control en el que se carga la variable. Por ejemplo, si la variable se carga en el LOAD de un grid entonces la variable tiene que estar en pantalla después del grid. Si el evento que se ejecuta llama a otro web panel, comenzará a ejecutarse ese objeto, disparándose los eventos del mismo según lo descrito antes en la primer Ejecución de los web panels. En HTML se puede especificar dos métodos distintos para someter un formulario. El método se especifica dentro del elemento HTML “FORM”, usando el atributo “METHOD”, por ejemplo: <form id="MAINFORM" name="MAINFORM" method="POST" ACTION="hwfmain.aspx"> Las especificaciones HTML definen técnicamente la diferencia entre GET y POST de la siguiente forma:   En el GET, los datos del form son codificados por el browser en la URL misma. En el POST, los datos del form van en el cuerpo del mensaje. Entonces, cuando es METHOD="GET" los datos del form se codifican en una URL (o mas genéricamente en una URI), lo cual significa que esa forma de someter el form es equivalente a seguir un link a la URL codificada. En general, el GET es para recuperar datos mientras que el POST sería para grabar, actualizar datos, ordenar un producto, etc.. En GeneXus todos los eventos se resuelven con un POST y se ejecutan en el servidor Web. Demo: Esquema de Trabajo en Internet Aunque decimos que los web panels son similares a los work panels, hay una diferencia fundamental entre ellos relacionada con el hecho que el objeto web una vez que finaliza la ejecución, no queda en memoria. Como consecuencia, la forma en que programamos este tipo de aplicaciones presenta algunas diferencias con respecto a lo acostumbrado en ambientes no web. Es por esta razón que es importante tener claro el orden de ejecución de los eventos. Ejemplifiquemos esto, programando nuestra aplicación. Supongamos que en el evento donde validamos el usuario y la contraseña (en el web panel Login), guardamos en una variable el código de usuario para poder utilizarlo en otro evento. Esto nos permitiría, por ejemplo, llamar a un objeto que permita visualizar los datos del usuario. En consecuencia, deberíamos programar lo siguiente en el evento donde validamos el usuario: Event ‘Login’ for each where UserNickName = &UserNickName if UserPwd = &UserPwd &UserId = UserId login.Caption = "Welcome to Travel.com" else login.Visible = 1 login.Caption = "Invalid password" endif when none login.Visible = 1 login.Caption = "Invalid User" endfor Endevent Para realizar la llamada al web panel Perfil del Cliente (UserProfile), existen varias alternativas: se puede definir un link en algún evento, o se puede agregar un botón y en el evento asociado invocar al objeto. El link se podría definir en el mismo evento Login a continuación de la asignación de la variable. Si agregásemos un botón o una imagen con un evento clic asociado, entonces el código seria el siguiente: Event profile.clic/profile Call(HUserProfile,&UserId) Endevent Otra alternativa (la que vamos a implementar en este caso), es usar un control textblock y hacer el llamado al webpanel en el evento clic del textblock. Repasemos entonces lo que pasa en este segundo caso: 1. 2. 3. En la primer ejecución se disparan los eventos: Start, Refresh y Load y podemos ingresar el usuario y password. Cuando presionamos el botón para validar el login, se asigna a la variable &UserId el código de usuario correspondiente. Cuando presionamos la imagen con el evento clic asociado, se dispara el evento Start, se leen las variables que están en pantalla, se ejecuta el evento clic y ahí cuando trata de redireccionarnos al Web Panel CustProfile, la variable &CustId no tiene valor ninguno, ya que la misma se perdió luego de haber finalizado la ejecución del Web Panel en el punto 2. Haga clic aquí para ver la demostración Probemos el web panel con el usuario “myuser”, y password “mykey”. Este usuario ya ha sido definido en los datos que se distribuyen con el curso. Haga clic aquí para ver la ejecución Es por esta razón, que si queremos disponer del valor de la misma, deberíamos agregar la variable &UserId en el form y la ocultaríamos usando la propiedad Visible (por ejemplo en el evento Start). Entonces en este caso, cuando el web panel ejecute por segunda vez, se dispararán los eventos: 1. 2. 3. Start Se leen las variables del form (en este momento se obtiene el valor de CustId) Se ejecuta el evento clic, y por consiguiente se llama al web panel con el código de cliente correcto! Haga clic aquí para ver la demostración Haga clic aquí para ver la ejecución INTRODUCCIÓN En los objetos web, se dispone de más de un tipo de grid: el grid estándar y el grid Freestyle. Estos grids, potencian el diseño de aplicaciones Web, permitiendo al desarrollador mayor libertad a la hora del diseño. Además en el caso de los Web Panels, es posible utilizar múltiples grids y también anidarlos para permitir navegaciones más complejas. A lo largo de este capítulo iremos implementando todo esto a medida que vamos viendo los conceptos teóricos necesarios para su desarrollo. Control Grid Este control permite desplegar, -y dependiendo del objeto GeneXus que se trate, también ingresar, modificar y/o eliminar- información asociada a muchos registros. Puede utilizarse en los objetos con interfaz, es decir transacciones, web panels o work panels y permite incluir tanto atributos como variables (incluyendo las de tipo bitmap). Cuando el control Grid se utiliza en una transacción, por medio del mismo será posible insertar, modificar y/o eliminar registros, en la tabla asociada que corresponda (en ejemplo, en la tabla TOURISMSERVICELEVEL1). Cuando en cambio, el control Grid se utiliza en un web panel o work panel, el mismo permitirá visualizar únicamente los datos almacenados en tablas. En ejecución, el grid es una tabla HTML. que se encuentra en la barra de controles, permite insertar el control Grid. Al editar las El botón propiedades del control Grid, se abre un diálogo con las siguientes opciones: Columnas y Propiedades. Columns Permite indicar las columnas que componen el grid. Botones Add y Delete: Permiten agregar y eliminar columnas al grid respectivamente (tanto atributos como variables). Botones Move Up y Move Down: Permiten cambiar el orden de las columnas. Botón Properties: Permite asignar propiedades específicas a la columna seleccionada. Properties Permite asignar propiedades de visualización para el grid estándar. Propiedades del Grid A continuación se detallan las propiedades generales del grid:   Control Name Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. AutoResize Width Heigth LinesColor LinesFont TitleForeColor TitleFont                 BackColorStyle BorderColor Rows AllowCollapsing Collapsed AllowSelection SelectionColor AllowHovering HoveringColor Dependiendo del valor de la propiedad “BackColorStyle”, estarán disponibles otras propiedades adicionales relacionadas con la configuración de las líneas del grid. Si BackColorStyle = Header   LinesBackColor TitleBackColor Si BackColorStyle = Report    LinesBackColor LinesBackColorEven TitleBackColor Si BackColorStyle = Uniform  BackColor Cálculo del ancho de cada columna de un grid. El ancho de cada columna de un grid se especifica como un porcentaje del ancho total del grid (que por defecto no se especifica, el browser lo calcula en función al contenido de todas las celdas). El ancho del grid NO se deduce como la suma de los anchos de las columnas, ya que si estos se especifican en valores relativos (porcentajes), puede no corresponderse a lo deseado. Las propiedades LinesColor, LinesFont, TitleForeColor y TitleFont: Aplican a todas las columnas del grid, para modificar los valores correspondientes a una determinada columna, se deben modificar las propiedades de la misma (ver más adelante). TABLE Los grids también tienen algunas propiedades configurables para las tablas. Estas propiedades son:        ToolTiptext Align Background BorderWidth Cellpadding Cellspacing Rules Propiedades modificables en ejecución A continuación se detallan las propiedades que se pueden modificar a los grids en tiempo de ejecución:          Visible: si la propiedad Visible tiene el valor 0, el grid completo desaparece del formulario. No aplica a los grids de las transacciones. Backstyle BackColor BackColorEven BackColorOdd PageCount RecordCount Rows Align         AllowCollapsing AllowHovering AllowSelection BackColorStyle Background BorderColor BorderWidth CellPadding            CellSpacing Class Collapsed Height HoveringColor InternalName Rules SelectionColor TitleBackColor Tooltiptext Width Propiedades de las columnas del grid También es posible indicar propiedades particulares para las diferentes columnas que forman el grid. Para esto, se debe seleccionar la opción Columns del menú que aparece al hacer clic en el grid. En este diálogo, seleccionando Properties sobre una columna se despliega un diálogo, como el siguiente:   ControlName Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. ControlType InputType Suggest ReadOnly EnableHistory EmptyAsNull IsPassword Autoresize Font ForeColor Title TitleFont TitleForeColor Format Visible Tooltiptext ReturnOnClick                  PROPIEDADES DE COLUMNAS EN TIEMPO DE EJECUCIÓN En tiempo de ejecución se pueden modificar las siguientes propiedades de las columnas de un grid:                        Backcolor Backstyle Enabled EnableHistory FontBold FontItalic FontName FontSize FontStrikeThru FontUnderline ForeColor Format InternalName IsPassword Link LinkTarget Title TitleBackcolor TitleBackstyle TitleFontBold TitleFontItalic TitleFontName TitleFontSize        TitleFontStrikeThru TitleFontUnderline TitleForeColor TitleFormat Tooltiptext Visible Class Propiedades de grids en los Temas En la clase Grid o derivada de ella, en los Temas, es posible configurar propiedades adicionales para dicho control. Ver Clase Grid. Demo: Grid Estándar Continuemos con el desarrollo de nuestro objeto MainSearch Vamos ahora a definir el grid de los vuelos que arriban al país/ciudad seleccionado. Se quiere que solamente cuando no se selecciona un valor para el país y/o ciudad, en el grid aparezca una columna con esa información. En la descripción del vuelo incluiremos un link a otro Web Panel (denominado “Flight” que desarrollaremos más adelante, por eso definimos el nombre entre comillas para que lo considere como objeto externo) para mostrar los detalles del vuelo. Para esto, programaremos en el evento Load del control la propiedad link para el atributo FlightDsc. Por defecto, GeneXus propone nombres para los controles (que sugiere según el tipo de control y la cantidad de ese tipo que existan en el form). En muchos casos para simplificar la comprensión de la lógica del control puede ser útil asignarles nombres más intuitivos. Le asignaremos al control grid el nombre “Flights” y los atributos que lo componen serán la descripción, la aerolínea y el código del país/ciudad de donde parte el vuelo, por lo tanto será un grid con tabla base. El evento será: Event Flights.Load FlightDsc.Link = Link("HFlight", FlightId) Event Fligths.Refresh if &CityId.IsEmpty() ArrivalCityId.Visible = 1 else ArrivalCityId.Visible = 0 endif if &CountryId.IsEmpty() ArrivalCountryId.Visible = 1 else ArrivalCountryId.Visible = 0 endif EndEvent // Refresh Definiremos también las condiciones de filtro locales a este grid. Las condiciones son: ArrivalCountryId = &CountryId WHEN .NOT.&CountryId.isempty(); ArrivalCityId = &CityId WHEN .NOT.&CityId.Isempty(); Vea la demostración aquí Especifiquemos el objeto y revisemos la navegación del mismo. GeneXus navega la tabla COUNTRIES ordenada por nombre de país, para realizar la carga del combo dinámico &CountryId. Mientas que para la carga de &CityId, recorre la tabla COUNTRIES1 ordenado por el nombre de la ciudad y filtrando por el país seleccionado en la variable &CountryId. Para resolver el evento Load asociado al grid Flights, GeneXus navega la tabla FLIGHTS ordenada por número de vuelo y filtrando por el país seleccionado en la variable &CountryId (en el caso de que se haya seleccionado uno) y por la ciudad seleccionada en la variable &CityId (en el caso de que se haya seleccionado una). Genere el objeto y ejecútelo para ver como funciona. Al ejecutarlo habrá notado que si indica un valor para el país o la ciudad el dato no se muestra en la línea del vuelo, pero el título se mantiene. Esta es una de las principales diferencias entre los grids estándar y de tipo Free Style. Notar que las condiciones de filtro por país y ciudad se realizan con la cláusula WHEN para indicar que se toman en cuenta cuando las variables tengan un valor. En el caso de tener un valor nulo, no se considera la condición por lo que se recorrerá toda la tabla. Control Free Style Grid y sus propiedades El grid Free Style permite al usuario definir el formato de los datos a desplegar de una forma menos estructurada que el grid tradicional. Puede utilizarse en los objetos con interfaz web, es decir transacciones y web panels. El grid Free Style es básicamente una tabla a la que se le pueden insertar los atributos / variables, text blocks, imágenes, botones, web components, embedded pages, grids Free Style y/o grids que se van a mostrar posteriormente en la pantalla. Este tipo de grid no posee títulos para las columnas y además permite tener más de un tipo de control, atributo / variable en una misma celda, proporcionando de esta forma mayor libertad de diseño. En ejecución, el grid es una tabla HTML. de la barra de controles disponibles. Se Para insertar el grid Free Style se debe utilizar el botón despliega el diálogo de selección de atributos y variables que conformarán la grilla. Propiedades del grid Free Style Para visualizar las propiedades de un grid Free Style, hay que seleccionar la tabla del grid, presionar el botón derecho del mouse y seleccionar la opción ‘Properties’. A continuación se documentan las propiedades disponibles para el grid Free Style.   Control Name Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. BackColorStyle Rows Columns AllowCollapsing Collapsed      Dependiendo del valor de la propiedad “BackColorStyle”, estarán disponibles otras propiedades adicionales relacionadas con la configuración de las líneas del grid. Si BackColorStyle = Report  LinesBackColor  LinesBackColorEven Si BackColorStyle = Uniform  BackColor Propiedades del grid Free Style modificables en ejecución En tiempo de ejecución se puede modificar la siguiente propiedad:  Visible: Si la propiedad Visible tiene el valor 0, el grid Free Style desaparece del formulario. En el caso de tener grids anidados, la propiedad Visible aplicada al grid padre, aplica también a los grids hijos.                    Align AllowCollapsing BackColor BackColorEven BackColorOdd BackColorStyle Background BorderColor BorderWidth CellPadding CellSpacing Class Collapsed Columns Height InternalName PageCount RecordCount Rows   Rules Width Propiedades del grid Free Style en los Temas En la clase FreeStyleGrid o derivada de ella, en los Temas, es posible configurar propiedades adicionales para dicho control. Ver Clase FreeStyleGrid. Demo: Grid Free Style Diseñando el Web Panel Flights Vamos ahora a definir el Web Panel “Flights” que invocamos desde el grid de los vuelos del objeto MainSearch para mostrar los detalles del vuelo. Este será un Web Panel de salida (así se clasifican los Web Panels -y también los Work Panels- cuya única función es exhibir datos). Para que un Web Panel únicamente muestre datos, su form debe contener solamente atributos, ya que los atributos al incluirse en Web Panels son indefectiblemente de salida. Otra posibilidad es incluir en el form variables (sin ningún evento que las procese con el comando For Each line) y cargarles valores explícitamente. Mostraremos los datos básicos del vuelo, la aerolínea, el origen y el destino del mismo y también los datos de los posibles precios. Pondremos también las banderas de los países, para eso, usaremos variables de tipo bitmap donde cargaremos las imágenes correspondientes. Comencemos entonces creando un nuevo objeto de tipo Web Panel con nombre Flights. Como recibiremos como parámetro el código del vuelo, definimos la regla parm(FlightId); En el form incluiremos los atributos y definiremos el grid. Usaremos una tabla para agrupar los atributos correspondientes al vuelo. Para los precios, utilizaremos un grid Free Style, que nos de más libertad en el diseño. Le asignaremos el nombre Prices al control y para mostrar la información en forma horizontal (y no vertical) utilizaremos las propiedades Rows y Column. Vea la demostración aquí Se recomienda repasar la clasificación de los tipos de Work Panels en el material del curso no presencial de GeneXus Cómo trabajar con grids en Web Panels A continuación se detalla la forma de trabajo con grids en Web Panels. Cómo desplegar datos Por defecto todo atributo y variable que está dentro de un grid se despliega en ejecución como texto, es decir que son únicamente de lectura y por consiguiente no pueden ser modificados. Cómo aceptar datos Es posible aceptar datos en las variables de un grid dependiendo de la programación de los eventos existentes en el objeto. Si: 1. 2. dentro de un evento del Web Panel se está utilizando el comando For each line o For each line in <grid>, ó existe algún control en el grid con un evento clic asociado, entonces todas las variables que están dentro del grid pasan a ser de ingreso. Es posible indicar en este caso cuáles son las variables que no van a poder ser modificadas utilizando la regla noaccept() o modificando la propiedad Read Only de la variable dentro del grid. Cómo asociar eventos a una línea Es posible asociar un evento a cualquier variable o atributo que pertenezca al grid. Se consigue de dos maneras distintas: 1. 2. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad OnClicEvent En la sección de Eventos programando: Event nombreControl.click … Endevent Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos programando el evento clic. Cómo seleccionar líneas Para ello, se accede a las propiedades del grid haciendo clic en el botón derecho sobre el control grid y se configura la propiedad AllowSelection con el valor ‘True’. Al hacerlo se habilitan tres propiedades más, que permiten especificar SelectionColor: el color que tendrá la línea cuando el usuario la seleccione (haciendo clic con el mouse sobre la misma); AllowHovering: la posibilidad de que cambie el color de las líneas cuando el usuario se desplaza con el mouse sobre ellas, y HoveringColor: el color que tendrá una línea cuando el mouse pasa sobre ella. Demo: Cómo procesar registros en el grid Volvamos al Web Panel MainSearch. En el grid de los vuelos, existe una columna con una imagen que nos permite marcar el vuelo como interesante para analizarlo más adelante en detalle y planificar así el viaje. Para implementarlo, deberemos agregar una variable de tipo bitmap, la cual se cargará en el evento Load del control Flights. Agregaremos entonces en el Event Flights.Load : &interesting = Loadbitmap("int_unsel.jpg") Existen varias formas posibles para procesar el registro como se describió anteriormente.En este ejemplo, programaremos el evento Click asociado a la variable: Event &interesting.Click call(“Interesting”, FlightId) &interesting = Loadbitmap("int_sel.jpg") EndEvent // &interesting.Click Vea la demostración aquí Como no implementaremos el procedimiento Interesting, lo hemos dejado entre comillas dobles como invocación a un programa externo. Dicho procedimiento grabaría en una tabla los vuelos que se han seleccionado como interesantes para que luego el usuario pueda consultar los vuelos que le han resultado de interés. Paginado de grids en Web Panels En ambiente web, los datos resultado de una consulta a la base de datos que se devuelven en un grid se trasforman en texto html y ocuparán tantas líneas como resultados. Tanto por temas de usabilidad, de performance o de tamaño de la página HTML generada, puede ser conveniente desplegar los resultados en un grid de tamaño fijo y permitir con botones de movimiento la navegación entre las páginas de los mismos. Nos referimos a esto como paginación del grid. Para esto, se dispone de métodos asociados al control Grid, los que aplican cuando la propiedad ‘Rows’ del grid tiene un valor diferente de cero. Aplica a ambos tipos de grids estándar y free style y también cuando los grids están anidados. Existen algunas diferencias relacionadas con la paginación cuando un grid tiene tabla base o no. Cuando el grid no tiene tabla base, no está disponible el método Last Page ni GotoPage. Métodos A continuación se describen los métodos disponibles: FIRSTPAGE El método FirstPage lleva al usuario al primer conjunto de registros devueltos. Los valores devueltos por este método son los siguientes: 0: Operación exitosa 1: No está habilitado el paginado en el grid Ejemplo Event Enter MyGrid.FirstPage() Endevent En este ejemplo cuando el usuario presiona el botón asociado al evento enter, en el grid se mostrará el primer conjunto de registros. NEXTPAGE El método NextPage lleva al usuario al siguiente conjunto de registros. Los valores devueltos por este método son los siguientes: 0: Operación exitosa 1: No está habilitado el paginado en el grid 2: Ya se encuentra en la última página. Ejemplo Event Following.Click &err = MyGrid.NextPage() if &err = 2 Message.Caption = ‘You already are in the last page’ endif Endevent En este ejemplo cuando el usuario presiona el botón Following, en el grid se mostrará el siguiente conjunto de registros. En el caso que ya esté cargada la última página, se muestra el mensaje ‘You already are in the last page’ en el textblock Message. PREVIOUSPAGE El método PreviousPage lleva al usuario al conjunto anterior de registros. Los valores devueltos por este método son los siguientes: 0: Operación exitosa 1: No está habilitado el paginado en el grid 2: Ya se encuentra en la primera página Ejemplo Event Back.click &err = MyGrid.PreviousPage() if &err = 2 Message.Caption = ‘You already are in the first page’ endif Endevent En este ejemplo cuando el usuario presiona el botón Back, en el grid se mostrará el conjunto de registros anterior y en el caso que ya esté cargada la primer página se muestra el mensaje ‘You already are in the first page’ en el textblock Message. LASTPAGE El método LastPage lleva al usuario al último conjunto de registros. Puede ser utilizado únicamente si el grid tiene tabla base. Los valores devueltos por este método son los siguientes: 0: Operación exitosa 1: No está habilitado el paginado en el grid 3: El grid no tiene tabla base Ejemplo Event Last.click MyGrid.LastPage() Endevent En este ejemplo cuando el usuario presiona el botón Last, en el grid se mostrará el último conjunto de registros. GOTOPAGE El método GotoPage(PageNumber) permite acceder en forma directa a un determinado conjunto de registros. Puede ser utilizado únicamente si el grid tiene tabla base. Los valores devueltos por este método son los siguientes: 0: Operación exitosa 1: No está habilitado el paginado en el grid Ejemplo En este ejemplo, dado el grid (GSearchResults) con el resultado de una búsqueda, y otro grid (GPages) con el número de páginas de la primera para permitir un acceso más rápido de paginado. Event Refresh &PageCounts = GSearchResults.PageCount EndEvent Event GPages.Load if &PageCounts > 1 &Count = 1 Do while &Count <= &PageCounts &PageNumber = &Count SFPages.Load() &Count += 1 enddo endif EndEvent Event &PageNumber.Click GSearchResults.GotoPage(&PageNumber) EndEvent Resumen A continuación se incluye una tabla con un resumen de los métodos disponibles cuando un grid tiene tabla base y cuando no. Grid con tabla base FirstPage NextPage PreviousPage LastPage GoToPage Grid sin tabla base           Propiedades Cada grid dispone de las siguientes propiedades que son utilizadas en la paginación:   RecordCount PageCount Consideraciones  Si el web panel que se está paginando tiene filtros, se debería agregar el método FirstPage dentro del evento que aplica el filtro, a los efectos de evitar que el resultado desplegado corresponda a la página en la que se encontraba anteriormente.  La eficiencia de los métodos FirstPage, NextPage, PreviousPage y GotoPage( N) está asociada a la eficiencia de la definición de la navegación del grid correspondiente. En otras palabras, si el grid, sin paginado tiene buenos tiempos de respuesta, los tiempos con paginado serán semejantes.  El método LastPage determina cuál sería la última página, para lo que utiliza la propiedad Rows y la propiedad RecordCount del grid. El hecho de utilizar la propiedad RecordCount implica que el DBMS (no el código generado) barre dos veces la tabla base del grid (la primera vez para contar y la siguiente para "cargar").  El método LastPage ha sido pensado para que se ejecute un único comando Load por cada registro de la tabla base. Por ello, si existen IFs en el evento Grid.Load que pueden condicionar la ejecución del comando mencionado o se ejecuta más de una vez el método Load por cada registro, los resultados pueden ser inesperados. Implementación El paginado se realiza por "número de registro". Esto quiere decir que, la página 1 tendrá los registros del 1 al valor de la propiedad Rows, la página 2 los que van del Rows +1 al Rows * 2 y así sucesivamente. Para mostrar la página 2, internamente, se "pasa por" los registros de la página 1 sin mostrarlos. En general, para mostrar la página N, se "pasa por" los registros de las páginas anteriores (N-1) sin mostrarlos. Dada la implementación, se recomienda: 1. Tener un buen filtrado de datos (de forma que no existan muchas páginas) 2. 3. Evitar, cuando el costo sea alto, el uso de GotoPage( N) con valores altos de N, así como el uso de LastPage. También se recomienda salvar el valor de la propiedad RecordCount en una variable ya que cada invocación de la propiedad implica un COUNT en la base de datos. Ejemplo Los métodos de paginado de grids pueden ser utilizados en los eventos escritos por el usuario. Por ejemplo: Event Start &Count = MyGrid.RecordCount If &Count > MyGrid.Rows Pagina2.Visible = 1 EndIf If &Count > MyGrid.Rows * 2 Pagina3.Visible = 1 EndIf Endevent Event Siguiente.Click MyGrid.NextPage() Endevent Event Anterior.Click MyGrid.PreviousPage() Endevent Event Enter MyGrid.FirstPage() Endevent Demo: Paginación de grids En el grid de vuelos, se quieren cargar de a 5 vuelos a la vez. Para eso debemos modificar la propiedad Rows del grid y asignarle 5 como valor. Además, para permitir la navegación entre todos los registros (las típicas acciones de ir a la primer página, a la anterior, a la siguiente y a la última), vamos a incluir imágenes en el formulario programando su comportamiento en el evento clic de cada una. Definiremos entonces las variables de tipo Bitmap &first, &previous, &next y &last a las cuales les asociaremos la imagen correspondiente en el evento start y luego en el evento click de cada una de ellas programaremos el método de paginación del grid correspondiente. El código que se ejecutará cuando el usuario haga clic sobre cada una de las imágenes será el siguiente: Event &first.Click Flights.FirstPage() EndEvent // &first.Click Event &previous.Click Flights.PreviousPage() EndEvent // &previous.Click Event &next.Click Flights.NextPage() EndEvent // &next.Click Event &last.Click Flights.LastPage() EndEvent // &last.Click Es decir: Flights.FirstPage(), Flights.LastPage() Además cuando “modifiquemos” los valores de las variables &CountryId y &CityId de la parte fija, vamos a presionar el botón de Buscar (“Search”) queriendo que se carguen los primeros 5 vuelos que cumplen con los nuevos valores de las variables. Para esto, vamos a tener que programar en el evento asociado al botón de Buscar lo siguiente: Event Enter Flights.FirstPage() EndEvent // Enter Vea la demostración aquí Si el evento de Buscar no tiene al evento Enter asociado, esta lógica deberá estar en el evento de usuario definido. Web Panels con más de un grid Cuando un web panel contiene más de un grid en su form, GeneXus no determina una única tabla base asociada al web panel, sino una tabla base asociada a cada grid. Es decir, GeneXus determina para cada grid una navegación independiente. Puede verse una analogía entre un web panel con varios grids y un reporte con for eachs paralelos. A continuación mostramos un ejemplo: Dado que el web panel “View Users & Service Providers” tiene más de un grid en su form, GeneXus no determinará una tabla base asociada al web panel, sino que determinará una tabla base para cada grid. Los atributos que participan en la determinación de la tabla base de cada grid son:   los incluidos en el grid (se tienen en cuenta tanto los atributos visibles como los ocultos) los referenciados en Order y Conditions locales al grid Los atributos de la parte fija del web panel no participan en la determinación de la tabla base de ninguno de los grids, pero deberán pertenecer a la tabla extendida de alguno de ellos (para que sea posible inferir sus valores). De no respetarse esto, al especificar al web panel, se mostrará en el listado de navegación resultante, el warning: “Attribute not instantiated”. Los atributos utilizados en los eventos del web panel tampoco participan en la determinación de la tabla base de ninguno de los grids. Los atributos que se incluyan en los eventos fuera de comandos for each, deberán pertenecer a la tabla extendida de alguno de los grids. En el ejemplo, no hay definidos ni Order ni Conditions para ninguno de los grids, por lo que la tabla base del grid que se encuentra arriba en el form será: USERS y la tabla base del grid que se encuentra abajo en el form será: RATES. Es importante resaltar que GeneXus determina la tabla base de cada grid, pero no busca ni establece relaciones entre las mismas. Al igual que en el web panel recientemente visto, si se define el siguiente web panel: GeneXus determinará la tabla base del primer grid (que será USERS) y la tabla base del segundo grid (que será COUNTRIES), pero no analizará si hay atributos en común entre ellas, y por ende no definirá filtros automáticos. Es decir que los grids tendrán asociadas navegaciones independientes o paralelas. Si bien GeneXus no establece relaciones entre las tablas bases de los grids, el analista podrá definirlo explícitamente. Primero estudiaremos los eventos en web panels con más de un grid, y a continuación veremos cómo definir cargas relacionadas. Eventos en Web Panels con más de un grid En web panels con más de un grid, existe un evento Refresh global y un evento Refresh particular para cada grid. El evento Load, no existe global sino sólo a nivel de cada grid. Los eventos Refresh y Load a nivel de grids, deben referenciar al grid usando la siguiente nomenclatura: Event <Subfile Control Name>.<Refresh | Load> .... EndEvent Por ejemplo, si en el último web panel visto, los nombres de los grid son GridUsers y GridCountries respectivamente, para codificar los eventos Refresh y Load a nivel de los grids, la sintaxis deberá ser: Event GridUsers.Refresh .... EndEvent Event GridUsers.Load .... EndEvent Event GridCountries.Refresh .... EndEvent Event GridCountries.Load .... EndEvent Además de estos eventos a nivel de los grids, estará el evento Refresh global: Event Refresh .... EndEvent Cada vez que se ejecute cualquiera de las acciones que provocan que se ejecute el evento Refresh, se ejecutará: Refresh // (el genérico) GridUsers.Refresh GridUsers.Load GridCountries.Refresh GridCountries.Load De esta manera, cada uno de los grids se cargará con los datos correspondientes. El comando LOAD mantiene la misma sintaxis en web panels con más de un grid. Se debe incluir al mismo para hacer cargas de grids sin tabla base, dentro del evento Load de un grid. Cómo definir cargas relacionadas en Web Panels con más de un grid Dadas las transacciones “Country” y “Cities” definida en una base de conocimiento: Definiremos un web panel que muestre en un grid a todos los países (GridCountries), y cada vez que el usuario seleccione un país, se cargarán sus ciudades en un segundo grid (GridCities). Para asociar cargas, se deben definir grids con variables: De modo que los grids “no tendrán tabla base” y en consecuencia el evento Load de cada grid, se ejecutará una sóla vez. A continuación detallamos el código que definimos para resolver las cargas: Event GirdCountries.Load For each &CountryId=CountryId &CountryName=CountryName Load Endfor Endevent Event GridCities.Load For each where CountryId=&CurrentCountryId &CityId=CityId &CityName = CityName Load endfor Endevent Luego codificamos el evento Enter asociado al botón “View cities”: Event Enter &currentCountryId = &CountryId Endevent Consideraciones  Es posible especificar condiciones de filtro tanto a nivel global como a nivel de cada grid. Para cada grid, se tendrán en cuenta las condiciones globales y las condiciones locales (es decir: condiciones globales “and” condiciones locales).  De necesitarse utilizar al comando For each line en un web panel con más de un grid, se deberá incluir una referencia al grid con la siguiente sintaxis: For each line IN <Grid Control Name> Endfor  No es posible nombrar a un atributo o variable de un grid determinado. Por ejemplo, no es posible referirse a: GridUsers.CountryId GridCountries.CountryId Sí podemos referirnos a CountryId y por ejemplo codificar sus propiedades, eventos y métodos (por ejemplo, definir en algún evento la siguiente sentencia: CountryId.Visible=0). De todos modos no se recomienda tener al mismo atributo / variable en más de un grid, ya que las codificaciones que se le hagan, afectarán a todos los grids en los que se encuentre. Es decir, si el atributo CountryId perteneciera a más de un grid, al ejecutarse la línea de código: CountryId.Visible=0, el atributo CountryId quedaría invisible en todos los grids. Demo: Múltiples grids en un Web Panel Continuemos avanzando con el desarrollo de nuestro objeto MainSearch Lo que nos quedaría por hacer en este Web Panel es desplegar la bandera y el resumen del "Destino del Mes" y un grid con las ciudades del mismo. Recordemos cómo es que dijimos que queríamos que apareciera el formulario en ejecución … Lo primero que debemos hacer para poder mostrar el país del mes es agregar una celda a la derecha de la celda donde filtramos por país/ciudad. La forma más sencilla de hacerlo es clic con el botón derecho, y seleccionar la opción “Split Cell”. Una vez realizado este cambio es necesario modificar el valor de la propiedad “Colspan” de la celda superior a 3, ya que ahora la misma debe abarcar 3 celdas en lugar de 2. Para simplificar el desarrollo suponemos que el país del mes es el de código “URU”, entonces podemos cargar la bandera y el resumen del mismo en el evento Start. Definiremos las variables &MonthlyCountryFlag - de tipo bitmap -y &MonthlyCountryDetails basada en el atributo correspondiente. Por otro lado, vamos a tener que crear un grid con las ciudades del país del mes . Para eso el nombre de la ciudad será la única columna del grid y en las condiciones locales al mismo definiremos el filtro por el país del mes. Podemos definir un grid estándar que tenga como título de la columnas Cities. Para que no se vean en ejecución los bordes donde se carga el resumen del país del Mes, a la variable correspondiente se la debe definir como ReadOnly. Vamos entonces a hacer estos cambios a la aplicación… Haga clic aquí para ver la demostración Como no se asigna un nombre al grid, el control name correspondiente será Grid1. Se sugiere que de todos modos se asigne el nombre Cities al control para facilitar luego la lectura del código y también de la navegación del objeto. Grids anidados Es posible definir grids 'anidados' en un web panel. Los grids anidados consisten en un grid Free Style al que se puede insertar dentro de una celda otro grid. Cada grid puede ser un Free Style o un grid estándar, aunque si es estándar no puede tener ninguno anidado. Puede haber grids anidados de varios niveles y puede haber también paralelos. Puede decirse que se está definiendo un árbol en donde cada nodo es un grid. Los grids comunes solo pueden ser hojas del árbol de anidación. Por ejemplo, se quiere tener un web panel que muestre los poveedores de servicios, pero indentados por categoría: Hoteles Hotel Colonia Hotel Oceanía Transport Alfa Travel OtherWorld Travel ... Para ello se define un grid Free Style con la categoría y dentro de este se inserta otro grid con los poveedores de servicios (podría ser un grid estándar o Free Style). Determinación de tablas bases Los grids anidados cumplen las mismas reglas de relacionamiento que si fueran For Eachs anidados. Por lo tanto, GeneXus determina la tabla base de cada grid (no son por completo independientes: en la determinación de la tabla base del anidado influirá la del principal). Luego, a partir de esas determinaciones, define las navegaciones que realizará para cada grid. La lógica de los grids dependerá de las relaciones que encuentre entre las tablas determinadas. Si no tiene tabla base, se deben cargar los datos con el comando Load. Disparo de Eventos Cada grid mantiene sus eventos load y refresh particulares. Cada vez que se ejecuta el comando Load en un grid con anidaciones, se llama al evento Refresh y load de cada hijo. Demo: Grids Anidados en un Web Panel Continuemos con el desarrollo de nuestro objeto MainSearch Para mostrar las atracciones turísticas del país/ciudad seleccionado, debemos implementar grids anidados. El grid padre tendrá la categoría de las atracciones y en el grid anidado las atracciones en sí. En caso de que no se seleccione un país, se mostrarán las atracciones del país del mes. Además como no se referencia a la ciudad estarán todas las atracciones de las ciudades del mismo. Agregamos entonces un grid Free Style (de nombre Attractions), donde colocamos el atributo TouristAttractionCatDescription, CountryId y una variable bitmap para cargar la imagen correspondiente (almacenada en el atributo TouristAttractionCatImage) y dentro de este grid colocamos otro (también de tipo Free Style y de nombre Attraction) para desplegar la información de la atracción turística. Suponiendo que el país del mes es Uruguay, en el grid Attractions, agregaremos las siguientes conditions: CountryId = &CountryId WHEN .NOT.&countryid.IsEmpty(); CountryId = "URU" WHEN &countryid.IsEmpty(); Como vimos anteriormente el grid puede ser estándar o Free Style, en este caso elegimos un grid Free Style simplemente por el modo en que esta página va a ser diseñada. Haga clic aquí para ver la demostración Grids en transacciones con form HTML El botón que se encuentra en la barra de controles y permite insertar el control grid. Al igual que en los Web Panels, el grid es en ejecución una tabla HTML. Las columnas pueden ser atributos o variables (incluyendo las de tipo bitmap). El comportamiento de los atributos y variables en un grid en una transacción es diferente al descrito en los Web Panels. Como desplegar datos en un grid En ejecución, los atributos que se encuentran en el formulario de una transacción son de ingreso, por lo tanto lo mismo aplica a aquellos que se encuentran dentro de un grid. Si se quiere modificar el comportamiento por defecto, es decir no se desea el ingreso de un atributo, entonces se puede utilizar la regla noaccept(Att) o la propiedad Read Only de la columna. Las variables que se colocan en una transacción son de sólo lectura. Nuevamente en este caso, se despliegan en el grid todos los registros ingresados en la transacción, pero en el caso de transacciones no se puede programar paginación a pedido, por lo que de ser necesario, se aconseja el uso de un Web Panel para el ingreso de información. Como aceptar datos en un grid En el caso de las transacciones, el grid despliega por defecto 5 líneas de ingreso, este valor puede ser modificado por el usuario utilizando las propiedades del mismo (Ver Propiedades del grid). Esto significa, que siempre se despliegan x filas adicionales a los registros ya ingresados en la tabla. Como se menciona anteriormente, los atributos en una transacción son de ingreso, por lo tanto no es necesario realizar ninguna modificación. Para poder ingresar valores en variables, es necesario utilizar la regla accept(&Var) para modificar el comportamiento por defecto. INTRODUCCIÓN En este capítulo veremos los conceptos de Web Component y Embedded Page (página embebida). El primero nos permite la reutilización de lógica entre los objetos y el segundo permite incluir dentro de sitios diseñados con GeneXus páginas de terceros. Incluiremos también en nuestra aplicación práctica un Web Component. Web Components Los Web Components permiten a los diseñadores de aplicaciones GeneXus Web un alto grado de reutilización de los mismos. Son objetos web que tienen una propiedad en la cual se indica que son componentes. Es decir, pueden ser ejecutados en forma independiente (como cualquier otro objeto web) o pueden formar parte de otro objeto web (Web Panel o Web Transaction). Cualquier parte de un objeto web que se repita en varios objetos de una aplicación web, puede ser definida como Web Component. Los ejemplos más comunes son: menús, login, área que permite la personalización, etc. La idea entonces es, en lugar de tener implementado, por ejemplo, la carga del menú en cada uno de los objetos web que requieren el mismo, programarla en un Web Component y reutilizarlo en cada Web Panel que requiere un menú. Cómo definir un Web Component Para definir un objeto web como Web Component se debe configurar la propiedad “Type” (antes Web Component) con el valor “Component”. De esta forma, se habilita la propiedad “URL access”. La cual puede tomar los siguientes valores:   Yes: permite que el objeto sea ejecutado desde la URL. No: no permite que el objeto sea ejecutado desde la URL. Se debe notar que un objeto web definido como Web Component no pierde ninguna de sus características, por lo tanto, puede ser ejecutado en forma autónoma. Los Web Components se generan dentro del mismo HTML del Web Panel que los contiene. Esto significa que el servidor resuelve la inclusión del Web Component en tiempo de ejecución y devuelve al navegador el código HTML con el Web Component ya incluido. Uso de Web Components Para insertar un control Web Component en un Web Panel o Web Transaction se debe elegir la opción Insert / Web Component, o la opción control de tipo ‘Web Component’ en el objeto. de la barra de controles, con lo cual se creará un Además, se pueden insertar Web Components en grids free style. Para determinar el objeto que se va a desplegar en lugar del control Web Component, se utilizan las propiedades del mismo. El objeto web a desplegar se puede fijar en diseño o en tiempo de ejecución, como se describe a continuación. PROPIEDADES MODIFICABLES EN DISEÑO El control Web Component tiene las siguientes propiedades de diseño:   ControlName: Nombre del control. Object: Permite asociar un objeto web al Web Component. Sólo se aceptan objetos con la propiedad “Type” en “Component”. Parameters: Permite especificar la lista de parámetros con los que se invocará el Web Component.  PROPIEDADES MODIFICABLES EN EJECUCIÓN A continuación se detallan las propiedades de los Web Components que se pueden modificar en tiempo de ejecución:  Object: permite determinar en tiempo de ejecución qué Web Panel o Transacción se va a desplegar en el lugar del control. Sintaxis Control.Object = Create(Wxxx, [par1], ... [parn]) Donde: Wxxx Es el Web Panel o Transacción al que se le ha configurado la propiedad “Type” en “Component”. [par1], ... [parn] Son los parámetros recibidos por el mencionado objeto.  Visible: determina si el control Web Component está visible o no. Sintaxis: Control.Visible = Value Valores: 0: False. El control no se muestra en el form. 1: True. El control se muestra en el form. Web Components dinámicos Como lo demuestra la sintaxis, es posible dinamizar los Web Components, es decir que el contenido de un Web Component sea variable. Por ejemplo: &variable = ‘HMenu’ Comp1.Object = Create(&variable) En el momento de hacer el Create (al ejecutar) GeneXus busca qué nombre de objeto (de los que tengan definida la propiedad “Type” en “Component”) es igual al valor de la variable, si lo encuentra, evalúa que coincidan los parámetros (cantidad y tipo), si no encuentra el objeto el espacio del Web Component queda en blanco al ejecutar el Web Panel que lo contiene. Esto implica que si se agrega un componente al modelo y el mismo será llamado de forma dinámica, basta con generar y compilar el componente mismo. Estos objetos se verán además en el object browser como objetos llamados. Observaciones En diseño, el tamaño del Web Component permanece fijo, pero en ejecución, el tamaño quedará sujeto al espacio ocupado por el mismo. La forma de fijar el tamaño del Web Component en ejecución es entonces incluyéndolo en una tabla y fijando el tamaño de la celda. Un Web Component puede a su vez contener otros Web Components. La asignación de un Web Component puede realizarse dentro de cualquier evento del Web Panel ‘padre’. Si se asigna un Web Component en el evento Start del padre, los parámetros se pasarán solamente la primera vez que se crea. En sucesivos POST, los parámetros se recordarán del render anterior. Si se asigna un Web Component en cualquier otro evento (Refresh, Load, de usuario, etc.), los parámetros se pasarán siempre que se ejecute dicho evento. Si se asigna el objeto web en la propiedad Object del control Web Component en diseño, el pasaje de parámetros se realiza en forma análoga a lo descrito en el punto anterior. Los controles y las variables de los Web Components no son accesibles por los objetos que los contienen (objeto web ‘padre’). Si por ejemplo se desea que un campo del Web Component tenga un color determinado por el padre, se le tendrá que pasar por parámetro el color y asignarlo en el evento Start del Web Component. En ejecución, las propiedades del form del Web Component son heredadas del objeto web que lo contiene. Por ejemplo si el form de un Web Component tiene color verde, pero el form del objeto web que lo contiene tiene color blanco, entonces este último predominará sobre el primero. No es así con las propiedades de los demás controles. No se soporta el uso de atributos como primer parámetro de la función Create. Ejecución de objetos web con Web Components A continuación se describe la ejecución de objetos web que contienen Web Components. Web Components en área plana del objeto Web ORDEN DE EJECUCIÓN DE LOS EVENTOS Se pueden diferenciar dos instancias al ejecutar un objeto web que incluye un Web Component: primera llamada al objeto web (GET) y disparo de un evento en el objeto (POST). Primer llamada (GET) El orden de ejecución de los eventos al realizar la primer llamada al mismo (GET) es el siguiente: Evento START del objeto web que contiene el Web Component (objeto web ‘padre’), 1. Evento REFRESH del objeto web ‘padre’, 2. Evento START de todos los Web Components dentro del objeto web que no están dentro de 3. grids, Eventos REFRESH y LOAD de cada uno de los Web Components y de los grids en el orden que 4. aparecen en pantalla (de arriba a abajo y de izquierda a derecha). Ejemplo: En la siguiente figura, se puede observar un Web Panel que contiene 2 Web Components (A y B) y un grid. Cada Web Component tiene a su vez un grid. En este caso el orden de los eventos cuando se ejecuta por primera vez es el siguiente: 1. 2. 3. 4. 5. 6. 7. Evento Evento Evento Evento Evento Evento Evento START del Web Panel REFRESH del Web Panel START del Web Component A START del Web Component B REFRESH del Web Component A y evento LOAD del grid en el Web Component A LOAD del grid del Web Panel REFRESH del Web Component B y evento LOAD del grid en el Web Component B Disparo de un evento (POST) Al disparar un evento, el orden de los eventos depende de si se disparó el evento en el objeto web ‘padre’ o en un Web Component. A continuación se analizan ambos casos. Nota: La lectura de variables de cada objeto se realiza siempre inmediatamente después del evento Start de dicho objeto. Disparo de un evento de un Web Component 1. 2. 3. 4. 5. 6. Evento START del objeto web ‘padre’ Evento START del Web Component cuyo evento se disparó Evento de usuario del Web Component Evento REFRESH del objeto web ‘padre’ Evento START de los Web Components restantes Eventos REFRESH y LOAD cada uno de los Web Components y grids en el orden que aparecen en pantalla. En el ejemplo, si se dispara un evento del Web Component A, el orden de los eventos sería el siguiente: 1. Evento START del Web Panel 2. Lectura de variables del Web Panel 3. Evento START del Web Component A 4. Lectura de variables del Web Component A 5. Evento de usuario del Web Component A 6. Evento REFRESH del Web Panel 7. Evento START del Web Component B 8. Lectura de variables del Web Component B 9. Evento REFRESH del Web Component A y evento LOAD del grid en el Web Component A 10. Evento LOAD del grid del Web Panel 11. Evento REFRESH del Web Component B y evento LOAD del grid en el Web Component B Disparo de un evento en el objeto web ‘padre’: 1. 2. 3. 4. 5. Evento START del objeto web ‘padre’ Evento de usuario del objeto web ‘padre’ Evento REFRESH del objeto web ‘padre’ Eventos START de todos los Web Components en el orden que se encuentran en pantalla Eventos REFRESH y LOAD de los Web Components y grids en el orden que aparecen en pantalla. En el ejemplo, al dispararse un evento del Web Panel, el orden de los eventos sería el siguiente: 1. 2. 3. 4. Evento START del Web Panel Lectura de variables del Web Panel Evento de usuario del Web Panel Evento REFRESH del Web Panel 5. Evento START del Web Component A 6. Lectura de variables del Web Component A 7. Evento START del Web Component B 8. Lectura de variables del Web Component B 9. Evento REFRESH del Web Component A y evento LOAD del grid en el Web Component A 10. Evento LOAD del grid del Web Panel 11. Evento REFRESH del Web Component B y evento LOAD del grid en el Web Component B Nota: si el objeto web tiene más de un grid, primero se ejecuta el Refresh independiente de los grids y luego el refresh de cada uno de los grids en el orden en que aparecen en pantalla. Web Components en grid free style ORDEN DE EJECUCIÓN DE LOS EVENTOS En caso de haber Web Components en grids, se ejecuta el evento Start del Web Component justo antes del evento Refresh en vez de ejecutarse al principio. Todos los eventos del Web Component (Start, Refresh y Load si tiene grids) se ejecutan cada vez que aparece el Web Component. Consideraciones de diseño para la optimización de Web Components A continuación se describen algunos puntos a considerar para el diseño de páginas Web con GeneXus y Web Components para lograr una optimización del código HTML generado: USO DE LA FUNCIÓN CREATE Evitar el uso de la función Create y por lo tanto especificar, siempre que sea posible, el nombre del Objeto Web Component en las propiedades del Control Web Component. Cuando se utiliza la función Create (especificando un objeto o una variable) los generadores tienen que incrementar el código HTML generado para saber cuál fue el nombre del Objeto Web Component que se utilizó. El incremento en el código HTML por utilizar Create es relativamente menor. De todas formas, en páginas con muchos Web Components y/o con Web Components dentro de grids, puede sumar varios KBytes más a la página. EVITAR EL USO DE LA FUNCIÓN CREATE CON UNA VARIABLE En algunos generadores el Create con una variable es transformado, por el especificador, en un DO CASE con Creates "fijos" (con nombre de objeto) basándose en los parámetros especificados. Resulta evidente que el DO CASE puede incluir Creates de Web Components que nunca van a ser llamados (porque no son necesarios en la lógica del programa) y entonces nos encontraríamos en la misma situación del punto anterior. UTILIZAR TEXT BLOCKS EN LUGAR DE VARIABLES SIEMPRE QUE SEA POSIBLE Un Text Block tiene menos funcionalidad que una variable. Sin embargo, en la medida en que la funcionalidad adicional no sea necesaria es recomendable utilizar un Text Block en lugar de una variable ya que el código HTML generado para un Text Block es normalmente menor (en algunos casos la mitad) que el de una variable. Es importante notar que la cantidad de código HTML generado depende del contenido de la variable o del valor de la propiedad Caption de un Text Block. Un ejemplo de esto es la inclusión de código HTML escrito por el usuario en las páginas generadas. Es muy recomendable utilizar Text Blocks en este caso. ELIMINAR ATRIBUTOS/VARIABLES QUE NO ESTÉN SIENDO UTILIZADOS EN LA PANTALLA Genera menos código HTML un atributo/variable que no está en el form que uno que sí está pero tiene la propiedad Visible en cero. Ninguno de los dos se "ve" en la página generada. Demo: Definir un Web Component Lo que vamos a hacer ahora es definir el Web Panel Login que tenemos desarrollado para indicar que el mismo es un Web Component. Para esto, configuraremos la propiedad “Type” en “Component”. Haga clic aquí para ver la demostración Más adelante incluiremos este componente en la Master Page. Embedded Pages Definición El objetivo de las páginas embebidas o ‘Embedded Pages’ es poder incluir información externa; es decir desplegar el contenido de cualquier URL en objetos web generados por GeneXus. Una ‘Embedded Page’ es un control que se puede insertar en un Web Panel o Web Transaction. A este control se le puede asociar cualquier página u objeto web GeneXus, cuyo contenido luego será incluido en ejecución dentro del objeto. El uso de Embedded Pages brinda a los usuarios GeneXus la siguiente posibilidad de incluir información externa: permite que se incluyan páginas estáticas o dinámicas de la propia aplicación o desarrolladas por terceros. Dichas páginas pueden estar en el mismo servidor que la aplicación o en otro servidor. Esta característica brinda gran dinamismo a las aplicaciones web desarrolladas con GeneXus. Generación Las Embedded Pages se generan como un ‘inline frame’ en el HTML final. Al ejecutar el objeto que contiene una Embedded Page, el browser se encarga de realizar el requerimiento de la página asociada y de incluirla dentro del inline frame. Uso de Embedded Pages Para insertar una Embedded Page en un objeto web se debe seleccionar la opción Insert / Embedded Page, con lo cual se creará un control de tipo Embedded Page. También es posible insertarla con un solo clic en el ícono de la barra de controles. Orden de los eventos Como se mencionó anteriormente la Embedded Page es una página totalmente independiente del objeto web que la contiene, por consiguiente, si se utiliza un objeto GeneXus en una Embedded Page, los eventos de éste y del contenedor se dispararán en forma independiente y no es posible establecer a priori cuándo se ejecutan los de uno con relación a los del otro. Requerimientos Para poder visualizar objetos web que contienen Embedded Pages, se requieren browsers que soporten el tag correspondiente al ‘inline frame’ (<IFRAME>). En consecuencia, el browser (en el cliente) debe ser como mínimo Internet Explorer 4.0, Netscape 6.0 o versiones superiores. Propiedades El control Embedded Page tiene las siguientes propiedades:       ControlName: Nombre del control. BorderStyle Scrollbars Source TooltipText Height   Width Align PROPIEDADES MODIFICABLES EN EJECUCIÓN A continuación se detallan las propiedades modificables en tiempo de ejecución:         BorderStyle TooltipText Source Visible Height Width HeightUnit WidthUnit Nota: La propiedad TooltipText no funciona en Internet Explorer 6.0 o menor. Sí funciona en Netscape 6.0 o superior. Observaciones Si en las propiedades del control no se especifica la propiedad Source, entonces en el evento Start o Refresh se debe asignar algún valor a la misma. Por ejemplo: MyPage.Source = “http://www.genexus.com”, siendo MyPage el nombre del control Embedded Page. Se permite la asignación dinámica de URLs. Por ejemplo: &url = “http://www.genexus.com” MyPage.Source = &url Se pueden incluir Embedded Pages dentro de grids free style. Demo: Embedded Page Continuemos con el desarrollo de nuestro objeto MainSearch Vamos ahora a definir una página embebida para mostrar propaganda. Para esto, en el objeto MainSearch agregaremos debajo de la tabla que contiene a los restantes objetos un control Embedded Page. Para lo cual, deberemos ir al menú Insert / Embedded Page. Una vez creado el control en la propiedad “Source” incluiremos la siguiente URL: www.uruguaynatural.com. Vea la demostración aquí INTRODUCCIÓN En este capítulo continuaremos viendo formas de reutilizar lógica en el desarrollo de las aplicaciones Web. La finalidad continúa siendo que la creación y el mantenimiento de páginas Web asegure consistencia con la totalidad del sitio. La Master Page permite centralizar el diseño y el comportamiento en un solo objeto y reutilizarlo en otros objetos sin requerir programación. Definiremos también en nuestra aplicación práctica una Master Page. Definiendo una Master Page Una Master Page es un Web Panel con la propiedad “Type” en “Master Page”. En una misma base de conocimiento se pueden definir tantas Master Pages como se desee. Una vez que exista al menos una Master Page en la base de conocimiento, puede ser referenciada desde cualquier Web Panel o Transacción Web, para ser utilizada por este objeto de modo de ser cargado con ese marco o contexto. De esta forma, el objeto referenciado hereda todo el layout y comportamiento de su Master Page. Para poder cargar cualquier objeto web con el marco especificado por la Master Page, se creó un nuevo control llamado “Content Placeholder”. Este control define en qué lugar, dentro de la Master Page, estará ubicado el contenido de las Transacciones Web y los Web Panels que la utilizarán como su página maestra. Tal como lo ilustra la figura anterior, se define un Web Panel para oficiar de página maestra, es decir, de la página que contendrá el layout y comportamiento genérico del sitio. Esa página tendrá un Web Component para cargar el Header que deseemos darle a todas las páginas del sitio, otro para el menú, y luego tendremos el “hueco” donde querremos que cada página particular del sitio sea cargada. A cada una de esas páginas individuales que conforman en conjunto el contenido del sitio, habrá que configurarles en su propiedad “MasterPage” el nombre de la página maestra que creamos antes, para que cuando sean ejecutadas, lo sean con el “marco” dado por la Master Page. Una Master Page es definida, especificada y generada en forma independiente. Si se desea modificar el layout o comportamiento general del sitio, solo hay que realizar la modificación en la Master Page, sin necesidad de modificar/regenerar los objetos web que la utilicen. Algunos de los beneficios de esta nueva funcionalidad son: • • • • • Menos código (se ahorra mucho código Javascript que generan los Web Components) Facilidad para diseñar forms de objetos web Algunos aspectos de seguridad y auditoría pueden ser implementados en el Web Panel Master Page Mejor performance (menos código HTML) Desarrollo incremental (solo cambiando el Master Web Panel cambia toda la aplicación) ¿Cómo hacer que un objeto web tenga una Master Page asociada? Contamos con la propiedad “Master Page” para objetos web (Transacciones Web o Web Panels). Sus valores posibles son:   (none) Master Pages definidas en la base de conocimiento Y solo puede definirse para: Transacciones Web y Web Panels con la propiedad “Type” en “Web Page” (no Component). Si se definen varios Web Panels como Master Pages, éstos aparecerán para ser seleccionados como “Master Page” de un objeto web, en la propiedad “Master Page” que por defecto asume el valor “(none)”. Solo puede asociarse una Master Page a Transacciones Web o Web Panels que no sean Web Components. Observaciones EVENTOS Cuando se ejecuta un Web Panel que tiene asociada una Master Page, la secuencia de ejecución de los eventos de cada uno será la siguiente: 1. 2. 3. 4. 5. Evento START de la Master Page Evento START del Web Panel Evento REFRESH y LOAD de la Master Page (aquí la Master Page es dibujada hasta que se encuentra el Content Placeholder) Evento REFRESH y LOAD del Web panel … Restricciones Una Master Page es un Web Panel común y corriente (incluso puede tener Web Components) pero necesita cumplir las siguientes condiciones: • • • • Solo puede tener un control “Content Placeholder” No puede tener regla parm (en caso contrario mostrará en tiempo de especificación “spc0092 Master Pages do not support the parm() rule”) No puede ser Main (si se escoge para la propiedad “Type” el valor “Master Page” para un Web Panel, la propiedad Main desaparece) No puede invocarse una Master Page desde otro objeto como si fuera un simple Web Panel (en tiempo de especificación mostrará: “spc0008 Events(6): Call to program MasterWebPanel that cannot be generated”) Si un Web Panel era una Master Page y deja de serlo, los objetos que tuviesen asociada esa Master Page mostrarán un error de especificación (“spc0093 The Master Page property references an object that is not a Master Page). • Demo: Uso de Master Pages Definamos en nuestra aplicación práctica una Master Page para incluir en ella el diseño del sitio. Creemos entonces un nuevo objeto Web Panel MyMPage. La idea sería tener un cabezal en la parte superior, el componente de login a la izquierda y un pie de página para la aplicación. En la parte derecha tendremos las páginas de la aplicación. Por lo tanto definiremos una tabla de 3 x 1 para alinear las secciones. La celda del medio la dividiremos utilizando la opción Split Cell. Para que luego en ejecución se visualice correctamente definiremos en la property “Width” tanto de las celdas (superior e inferior) como de la Tabla en “100%”. Mientras que en la celda que tiene el Componente Login definiremos “20%” y en la celda Zona de datos “80%”. El cabezal y el footer serán dos nuevos objetos definidos como componentes que serán incrustados en esta tabla. Entonces será así: Componente Cabezal Componente Login Zona de datos Componente Pie de página Vea la demostración aquí Ahora, es necesario definir los Web Panels que se invocarán desde este objeto para tener el diseño definido. Para esto siga las instrucciones que se describen en el próximo documento. Práctico: Definición y uso de Web Components Ahora es necesario que defina los componentes que se invocarán desde la Master Page. Para el cabezal, crearemos un Web Panel “Header”. En el mismo incluiremos una Tabla de 1x1, en la propiedad “Backcolor” configuraremos el color “Blue” para la celda de la primera fila. Además, configuramos la propiedad “Width” en “100%”, para que la misma ocupe el ancho completo de la pantalla. Luego, insertaremos el texto “Travel Agency”.Finalmente, configuraremos la propiedad “Type” de este Web Panel en “Component”, de forma tal que luego lo podramos invocar desde la Master Page. Para el pie de página, crearemos un nuevo Web Panel denominado “Footer”.En el mismo agregaremos una Tabla de 2x1. En la celda superior configuraremos la propiedad “BackColor” en el siguiente color: “Peach” y en la celda inferior “Bone”. Agregaremos las variables &Today y &Time respectivamente en esta celda, además en la propiedad “Align” de la misma se debe optar por “Center”. En la propiedad “Width” de la tabla la configuramos en “100%”. Por último, se deberá setear la propiedad “Type” de este Web Panel en “Component”, de forma tal que luego lo podramos invocar desde la Master Page. Luego de tener estos objetos definidos, vuelva a la Master Page para referenciarlos desde los controles correspondientes. Asignemos también al objeto MainSearch que estamos desarrollando esta Master Page. Para esto, en la propiedad “Master Page” configure la Master Page definida anteriormente (MyMPage). Especifique y genere los objetos modificados y ejecute el objeto para verlo en ejecución. Control Content Placeholder Para poder cargar cualquier objecto web con el marco especificado por la Master Page, se creó un nuevo control llamado “Content Placeholder”. Este control define en qué lugar, dentro de la Master Page, estará ubicado el contenido de las Transacciones Web y los Web Panels que la utilizarán como su página maestra. Para insertar un Content Placeholder se debe seleccionar la opción Insert / Content Placeholder, con lo cual se creará un control de tipo Content Placeholder. Propiedades El control Content Placeholder tiene las siguientes propiedades:   Pgmname: nombre del programa. Pgmdesc: descripción del programa. Observaciones Solo puede insertarse un Content Placeholder por Master Page. En caso de intentar insertar un segundo control de este tipo, al grabar dará un error: “Error: Only one Content Placeholder control is allowed”. INTRODUCCIÓN Destacaremos aquí algunas particularidades de las Transacciones Web que están diseñadas en la aplicación para profundizar algunos conceptos. Para destacar el funcionamiento de las mismas, se describirán sus diferencias con respecto al comportamiento de las transacciones en ambiente gráfico, destacando las propiedades y métodos específicos utilizados en ambiente Web, como ser las propiedades Rows y AddLines. Así como también el manejo de Blobs en Web Forms. Form web de Transacciones Cada Transacción contiene un form (pantalla) web mediante el cual se realizarán las altas, bajas y modificaciones en ambiente Web. Para diseñar el form web de una Transacción, se debe abrir la Transacción y seleccionar la opción Object/ Web Form del menú GeneXus. Otra forma, es seleccionando el tab Web Form: Este form es similar al form GUI-Windows, en el sentido que contiene a todos los atributos definidos en la estructura, con sus respectivas descripciones (para cada descripción se creará un text block). Sin embargo, se pueden percibir algunas diferencias: 1) Aparece un control llamado Error Viewer que se utiliza para presentar mensajes. Este control podrá ubicarse en cualquier parte del form y se le podrán asignar propiedades (tipo de letra, color, etc.). que se utiliza para obtener un registro luego de 2) Aparece un botón llamado Get ingresar un valor en el/los atributo/s clave. 3) Algunos botones difieren con respecto a los botones del form GUI-Windows. En particular los botones Close y Help tienen la misma funcionalidad en ambos forms; sin embargo el botón Delete All del form web, no opera de la misma forma que el Delete del form GUIWindows; y existen otras diferencias en lo que a botones se refiere, y su funcionamiento. Las diferencias tienen que ver con la forma de trabajo de las aplicaciones Web (HTML), donde cada vez que el usuario selecciona un botón, hay una comunicación con el servidor Web, una conexión a la base de datos para efectuar una consulta u operación, desconexión de la misma, y presentación del resultado con formato HTML en el browser del usuario. Los botones definidos automáticamente por GeneXus pueden cambiarse por imágenes a las que se les asocian en la propiedad OnClickEvent los eventos estándar de GeneXus (por ejemplo, ‘Next’, ‘Last’, ‘Get’, etc.). Se muestra un ejemplo a continuación: Error Viewer El control Error Viewer es utilizado para desplegar mensajes al usuario, utilizando la función msg(). Para insertarlo, ir por el menú de GeneXus: Insert / Error Viewer. Si el control Error Viewer no se coloca en una posición determinada del form, y se usa la función msg(), el mensaje aparece en la esquina superior izquierda de la pantalla, de lo contrario, aparece donde se colocó el control. Esto significa que los objetos Web tienen un control Error Viewer implícito que es donde se despliega el mensaje al usar la función msg(). Propiedades del Error Viewer en diseño Las propiedades del control Error Viewer en diseño son:   ControlName Class: La propiedad Class solo se encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado. Display Mode ForeColor Font Fill     Propiedades del Error Viewer en ejecución Además de las propiedades detalladas anteriormente, se pueden modificar las siguientes propiedades en tiempo de ejecución:     BackColor Display Mode ForeColor Class Propiedades del control Error Viewer en los Temas Además de las propiedades mencionadas, en la clase Error Viewer de un Tema (o alguna clase derivada de ella), se pueden configurar otras propiedades para el control. Ver Clase ErrorViewer. Tener en cuenta que además de la Clase ErrorViewer, están las clases: ErrorMessages y WarningMessages (que pertenecen a la clase Messages) de un Tema y que aplican a los mensajes (de las reglas “msg()” y/o “error()”) que se despliegan al utilizar Client Server Validation). Demo: Transacción de un nivel Ahora que ya vimos como funcionan las Transacciones Web, podemos definir la Transacción para registrar un nuevo usuario que es invocada en el link que definiremos en el Web Panel MainSearch. Para hacerlo, tenemos que editar la Transacción de Usuarios (Users), seleccionando previamente el modelo de Diseño en la base de conocimiento. Comenzaremos asociando la Master Page definida previamente para que tome el diseño que ya hemos definido. Para esto, debemos asignar a la propiedad “MasterPage” el valor “MyMPage”. La numeración de usuarios se realiza en forma automática, por lo tanto se debe asignar “Yes” a la propiedad “Autonumber” de la Transacción para que la clave primaria de la tabla se autonumere. Como ya existe un registro ingresado, comenzaremos a numerarla a partir del número 2. Para eso, asignar el valor “2” a la propiedad “Autonumber Start”. Haga clic aquí para ver la demostración Se debe evitar que el Nickname incluya menos de 5 caracteres. El algoritmo podría ser más complejo, por lo que en ese caso se debería invocar a un procedimiento que devuelva si hubo o no error. En este caso la regla será: error(‘More characters’) if len(UserNickName)<5; El ingreso de todos los campos (menos el número de teléfono) es “obligatorio”, por lo cual debemos agregar reglas que hagan este control: error(‘Password is required’) if UserPwd.IsEmpty(); error(’E-mail address is required’) if UserEmail.IsEmpty(); error(‘Country is required’) if CountryId.IsEmpty(); error(’City is required’) if CityId.IsEmpty(); msg(‘Please complete your phone number’) if UserPhone.IsEmpty(); Error(‘Please specify a Last Name’) if null(UserLastName); Error(‘Please specify a First Name’) if null(UserName); Error(‘Please specify an E-Mail account’) if null(UserEmail); Error(‘Please specify a User name’) if null(UserFirstName); Error(‘Please confirm the Password’) if null(&PswConf); Para que la variable &PswConf sea de ingreso, se debe agregar la regla: Accept(&PswConf); Finalmente, se debe controlar que la contraseña concuerde con la confirmación ingresada, para eso es necesario agregar: Error(‘Your password entries did not match’) if UserPwd <> &PswConf; En el evento Start, se deberá agregar el código siguiente para que los controles de ingreso de passwords queden enmascarados: Event Start &PswConf.IsPassword = 1 UserPwd.IsPassword = 1 EndEvent Haga clic aquí para ver la demostración Ahora que ya definimos la Transacción Web, podemos modificar el link para registrar un nuevo usuario, en la página principal, de forma de que le pase los parámetros adecuados a la Transacción Users. Recuerde que la página principal del sitio MainSearch tiene asociada la Master Page MyMPage la cual contiene un Web Component ”Login”, al cual le crearemos un link para registrar un nuevo usuario. Veamos la ejecución de nuestra aplicación y registremos un nuevo usuario… Haga clic aquí para ver la ejecución Durante la ejecución pudimos visualizar claramente como es la ejecución de las reglas con Ajax. Pudiendo ver cómo se disparan las reglas, la fórmula (en el caso del campo Full Name) y en cuando y donde se despliegan los mensajes correspondientes a las reglas Error y Msg. Resulta importante tener en cuenta que algunas reglas se disparan tanto en el cliente como en el servidor, por lo que se disparan más de una vez, como se pudo observar en la ejecución anterior. Además, al momento de grabar la password se podría haber utilizado las funciones de encriptación que provee GeneXus. GeneXus provee las siguientes funciones para encriptar datos: GetEncryptionKey, Encrypt64 y Decrypt64. Demo: Transacción de dos niveles A continuación realizaremos las siguientes modificaciones en la Transacción Flights para poder observar los filtros automáticos que presentan los combos. Para lo cual, modificaremos los controles correspondientes a los países y ciuades, de forma tal que cuando el usuario seleccione un país, luego al seleccionar las ciudades únicamente se desplieguen las ciudades de dicho país. Cuando tenemos Transacciones de más de un nivel en GeneXus y necesitamos eliminar registros correspondientes a los subniveles, debemos entonces tener presente en el grid que representa el subnivel (en este caso el grid Prices), la variable de GeneXus &GxRemove. Al momento de ejecutar, el usuario deberá seleccionar el check box correspondiente a la variable &GxRemove y luego presionar el botón Aplay Changes (que tiene asociado el evento Enter). De esta forma se estará eliminando la/s líneas seleccionadas del grid. Haga clic aquí para ver la demostración Haga clic aquí para ver la ejecución Ahora que ya vimos como funcionan las Transacciones Web de dos niveles editaremos la Transacción CountryAttraction para registrar las diferentes atracciones de un país. Para ello el usuario deberá seleccionar un país y una ciudad (de los respectivos dynamic combo boxes, puesto que estos atributos fueron definidos así en la Transacción anterior) y para facilitar al usuario el ingreso de la información en el segundo nivel, aplicaremos las propiedades InputType y Suggest, al momento de ingresar la categoría de la atracción. Haga clic aquí para ver la demostración Es importante tener en cuenta que si se presiona el botón Delete All (), se eliminará el registro de la Transacción. Diálogo de las Transacciones en Web El diálogo de las Transacciones en ambiente Web utiliza la tecnología Ajax para brindar una alternativa al diálogo a pantalla completa (full screen) y proveer más interacción con el usuario. En la medida que el usuario final vaya pasando por los campos de la pantalla y/o ingresando información en ellos, se irán validando los datos, infiriendo los atributos de la tabla extendida, y disparándose las reglas y fórmulas definidas. Todas estas operaciones se ejecutarán en forma interactiva para que el usuario final pueda ir viendo resultados. De todas formas, las características del diálogo a pantalla completa se mantendrán, en el sentido que cuando el usuario final confirme los datos, se grabarán los de la pantalla completa, disparándose antes todas las validaciones, reglas, y fórmulas. Algunas funcionalidades basadas en Ajax son:   Web Client Side Validation Descripciones en vez de códigos o o o Propiedad InputType de atributos Suggest (intellitips) de atributos y variables Combo boxes dinámicos con filtros Web Client Side Validation (WCSV) En las aplicaciones .Net y Java con interfaz Web siempre se trabaja con diálogo de validación a nivel del cliente (Web Client Side Validation). El propósito de esta funcionalidad es incrementar el nivel de interacción de las aplicaciones Web utilizando la arquitectura Ajax, haciéndolas más atractivas sin costo de desarrollo alguno. GeneXus genera código para muchas de las reglas y fórmulas que el desarrollador escribe en las transacciones, que es ejecutado en el browser del usuario final. En este sentido el usuario obtiene un feedback temprano, ya que no es necesario someter un request de la página entera al servidor. Este código es generado en el lenguaje Javascript, por lo que el browser debe tener habilitada la opción de ejecutar Javascript. Algunas reglas, por ejemplo aquellas que requieren acceso a la base de datos, deben acceder al servidor para retornar sus resultados en tiempo real, lo que ahora es posible sin que deba viajar la página HTML entera del servidor Web al cliente para ser desplegada por el browser. Cuando se carga la página solicitada en el browser, el código Javascript también será enviado para:  Disparo de reglas que no dependen de ningún evento de disparo. Esto quiere decir, reglas que dependen del árbol natural de evaluación. Disparo de fórmulas relacionadas, de acuerdo al árbol de evaluación. Realizar chequeos de integridad referencial e inferir los correspondientes datos. Validación del tipo de datos de los atributos.    Por ejemplo, cuando el usuario final ingresa un valor en un campo que es clave foránea, se realizará una invocación en Javascript al motor de Ajax (en el propio cliente) que realizará mediante XmlHttpRequest un pedido al servidor Web de ese dato -y los que deban inferirse a través de él. El servidor devolverá un XML con la información solicitada y en el browser se rearmará la página HTML. Observemos que la información que viaja por la Web es mínima. Todo lo que hace el usuario es ingresar un valor en el campo que es clave foránea, y al abandonarlo para pasar al siguiente campo, verá que aparecen en pantalla los valores inferidos. El usuario no se percatará que entre medio viajó información al servidor y volvió, rearmándose la página entera. Así como ocurría en Win cuando se tenía configurada la propiedad Client Side Validation para que reglas, fórmulas y controles de integridad referencial se ejecutaran en el cliente, éstas no dejan de ejecutarse en el servidor. Por el contrario, son ejecutadas por partida doble: primero en el cliente, y luego, cuando el usuario confirma, vuelven a dispararse en el servidor antes de actualizar la base de datos. La validación de reglas y el cálculo de fórmulas son disparados cuando se pierde el foco sobre el control. La regla de error, al igual que en Win, no permite seguir avanzando entre los campos del form, hasta que la condición que la produce deja de cumplirse. También al igual que en Win, al abandonar un control, se dispara todo lo que involucre a ese control, y a todos los que le sigan consecutivamente y que sean noaccept (o read only). Las validaciones de los tipos de datos (por ejemplo “invalid date format”) se hacen en el browser y para presentar el mensaje de error se utiliza el mismo control que veremos se utiliza para las validaciones de usuario. En ambiente Web las Transacciones implementan un diálogo muy similar al que permiten los generadores .Net y Java para aplicaciones con interfaz Windows cuando la propiedad Client Side Validattion tiene el valor Yes. Diferencias entre CSV Win y Web En ambiente Web las Transacciones implementan un diálogo muy similar al que permiten los generadores .Net y Java para aplicaciones con interfaz Windows cuando la propiedad Client Side Validation tiene el valor Yes. Sin embargo, presentan algunas diferencias:  CSV: Para Web no es configurable, es decir, siempre que se genere una aplicación Java o .Net Web, se generará con validación a nivel del cliente. En cambio, para Win es una propiedad, configurable tanto a nivel de modelo como de objeto. Si bien por defecto una aplicación Windows será con validación a nivel del cliente, puede deshabilitarse. Inferencia de modo: En Web el modo no será inferido automáticamente a partir del valor que el usuario ingrese en los atributos que conformen la clave primaria, al contrario de lo que sucede en Win. Es por ello que en diseño aparece automáticamente el botón “Get”, para permitir recuperar un registro existente y poder trabajar con él. El desarrollador puede eliminarlo si la transacción recibe clave y modo. En Win solo será incluido el botón “Get” si se tiene configurada la propiedad CSV en “No”. Botón de confirmación en ejecución: En Web el botón (con texto por defecto “Apply Changes”) no cambia su texto de acuerdo al modo en el que se esté trabajando. En cambio en Win el botón (con texto en diseño “Confirm”) cambia su texto en ejecución de acuerdo al modo en que se encuentre la transacción (si se está insertando, dirá “Add”, si se está actualizando dirá “Update” y si se invocó a la transacción recibiendo modo delete, el botón mostrará “Delete”). Resultado de la operación sobre la base de datos se informa en: el Error Viewer en la transacción Web, y en la barra de estado que aparece en el extremo inferior izquierdo de la pantalla en la transacción Win. Una quinta diferencia que es importante tener en cuenta tiene que ver con la UTL (Unidad de Trabajo Lógica). No debe perderse de vista que una UTL Web NO contiene las operaciones realizadas dentro de distintos objetos en una cadena de invocaciones. Por cada transacción Web existirá commit en caso de que el desarrollador no lo deshabilite, pero las operaciones de ese objeto deben commitearse ANTES de llamar a otro objeto, pues de no hacerlo, ya habrá terminado la vida de esa UTL al invocar al otro objeto y el Commit de la transacción no operará.     ¿En dónde serán desplegados los mensajes? El lugar dónde se desplegarán los mensajes depende del momento de disparo. Cuando un mensaje (“msg”) o error es disparado en el servidor (como por ejemplo registro duplicado), será desplegado como una lista en el control Error Viewer. Además, en cajas de texto sobre la pantalla, específicamente sobre los campos que el usuario haya ingresado (al momento de perder el foco) y en consecuencia se tengan que presentar mensajes. El Error Viewer continuará desplegando todos los mensajes y errores que no dependen de controles del form que el usuario se ha posicionado. Por ejemplo, las reglas stand-alone. Asimismo, cuando el usuario envía la página al servidor, todas las reglas y fórmulas se volverán a disparar. Todos los mensajes que fueron disparados en el cliente y aún son válidos se redesplegarán también en un Text Box o en el Error Viewer. Las reglas asociadas a eventos de disparo (AfterValidate, AfterInsert, etc.) serán evaluadas por primera vez, lo que generarán mensajes y errores que se desplegarán en el Error Viewer. Es decir, funcionarán de manera combinada el control Error Viewer junto con los mensajes interactivos en cajas de texto. PROPIEDADES DE LAS CAJAS DE TEXTO DE LOS MENSAJES EN LOS TEMAS Estas cajas de texto tienen dos clases asociadas a los Temas. Todas las reglas “error” están asociadas a la Clase ErrorMessages y las reglas “msg” están asociadas la Clase WarningMessages. Ambas clases pertenecen a la Clase Messages, donde se les puede configurar sus propiedades como con las demás clases. La diferencia en este caso es que no hay controles GeneXus asociados a dichas clases. La asociación a las clases ErrorMessages y WarningMessages es automática (para los errores y reglas “msg” respectivamente). Tener en cuenta que además de las mencionadas clases, está la Clase ErrorViewer que aplica a la lista de mensajes del control Error Viewer. En ambiente Web las Transacciones implementan un diálogo muy similar al que permiten los generadores .Net y Java para aplicaciones con interfaz Windows cuando la propiedad Client Side Validation tiene el valor Yes. Modos de las Transacciones en tiempo de ejecución Los programas que se generan correspondientes a las Transacciones –tanto para ambiente Windows como para ambiente Web- permiten dar altas, bajas y modificaciones en forma interactiva a la base de datos a través de los mismos. Al ejecutar un programa correspondiente a una Transacción, se podrán distinguir los siguientes modos, dependiendo de la operación que se realice:   Modo Insert : Indica que se está efectuando una inserción Modo Update : Indica que se está efectuando una actualización   Modo Delete : Indica que se está efectuando una eliminación Modo Display : Indica que se está efectuando una consulta Dependiendo de la plataforma o ambiente de generación, habrán algunas diferencias en lo que se refiere a la operativa de las Transacciones en tiempo de ejecución. No obstante, más allá de la plataforma, cada vez que se realice una operación de inserción, actualización, eliminación, o consulta a la base de datos a través de una Transacción, habrá un modo asociado. Además de esto, las Transacciones tienen un comportamiento diferente según reciban o no el modo instanciado. Transacciones Web sin Modo instanciado Las Transacciones Web pueden invocarse sin recibir el modo instanciado. Se detalla el comportamiento de las mismas dependiendo de la acción: inserción, modificación o eliminación de registros. Modo Insert Al ingresar a una Transacción Web de este tipo, se comienza en modo Insert, y se despliega una pantalla con la siguiente forma: Si se quiere ingresar un registro nuevo, se digitan los datos en la pantalla y se presiona el botón ‘Apply Changes’. Esto provoca, en primera instancia, que se validen los datos ingresados en forma similar a cuando se presiona el botón ‘Check’. En caso de que ya exista el registro va a dar un mensaje de error que se despliega en el Error Viewer. El mensaje es ‘Record already exists’. Además, si no se trabaja con confirmación (propiedad Confirmation del objeto), se insertarán los datos. Si se trabaja con confirmación, se desplegará el mensaje ‘Please confirm the data’. Al presionar nuevamente el botón ‘Apply Changes’, se insertarán los datos. Luego de actualizada la base de datos, se despliega el mensaje ‘Data has been successfuly added’. Modo Update Para entrar en modo Update, se deberá poner un valor en la clave y presionar el botón ‘Get’ ( Esto hace que se carguen los datos del registro. ). Al cargar los datos también se traen las descripciones. Se pueden modificar los datos y presionar el botón ‘Apply Changes’, y se actualizarán los datos con un procedimiento análogo al del modo Insert. Modo Delete Para eliminar un registro primero se debe ingresar en modo ‘Update’ (ingresando la clave y presionando el botón ‘Get’), y luego presionar el botón ‘Delete All’, lo que provoca que se deshabilite dicho botón. En el caso de trabajar con confirmación, se desplegará el mensaje ‘Confirm deletion’. Al presionar el botón ‘Apply Changes’, se eliminarán los datos y se desplegará el mensaje ‘Data has been successfuly deleted’. En el caso de que no se trabaje con confirmación, al presionar el botón ‘Delete All’ se eliminarán directamente los datos y se desplegará el mensaje ‘Data has been successfuly deleted’, sin necesidad de presionar ‘Apply Changes’. Al eliminarse un registro se cargan los datos correspondientes al registro anterior, quedando en modo ‘Actualizar’. Si se borran todos los registros, la Transacción queda en modo ‘Insert’. Observaciones Tener en cuenta que si la variable &mode no es recibida como parámetro puede tomar cualquier valor. Y en el evento Start al menos, el valor es indeterminado. Este es el comportamiento esperado ya que el valor que tiene que tener no está establecido aún. Transacciones Web con Modo instanciado Las Transacciones Web que se invocan instanciando el modo Insert, Update, Delete o Display, deshabilitan los botones de movimiento entre registros y los botones ‘Get’, ‘Select’ y ‘Delete All’. Modo Delete Cuando se invoca una Transacción Web instanciando el modo Delete siempre se despliega el mensaje ‘Confirm deletion’, sin importar si se está trabajando con confirmación o no. Al presionar el botón ‘Apply Changes’, se elimina el registro. Transacciones Web de más de un nivel Cuando se trabaja con Transacciones Web de más de un nivel, se tienen que tener en cuenta los siguientes puntos: Número de niveles de una transacción Las Transacciones Web pueden tener más de un nivel anidado. Asimismo, pueden tener varios niveles en paralelo. Se implementa de la siguiente forma:  El primer nivel debe ser plano  Cada nivel de anidación previo al último debe ser un grid Free Style que contenga al nivel siguiente El último nivel debe ser un grid estándar.  Por más detalles ver Grids en Transacciones Web. Método AddLines Se implementó el método AddLines para el tipo de control grid. El mismo aplica en Transacciones Web. Y permite al usuario ingresar líneas en el grid una por una. El uso es bastante simple, para el caso del ingreso de datos que necesita más líneas de las que hay por defecto se puede agregar un botón con este método. Este método no realiza ni validaciones ni chequeos, sólo agrega las líneas en blanco al final y mantiene los valores que ya estaban ingresados en la Transacción. Sintaxis MyGrid.AddLines(N) Agrega N líneas al grid de la Transacción. Ejemplo El usuario podrá presionar el botón AddLines en Modo Insert para agregar línea a línea en el grid de la Transacción. Event Start if &Mode = 'INS' MyGrid.Rows = 1 else // &Mode = UPD / DLT / DSP MyGrid.Rows = 0 endif EndEvent Event 'AddLines' MyGrid.AddLines(1) EndEvent // 'Addlines' Eliminación de líneas En diseño se utiliza una variable &GxRemove definida y agregada automáticamente a los grids de la pantalla por defecto. Esta variable es un check box que se ubica en la primera columna del grid. Cuando se desea eliminar alguna línea del grid, se debe marcar la misma con el check box, y presionar el botón de ‘Apply Changes’, no el botón de ‘Delete All’. Este último eliminará toda la transacción, no las líneas marcadas. Nota: Es importante considerar nuevamente que cuando se está en una Transacción Web se está modificando todo el “documento” y no se está en un nivel en particular de la misma. Por eso para eliminar líneas se debe utilizar el botón ‘Apply Changes’ porque en realidad se está actualizando el “documento”. Lo mismo para agregar líneas, se debe utilizar el botón ‘Apply Changes’ porque se está actualizando el “documento”. Reglas en Transacciones Web Las reglas, en el objeto Transacción, cumplen un rol muy importante ya que permiten programar su comportamiento (por ejemplo: asignar valores por defecto, definir controles sobre los datos, etc.). Se escriben de forma declarativa, es decir que el orden en el que se escriben no significa que sea el orden de ejecución. Pueden involucrar a los atributos definidos en la estructura de la Transacción , así como a variables, constantes y funciones. Son solo válidas dentro de la Transacción en la que están definidas, es decir, son locales. Todas las reglas de Transacciones pueden involucrar a atributos de la(s) tabla(s) base(s) asociada(s) a la Transacción; y la mayor parte de ellas pueden también involucrar atributos de la(s) tabla(s) extendida(s) de la(s) tabla(s) base(s) asociada(s) a la Transacción. Para poder referenciar a un atributo en una regla, el mismo deberá estar incluido en la estructura de la Transacción. Ya sea que pertenezca a alguna de las tablas bases asociadas a la Transacción, o a sus tablas extendidas. Reglas más utilizadas en Transacciones La siguiente es una lista de las reglas más utilizadas en Transacciones:            Default Error Msg Asignación Serial Subtract Add Allownulls Update Accept Noaccept Recomendamos acceder al Help de GeneXus para consultar sobre otras reglas válidas para Transacciones, o para profundizar sobre estas, de ser necesario. Default Permite asignar un valor por defecto a un atributo o variable; el valor por defecto inicializará al atributo o variable si se está realizando una inserción por medio de la Transacción (modo Insert), pero el usuario final podrá cambiarlo si ese valor no es el que desea. Sintaxis Default( att | &var, exp ); Donde: att: es un atributo perteneciente a alguna de las tablas base asociadas a la Transacción. var: es el nombre de una variable. exp: es una expresión que puede involucrar constantes, funciones, variables u otros atributos. El tipo de datos de la expresión debe coincidir con el tipo de datos del atributo o variable. Funcionalidad: Esta regla asigna el valor de la expresión exp como valor por defecto del atributo att o variable var, cuando la Transacción se ejecuta en modo Insert. Esta regla no es válida para atributos que forman parte de la clave primaria de alguno de los niveles de la Transacción, porque es disparada luego de que la clave es ingresada (ya que solo en ese momento el modo es conocido y esta regla se dispara solo en modo Insert). Error Permite desplegar un mensaje de error si la condición se satisface. Sirve para definir los controles que deben cumplir los datos. Sintaxis Error( ‘msg’ | &var | character expresion, msgId ) if cond [on evento/momento de disparo]; Donde: msg: es un string con un mensaje de error a desplegar. var: es el nombre de una variable de tipo character, que contiene un string con un mensaje de error a desplegar. character expression: es una expresión cuyo tipo resultante es character y que será desplegada. msgId: es un string (sin espacios en blanco ni comillas) que será utilizado solo si la Transacción es definida también como business component1. cond: es una expresión booleana (que puede contener los operadores lógicos and, or, not). evento/momento de disparo: es uno de los eventos predefinidos de GeneXus disponibles para reglas de Transacciones, que permiten definir el momento específico de ejecución de una regla. Funcionalidad: Esta regla despliega el mensaje del parámetro msg, var o character expresion, si la condición cond que se evalúa resulta verdadera. El mensaje de error se despliega en el control Error Viewer y/o un cuadro de texto, deteniendo cualquier actualización a la base de datos. Cuando la Transacción se ejecuta como Business Component, de dispararse el error, generará una entrada en el SDT messages, con identificador msgId. Msg Permite desplegar un mensaje de advertencia si la condición se satisface. Sintaxis Msg( ‘msg’ | &var | character expresion, msgId) if cond [on evento/momento de disparo]; Donde: msg, var, character expresion, msgId, cond, evento/momento de disparo: son los mismos que para la regla error. Observar que la sintaxis es exactamente la misma. Funcionalidad: Esta regla se utiliza para presentar mensajes de advertencia al usuario. Despliega el mensaje del primer parámetro, si la condición se satisface, análogamente a la regla Error; pero a diferencia de esta última, permite continuar con la ejecución si la condición sigue satisfaciéndose. Del mismo modo, si la Transacción es Business Component, de dispararse la regla genera una entrada en el SDT messages. Los mensajes de advertencia se despliegan en el Error Viewer o cuadro de texto en ambiente Web. Noaccept Permite indicar que los atributos no aceptarán valores por parte del usuario (serán solo de salida). Si bien se dispone de las propiedades ‘Visible’ o ‘Enabled’ para que los atributos no acepten valores, se recomienda el uso de la regla Noaccept. Sintaxis Noaccept( att1[, atti]…) [if cond]; Donde: atti: es un atributo perteneciente a alguna de las tablas bases asociadas a la Transacción. cond: es una expresión booleana (puede contener los operadores lógicos and, or, not). Funcionalidad: En una Transacción, todos los atributos que pertenecen a las tablas base asociadas a la Transacción, por defecto son aceptados. Si queremos que algunos atributos con estas características no sean aceptados, entonces contamos con la regla Noaccept. Subtract Sustrae el valor de un atributo al valor de otro atributo, si se satisface la condición especificada. Sintaxis subtract(att1, att2) [if cond]; Donde: att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la Transacción, o a sus tablas extendidas (y deben estar declarados en la estructura) cond: es una expresión booleana (que puede contener los operadores lógicos and, or, not). Funcionalidad: La sustracción se realiza teniendo en cuenta el modo en el que se esté trabajando en la Transacción (Insert, Update o Delete). En modo: - Insert: se le sustrae al valor del atributo att2, el valor del atributo att1 - Delete: se le suma al valor de att2, el valor del atributo att1 - Update: se le sustrae al valor del atributo att2, la diferencia entre el valor nuevo y el viejo de att1 Esta regla tiene la inteligencia para, dependiendo del modo, restar o sumar. Add Suma el valor de un atributo al valor de otro atributo, si se satisface la condición especificada. Sintaxis add( att1, att2) [if cond]; Donde: att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la Transacción, o a sus tablas extendidas (y deben estar declarados en la estructura). cond: es una expresión booleana. Funcionalidad: La adición se realiza teniendo en cuenta el modo en el que se esté trabajando en la Transacción (Insert, Update o Delete). En modo: - Insert: se le suma al valor del atributo att2, el valor del atributo att1 - Delete: se le sustrae al valor de att2, el valor del atributo att1 - Update: se le suma al valor del atributo att2, la diferencia entre el valor nuevo y el viejo de att1 Serial Permite numerar serialmente atributos numéricos. Sintaxis Serial( att1, att2, step); Donde: att1: es un atributo perteneciente a alguna de las tablas base asociadas a la Transacción (es decir, no inferido), que desea autonumerarse (debiendo estar declarado en la estructura). att2: Tiene que pertenecer a una tabla directamente superordinada a la del atributo att1. step: es el paso o incremento de la serialización. Funcionalidad: El propósito de esta regla es asignar un número correlativo a att1 cada vez que se inserta un registro en la tabla a la que pertenece att1. Se toma el valor de att2 (att2 contiene el último número utilizado en la autonumeración), se le suma el valor del parámetro step, y el valor resultante se asigna tanto al atributo att1 del nuevo registro, como al atributo att2 para conservar el último número asignado. Es decir, cuando se está insertando un registro por medio de una Transacción en la cual se ha definido la regla: Serial(att1, att2, step);, se accede al att2 (habrá un solo valor de este atributo relacionado, pues pertenece a una tabla directamente superordinada1), se le suma el valor step, y se asigna el valor obtenido tanto a att1 del registro que va a ser insertado, como a att2 perteneciente a una tabla directamente superordinada con respecto a la tabla que contiene a att1. Accept Permite indicar que las variables aceptarán valores por parte del usuario en un nivel dado de la Transacción. Sintaxis Accept(&var [, att]); Donde: &var: es una variable presente en el form. atti: es un atributo perteneciente a la Transacción. Funcionalidad: Esta regla permite al usuario el ingreso de valores en variables en el nivel de la Transacción indicado por los atributos att. El orden el el cual los datos son ingresados en un cierto nivel depende en el orden en que las variables y atributos estén posicionados en la pantalla. Si no se especifica un atributo en particular, se asume el primer nivel de la Transacción. Update Posibilita actualizar en el form de una Transacción atributos de la tabla extendida (inferidos). Sintaxis Update( att1[, atti …]); Donde: atti: es un atributo perteneciente a la tabla extendida de alguna de las tablas bases asociadas a la Transacción. Funcionalidad: En una Transacción, todos los atributos que pertenecen a las tablas base asociadas a la Transacción, por defecto son aceptados y los que perteneciendo a la tabla extendida, no pertenecen a la base, son inferidos, y por tanto no aceptados. Pero si queremos que algunos de estos atributos inferidos sean aceptados, para que el usuario pueda modificar desde el form su valor, entonces contamos con la regla Update. Consideraciones para el ambiente Web La regla Default_mode no aplica en Transacciones Web. La regla Default (Att,&today) se dispara únicamente la primera vez que se ejecuta la Transacción Web, en su lugar se aconseja utilizar default(Att,today()). Lo mismo ocurre con la variable &time y la función Time() correspondiente. Orden de Ejecución de Reglas y Fórmulas La forma de programar el comportamiento de las Transacciones es definiendo reglas, las cuales se escriben de forma declarativa. A su vez si hay cálculos para efectuar, se puede optar por la alternativa de definir atributos fórmula. El programador GeneXus en ningún momento especifica la secuencia de ejecución de las reglas y fórmulas definidas en una Transacción, sin embargo al momento de generar, GeneXus determina las dependencias existentes entre las reglas y fórmulas definidas. En la mayoría de los casos el orden de ejecución de las reglas definido por GeneXus a partir de nuestras especificaciones es el deseado. Pero en algunos casos podemos querer cambiar el momento de disparo de una regla. GeneXus ofrece eventos o momentos de disparo en las Transacciones, que ocurren antes o después de determinada acción, como la grabación del cabezal, o de una línea. Las reglas de las Transacciones pueden condicionarse de manera tal de dispararse en el preciso instante en que ocurre alguno de esos eventos de disparo. Eventos de disparo:     BeforeValidate AfterValidate BeforeInsert, BeforeUpdate, BeforeDelete AfterInsert, AfterUpdate, AfterDelete    AfterLevel BeforeComplete AfterComplete Al momento de la confirmación de la Transacción, ocurre una serie de acciones que es necesario conocer para poder programar correctamente el comportamiento de las reglas. Para una Transacción de dos niveles, podríamos enumerarlas como sigue:           Validación de los datos del cabezal Grabación física del cabezal (ya sea inserción, modificación o eliminación) Validación de los datos de la primera línea Grabación física de los datos de la primera línea Validación de los datos de la segunda línea Grabación física de los datos de la segunda línea … Validación de los datos de la n-ésima línea Grabación física de los datos de la n-ésima línea Commit La acción de “validación de los datos del cabezal” ocurre cuando se han validado todos y cada uno de los campos ingresados en el cabezal. Observar que en este punto ya se han disparado todas las reglas que correspondían a atributos del cabezal y que no tenían evento de disparo asociado. Inmediatamente después se grabará el registro correspondiente al cabezal. Análogo es el caso de las líneas: “la validación de los datos de una línea” ocurre cuando ya se han validado todos y cada uno de los datos de la línea, y también se han disparado todas las reglas correspondientes según el árbol de evaluación. Inmediatamente después de esta acción de validación, se grabará físicamente el registro correspondiente a la línea. Cada Transacción, al terminar de trabajar con un cabezal y sus líneas, realiza un commit (es automático); será colocado en el código generado por GeneXus, a menos que el analista especifique lo contrario. Los eventos de disparo de reglas permiten definir que se ejecuten antes o después de alguna de las acciones que acabamos de enumerar. Veremos cuándo ocurre cada evento de disparo. Evento de disparo: BeforeValidate Este evento de disparo ocurre un instante de tiempo antes de que la información de la instancia con la que se está trabajando (cabezal o línea x) sea validada (o confirmada). Es decir, ocurrirá un instante de tiempo antes de la acción de “validación del cabezal” o “validación de la línea”, según corresponda. Observar que aquí también se habrán disparado todas las reglas según el árbol de evaluación que no estén condicionadas a evento de disparo alguno. Eventos de disparo: AfterValidate, BeforeInsert, BeforeUdate, BeforeDelete El evento de disparo AfterValidate permite especificar que una regla se ejecute inmediatamente antes de que se grabe físicamente cada instancia del nivel al cual está asociada la regla, en la tabla física correspondiente, y después de que se hayan validado los datos de esa instancia. En otras palabras, si se le agrega el evento de disparo AfterValidate a una regla, la misma se ejecutará para cada instancia del nivel al cual esté asociada, inmediatamente antes de que la instancia se grabe físicamente (ya sea que se inserte, modifique o elimine) como registro en la tabla física asociada al nivel. Existen tres eventos de disparo que ocurren en el mismo momento que el AfterValidate, pero que ya contienen intrínseco el modo. Ellos son: BeforeInsert, BeforeUpdate y BeforeValidate. Observar que aquí es redundante condicionar la regla a “If Insert”. Por tanto, valen las siguientes equivalencias: on BeforeInsert ~ If Insert on AfterValidate on BeforeUpdate ~ If Update on AfterValidate on BeforeDelete ~ If Delete on AfterValidate Si hacemos un esquema de las acciones que rodean al evento de disparo, quedarán claros los dos sinónimos elegidos para este evento (AfterValidate y BeforeInsert para modo insert) VALIDACIÓN DE LOS DATOS AfterValidate – BeforeInsert – BeforeUpdate – BeforeDelete GRABACIÓN DEL REGISTRO (insert, update, delete según corresponda) Eventos de disparo: AfterInsert, AfterUpdate, AfterDelete Así como existe un evento de disparo que permite definir que determinadas reglas se ejecuten inmediatamente antes de que se produzca la grabación física de cada instancia de un nivel (AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete), también existen eventos de disparo para definir que ciertas reglas se ejecuten inmediantamente después de que se inserten, modifiquen o eliminen físicamente instancias de un nivel. Estos eventos son AfterInsert, AfterUpdate y AfterDelete. El evento de disparo AfterInsert permite definir que una regla se ejecute inmediatamente después de que se inserte físicamente cada instancia del nivel al cual está asociada la regla; el AfterUdate luego de que se actualice físicamente la instancia, y el AfterDelete luego de que se elimine. Eventos de disparo: AfterLevel, BeforeComplete El evento de disparo AfterLevel permite definir que una regla se ejecute inmediatamente después de terminar de iterar determinado nivel. Si el atributo que se especifica a continuación del evento de disparo AfterLevel pertenece al segundo nivel de la Transacción, la regla se ejecutará cuando se hayan terminado de iterar todas las líneas del segundo nivel. Y si el atributo que se especifica a continuación del evento de disparo AfterLevel pertenece al primer nivel la regla se ejecutará cuando se haya terminado de iterar por todos los cabezales. Observar que esto se da al final de todo, es decir, una vez que se hayan ingresado todos los cabezales y sus líneas y se cierre la Transacción (en ese momento se habrán iterado todos los cabezales). Por lo tanto, si el atributo especificado pertenece al primer nivel, la regla se disparará una vez sola antes del Evento Exit. El evento de BeforeComplete, se disparará después de abandonar el último nivel. Evento de disparo: AfterComplete Este evento corresponde al instante de tiempo que sucede al commit. Esquema de disparo VALIDACIÓN DE LOS DATOS CABEZAL AfterValidate – BeforeInsert – BeforeUpdate – BeforeDelete GRABACIÓN DEL REGISTRO (insert, update, delete según corresponda) AfterInsert – AfterUpdate – AfterDelete VALIDACIÓN DE LOS DATOS LÍNEA AfterValidate – BeforeInsert – BeforeUpdate – BeforeDelete GRABACIÓN DEL REGISTRO (insert, update, delete según corresponda) AfterInsert – AfterUpdate – AfterDelete ABANDONAR NIVEL 2 AfterLevel - BeforeComplete COMMIT AfterComplete Observaciones Una regla condicionada al evento de disparo AfterLevel Level atributo del 1er. nivel solo se disparará en una Transacción Win (para una Transacción Web no tiene sentido) y lo hará una sola vez, cuando se cierra la Transacción. El evento Start y el evento Exit, c omo mencionaremos luego, en una Transacción Web estos eventos se ejecutarán una vez por cada instancia de Transacción con la que se trabaje. Otro tema importante son las reglas que no tienen evento de disparo asociado, se ejecutarán una vez o dos o tres, dependiendo de lo que se haya configurado en la propiedad del modelo Confirmation. Por ejemplo, si se trabaja en Web y con la propiedad Confirmation=No, valor por defecto, las reglas que no tengan evento de disparo asociado se dispararán: primero en forma interactiva en la medida que el usuario final vaya trabajando en el form, y luego nuevamente cuando el usuario final efectúe la confirmación. Es especialmente importante considerar esto en aquellos casos de reglas que consistan en invocaciones a procedimientos que actualicen la base de datos. Si se tiene una invocación a un procedimiento que actualiza la base de datos, habrá que optar por alguna de las siguientes alternativas para evitar que se dispare más de una vez: • asignarle evento de disparo específico a la regla bien decidir si configurar o no la propiedad confirmation • o estudiar bien la lógica del procedimiento y tener en cuenta la doble o triple ejecución del mismo Por último, si se configurara la propiedad Confirmation= Yes, las reglas sin evento de disparo asociado tendrían un triple disparo. Esto no sucederá con reglas de GeneXus (como subtract, add) que actualizan la base de datos porque GeneXus tiene la inteligencia para realizar el update solo al confirmar (lo mostrado en forma interactiva se calcula en memoria). Eventos en Transacciones Web En las transacciones se permite la programación dirigida por eventos, que es un estilo de programación en el cual existe código que permanece ocioso, hasta que es llamado para responder a eventos, provocados en nuestro caso por el usuario, o por el sistema. Los eventos son acciones que pueden suceder o no. Se escribe código asociado a cada evento posible, y el mismo se disparará sólo si el evento se produce. La programación dentro del evento sigue un estilo procedural. Eventos existentes en Transacciones Los eventos existentes en las Transacciones, son:      Evento Start Evento After Trn Eventos de Usuario Evento Exit En primera instancia explicaremos cada uno de estos eventos conceptualmente y en qué momento exacto se ejecutan, y a lo largo del curso veremos varios ejemplos de utilización de los mismos. Evento Start (de Transacciones Web) El evento Start es un evento del sistema, que ocurre automáticamente. ¿En qué momento se ejecuta? Se ejecutará cada vez que se someta el form de la Transacción, es decir cuando se presione cualquier botón del form (“Get”, “Apply Changes”, botones de navegación, botón Select o cualquier botón con un evento de usuario asociado). En el evento Start fundamentalmente se trabaja con variables. En cuanto a utilizar atributos en este evento, ya sea para evaluarlos y/o usarlos de algún modo menos para actualizarlos, se debe tener en cuenta que los únicos atributos que se tienen disponibles son los que se reciben por parámetro en la regla parm. Ningún otro atributo tendrá valor en este evento, pues todavía no se ha editado ninguna instancia de la Transacción. Evento Alter Trn (de Transacciones Web) El evento After Trn de las Transacciones ocurre inmediatamente después de la ejecución de las reglas con evento de disparo AfterComplete. Por consiguiente, el código que se incluya en este evento, se ejecutará luego de culminada cada iteración completa por medio de la Transacción (es decir, luego de haberse grabado cada cabezal con sus correspondientes líneas como registros físicos en las tablas que corresponda y de haberse efectuado COMMIT). Existen las siguientes alternativas para programar comportamientos que se deseen ejecutar luego de cada iteración completa por medio de una Transacción:  Definir reglas individuales con evento de disparo AfterComplete y dejar el evento After Trn sin código Definir todas las sentencias en el evento After Trn con estilo procedural, y no definir reglas con evento de disparo AfterComplete Definir ambas cosas: alguna(s) regla(s) con evento de disparo AfterComplete y código en el evento After Trn   Como venimos explicando, primero se ejecutan las reglas definidas con evento de disparo AfterComplete, e inmediatamente después de las mismas se ejecuta el código definido en el evento After Trn. Un concepto que es muy importante tener claro, es que tanto en reglas con evento de disparo AfterComplete como en el evento After Trn, se conocen los valores de los atributos del primer nivel de la Transacción. Es decir, si bien ya se grabaron físicamente los registros correspondientes al cabezal y las líneas de cierta iteración completa, e incluso se efectuó COMMIT, aún se tienen disponibles los valores de los atributos del primer nivel, pudiendo estos utilizarse para pasarlos por parámetro en una invocación, o evaluar su valor, o usarlos de algún modo menos para actualizarlos . Un detalle a tener en cuenta es que en el evento After Trn -como en todo evento- es posible incluir comandos, a diferencia de en la sección de reglas de una Transacción, que no se puede. Hay dos motivos por los cuales no es posible actualizar a atributos ni en reglas con evento de disparo AfterComplete ni en el evento After Trn. El primer motivo es que ya se han hecho las grabaciones pertinentes e incluso se ha efectuado COMMIT, de modo que ya es tarde para asignar valores a atributos. Y además, en lo que respecta al evento After Trn, en los eventos no se permite realizar asignaciones a atributos. Eventos de usuario (de Transacciones Web) Además de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por él, los cuales reciben el nombre de eventos de usuario. Cada evento de usuario debe asociarse a un control insertado en el form Web de la Transacción de los que soportan el OnClickEvent (botones, text blocks, imágenes, atributos) y/o a una tecla de función. En tiempo de ejecución, el evento de usuario ocurrirá luego de que el usuario haga clic sobre el control o la tecla de función asociado/a al mismo. Se consigue de dos maneras distintas: 1. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad OnClicEvent. De esta manera GeneXus define la siguiente sintaxis automáticamente: Event ‘Nombre Evento de Usuario’ [key] EndEvent … 2. Dándole un nombre al control y en la sección de Eventos programando: Event nombreControl.click … Endevent Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos programando el evento clic del control. Nota: se pueden ejecutar eventos asociados a botones con Alt+<letra>. Se logra colocando un ‘&’ en el Caption del botón, antes de la letra con la que se desea acceder al evento. Evento Exit (de Transacciones Web) El evento Exit es un evento del sistema (por lo tanto ocurre automáticamente) y es lo último en ejecutarse. ¿En qué momento se ejecuta? Ocurre una única vez, al final de cada iteración (es lo último que se ejecuta). Al igual que en el evento Start, en el evento Exit fundamentalmente se trabaja con variables. En cuanto a utilizar atributos en este evento, ya sea para evaluarlos y/o usarlos de algún modo salvo actualizarlos, se debe tener en cuenta que los únicos atributos que se tienen disponibles son los que se reciben por parámetro en la regla parm. Ningún otro atributo tendrá valor en este evento. Como se dispara cada vez que se dibuja la pantalla, no hace las veces de un verdadero Exit, por lo que no suele utilizarse en este ambiente. Orden de disparo de los eventos Cuando se ejecuta por primera vez una Transacción, el orden de disparo de eventos y reglas es el siguiente: 1. 2. Evento START Reglas que no tienen condiciones de disparo Al presionar el botón ‘Get’, el botón ‘Confirm’ o cualquier botón con un evento de usuario asociado, el disparo de eventos y reglas es el siguiente: 1. Evento START 2. Lectura de los atributos/variables del form 3. Reglas Al confirmar los datos, se ejecuta en orden todo lo siguiente: 4. Evento START 5. Lectura de los atributos/variables del form 6. Reglas y Fórmulas según árbol 7. COMMIT 8. Evento AFTER TRN 9. Evento EXIT Propiedades de Transacciones Web A continuación veremos las propiedades más comunes en una Transacción Web:   Name: En dicha propiedad se especifia el nombre de la Transacción. Description: Permite el ingreso de una breve descripción de la Transacción. También se utiliza como título por defecto del form, por ejemplo. Folder: Permite indicar en qué subcarpeta dentro de la estructura de la carpeta Objects, estará el objeto. Style: Permite indicar cuál es el Style asociado a dicha Transacción. Theme: Permite indicar cuál es el Tema asociado a dicha Transacción. Type: Permite indicar si la Transacción será un WebComponent (Component) o una página Web (Web Page). Master Page: Permite indicar cuál es la MasterPage en la cual está basada la Transacción. Encrypt URL parameters: Permite o denega la encriptación de los parámetros enviados en la URL. Business Commponent: Permite indicar si es Business Commponent o no.         Commit on exit: Controla si se efectúa o no el commit automáticamente. Integridad Transaccional en Transacciones Web Por la forma de trabajo en Internet, las Transacciones Web “viven” solamente el tiempo entre que el usuario de un browser seleccionó el link o presionó un botón y la nueva página es mostrada. Toda modificación a la base de datos que se haga durante la “vida” debe ser confirmada o eliminada antes de que la Transacción Web “muera” y retorne la página resultante. Como consecuencia, una Transacción Web inicia una UTL (Unidad de Trabajo Lógica) al comenzar a ejecutar y la cierra (ya sea por COMMIT o ROLLBACK) antes de terminar. No puede formar parte de otra UTL. Si un programa llama a una Transacción Web, ésta iniciará una nueva UTL. No puede definirse una UTL compuesta por varias Transacciones Web. Una Transacción Web solo puede Commitear los registros insertados por ella misma, o por procedimientos (teniendo la propiedad “Commit on exit” en “No”) en una cadena de invocaciones, pero no puede Commitear los registros insertados por otra Transacción. El objeto que “gobierna” la UTL será la Transacción y puede incluir en ella las acciones realizadas en procedimientos invocados desde ella. Por todo esto, no aplica la propiedad “Commit on Exit” en las Transacciones Web, es decir si se pone “Commit on exit” en “No” nadie comiteará estos datos. Si se necesita que las operaciones de dos o más transacciones (con o sin procedimientos incluidos) conformen una misma UTL, se pueden emular las transacciones con Web Panels y Business Components y utilizar el comando Commit. Dejamos aquí presentado simplemente el tema, para volver a él luego de estudiados los Business Components, donde nos será posible comprender esta solución. Consideraciones Generales Control de concurrencia Las Transacciones Web utilizan el diálogo pseudo-conversacional. Esto implica que, mientras el usuario está realizando modificaciones a los datos o simplemente viéndolos, no existe ningún tipo de locks en la base de datos. El control de cambios (es decir la validación entre la lectura inicial y la confirmación) se realiza a nivel de cada tabla involucrada en la Transacción Web. Los valores leídos al momento de “enviar” los datos son comparados con sus correspondientes, en cada tabla, en el momento de “recibir” las modificaciones (cuando el usuario presiona Confirm). Si los valores no coinciden, se informa al usuario que hubo cambios y que debe intentar nuevamente. Es importante notar que el control de cambios se realiza sobre todos los atributos involucrados salvo aquellos de tipo Long VarChar por su tamaño. Prompts Para cada Transacción Web se genera un Web Panel que será el Prompt por defecto (autoPrompt), y los Prompts correspondientes a las claves foráneas que se tengan. Para modificar el Prompt llamado por defecto, se puede utilizar la regla Prompt. Propiedad del modelo: Generate Prompt Programs En el caso que no se quiera la generación por defecto de los Prompts, se tiene la propiedad a nivel del modelo: Generate Prompt Programs. La cual permite o no la generación de las referencias a los Prompts. Valores: Yes: Crea el Prompt asociado a la Transacción que está siendo especificada así como las referencias en la lógica interna de la Transacción. No: Elimina las referencias a los Prompts asociados a la Transacción. La primera vez que la Transacción se especifique con esta opción, el Prompt no se crea. De otra manera, los Prompts no son eliminados, solamente se eliminan las referencias a ellos. Valor por defecto = Yes Prompts creados por el usuario También es posible definir Web Panels como Prompts tal como se verá a continuación. Uso de Web Panels en reglas Prompt Existen casos en los que un usuario requiere crear un Web Panel que luego quiere utilizar como Prompt para obtener valores de atributos/variables. Para invocar el Web Panel, simplemente se utiliza la regla Prompt en una Transacción Web o dentro de un Web Panel. Al dispararse la regla Prompt (haciendo clic sobre un control) se abre una ventana con el Web Panel y, al seleccionar un valor (nuevamente haciendo clic) se cierra la ventana y el valor se asigna a el/los atributos/variables que corresponda. Programación de un Web Panel como Prompt El Web Panel que será utilizado como Prompt debe cumplir ciertas condiciones:  Debe tener uno o más parámetros de tipo output. Puede tener de in, de inout también pero lo importante es que tenga de output que son los que devolverá. Alguno de los atributos, variables, text blocks o imágenes del form debe tener la propiedad de diseño ReturnOnClic en True. Puede tener habilitada esta propiedad en más de un atributo/variable. En caso de ser una variable, tiene que tener la propiedad Read Only en Trae para que la propiedad esté habilitada. Los valores a retornar (de los parámetros definidos como de output) no se determinan al realizar clic, sino al desplegarse la pantalla por lo que tienen que tener el valor válido a retornar en cada Load (si se muestra un grid, por ejemplo).   Si uno de los atributos, variables, text blocks o imágenes del form que tienen la propiedad de diseño ReturnOnClic en True también tiene programado el evento Clic, el código que esté en dicho evento se ignora. Simplemente al hacer clic se asignan los valores a las variables de tipo OUT y se retorna. Uso avanzado Esta funcionalidad puede no contemplar todos los casos. Por ello, también se implementó la función ReturnOnClic() (sin parámetros) que puede ser asignada a la propiedad Link de cualquier control (que tenga esta propiedad). Ejemplos Prompt de Cities Un Prompt de Cities se programa así: En las Reglas del Web Panel: parm( out: &CityId); En los Eventos: Event Grid1.load &CityId = CityId Endevent En el form: Un grid que tiene CityNom y CityId, donde CityNom (por ejemplo) tiene la propiedad ReturnOnClic en true. Transacciones como Web Components No solo un Web Panel puede ser un Web Component, sino también cualquier Transacción con interfaz Web. La posibilidad de definir una Transacción como Web Component permite tener en un Web Panel varios componentes, algunos conteniendo Transacciones (para altas, bajas y modificaciones de datos) y otros conteniendo Web Panels que despliegan información relacionada, menues, etc.. La definición y el uso de una Transacción como Web Component es como lo vimos en el capítulo Web Components. Observaciones Es posible tener varios Web Components con Transacciones en un mismo Web Panel, pero se deben tener en cuenta los siguientes puntos: El estado de grabación no se mantiene por cada componente. Esto significa que si el usuario ingresa a un componente y realiza una operación (por ejemplo modifica un atributo de la Transacción y oprime el botón “Aplicar Cambios” por primera vez) y no reconfirma la misma, al realizar una operación en otro componente (por ejemplo un GET), se pierden los cambios realizados en el primero (es decir se refresca la página con el valor y estado que tenía antes de modificar el atributo). INTRODUCCIÓN Las aplicaciones Web necesitan un look & feel bastante más sofisticado que las aplicaciones Win y los desarrolladores no tenemos las habilidades y el tiempo para lograr un diseño con esas características. Por esa razón, por lo general se opta por contratar servicios de diseño. Por lo cual, es necesario luego integrar ese diseño con la aplicación GeneXus. Esta integración se logra a través de los “Themes”. Para el diseño gráfico contamos con el “Editor de Themes”, una herramienta de libre distribución que se puede ejecutar en forma independiente de GeneXus. Mientras que en versiones anteriores las propiedades de los controles en los “html forms” (Web Panels y forms html de las Transacciones) debían ser configuradas en los controles, hoy mediante los “Themes” se pueden definir “Clases” para los diferentes tipos de controles y asignarles propiedades a esas clases. Luego, los controles se asocian a esas clases, y éstos heredarán las propiedades allí configuradas. Por lo tanto ya no es necesario establecer los valores de las propiedades para cada control en el form. Las propiedades de los controles se configuran en un único lugar: en las clases del Theme. Cualquier cambio de diseño que se requiera hacer, se realizará en el Theme (sin necesidad de generar/compilar absolutamente nada), de esta forma se logra la uniformidad estética del sitio con un bajo costo de mantenimiento (no es necesario cambiar cada uno de los objetos), y como consecuencia se obtiene una mayor productividad en el desarrollo de aplicaciones Web. Recuerde que en el capítulo 2 se dió una introducción del objeto Theme e incluso se realizaron algunos ejercicios para comprender su funcionamiento. Veremos a lo largo de este capítulo en forma más completa, las diferentes funcionalidades que brinda este objeto. Generalidades de un Theme El editor de temas es una herramienta de libre distribución que se puede ejecutar en forma independiente de GeneXus. Esto es para que la herramienta pueda ser usada por el diseñador gráfico, y el desarrollo de la aplicación se independice e incluso se paralelice con su diseño. Se despliega como una estructura jerárquica de Clases, la siguiente es una imagen del editor de temas: Se puede observar que descendiendo en la estructura jerárquica, se presentan un nodo “Classes” y un nodo “HTMLNodes” (parte izquierda). Al centro, tenemos las propiedades correspondientes a cada una de las Clases, y HTML Nodes; y a la derecha un preview que es una vista de cómo se visualizará en ejecución un control asociado a la clase correspondiente. Clases A partir del nodo “Classes” se despliega un conjunto de clases predefinidas, correspondientes a controles GeneXus (con excepción de la Clase “Messages”, la cual no se corresponde a un control GeneXus, el significado de esta clase se explicará más adelante) Cada clase reúne un conjunto de propiedades configurables por el diseñador, y constituye un “diseño” para un tipo de control GeneXus. Una clase podrá ser asignada a un control en tiempo de diseño, y en tiempo de ejecución a través de la “Propiedad Class”. CLASES PREDEFINIDAS           Attribute Button Error Viewer FreeStyleGrid Grid HyperLink Image Table Textblock Form CLASE “MESSAGES” La clase “Messages” se utiliza para configurar los seteos de los mensajes desplegados en la pantalla a consecuencia de Web Client Side Validation. La misma tiene dos clases: ErrorMessages: todas las reglas error están asociadas a esta clase. WarningMessages: todas las reglas messages están asociadas a esta clase. Para utilizarlas, se configuran de igual forma que las restantes clases. La diferencia está en que no se tiene ningún control GeneXus asociado. La asociación de estas clases es automática. Nota 1: Existen también clases específicas de botones, correspondientes a aquellos que son generados en forma automática por GeneXus en Web Transactions y Web Prompts. Cuando se crean dichos objetos los botones se asocian a las clases correspondientes. Estas clases son descendientes directas de la clase “SpecialButtons” que es hija de la clase “Button”:             BtnCancel BtnCheck BtnDelete BtnEnter BtnFirst BtnGet BtnHelp BtnLast BtnNext BtnPrevious BtnRefresh BtnSelect Nota 2: Las propiedades del form, que se definen en GeneXus se aplican al BODY del HTML. Esto es porque algunas de esas propiedades no son soportadas por el tag FORM (por ejemplo, el background color). Por la misma razón, la clase Form queda en runtime asociada al tag BODY. CLASES ESPECIALES DERIVADAS DE “ATTRIBUTE” Si se define una clase en el editor de temas (llamada X), derivada de la clase “Attribute”, cuatro clases adicionales son creadas:  Blobs:    ReadonlyX (descendiente de X) BlobContentX (descendiente de X) ReadonlyBlobContentX (descendiente e BlobContentX) BlobInputX BlobContentX y BlobInputX son clases asignadas en tiempo de ejecución a los controles blob. Un control blob consiste en el contenido y en lo que se carga en el control. Si la clase X ha sido asociada al blob en diseño, la clase BlobContentX es asignada al contenido, y la clase BlobInputX es asignada al control cargado. Las configuraciones no se pueden hacer en diseño, solamente en tiempo de ejecución. La clase ReadonlyBlobContentX es asignada en tiempo de ejecución a los blobs readonly, que en diseño fueron asociados a la clase X. Si una clase es renombrada, todas sus clases que se crearon antes, serán renombradas también. Por ejemplo, si X es renombrada a Y, se obtendrán las siguientes clases:  Blobs:    ReadonlyY BlobContentY ReadonlyBlobContentY BlobInputY CLASES DERIVADAS Se pueden crear clases derivadas a partir de las clases predefinidas; el proceso de definir una clase significa para el desarrollador asignarle un nombre (hacer botón derecho en la clase padre y clic en “New Class”) y configurar las propiedades que le corresponden a esa clase. Las clases hijas o derivadas quedan implícitamente vinculadas en una relación de herencia con las clases de las cuales derivan. Como consecuencia de esto, las modificaciones en las clases “padre” se verán reflejadas en las “hijas”, con algunas excepciones. Las modificaciones consisten en cambiar los valores de alguna de las propiedades de la clase. La parte inferior del editor muestra el nombre de la propiedad, junto con una descripción de la misma. Además dirá “Inherited: True” o “Inherited: False” según corresponda. Si para una propiedad de una clase dice “Inherited: True”, significa que su valor es un reflejo del valor de la misma propiedad del padre. Es decir, cualquier cambio en la clase padre se traduce en un cambio en la misma propiedad en el hijo. En cambio, "Inherited: False" implica que un cambio en la propiedad en la clase padre no se reflejará en la clase hija. La herencia en el valor de las propiedades se pierde cuando éstas son alteradas en las clases hijas. CLASE POR DEFECTO Es posible definir una clase por defecto. Lo que es más, cuando en GeneXus asociamos un “Theme” a un objeto, una clase por defecto es asociada a cada control definido en el objeto. La clase asignada por defecto, es la clase que fue definida en la “Set as GeneXus Default”. Si la clase por defecto no se indica explícitamente, será la clase predefinida por GeneXus. La clase por defecto es identificada en el editor de temas por un triángulo azul en la esquina derecha del icono de la clase. Propiedades de un Theme Las propiedades de un Theme son las siguientes: FileName: Es el nombre del archivo físico que corresponde al Theme o al Template. Name: Nombre lógico del Theme (o Template). BaseImagePath: Es una propiedad editable únicamente cuando se trabaja con Templates. Si se configura la propiedad Base Image Path del modelo, y al salvar el Theme, si parte del path dado en alguna propiedad de una clase (como ser la propiedad Background) coincide con el indicado en la Base Image Path, la imagen se salva relativa. Esto es porque cuando se trabaja desde dentro de GeneXus el valor de la propiedad coincide con el Base Image Path de la base de conocimiento. La utilidad de esta funcionalidad es la siguiente: si el usuario que está trabajando en la base de conocimiento tiene seteada la propiedad Base Image Path (por ejemplo en el directorio: e:\images), pero el diseñador gráfico (quien usa el editor por fuera de GeneXus) tiene las imágenes en el directorio c:\cliente\imagenes. Si no se setea la propiedad cuando se trabaja con el Template, es decir, se usan caminos absolutos y no relativos, todas las imágenes quedarán apuntando a c:\cliente\imagenes que no existe en la máquina del usuario GeneXus y por lo tanto no se va a visualizar correctamente el Theme cuando se incorpore a la base de conocimiento (además del hecho de que el usuario seguramente tuviera que cambiar ese path porque no será válido en producción). Si el diseñador configura la propiedad (en el ejemplo, con el valor c:\cliente\imagenes), las imágenes quedarán salvadas en forma relativa, luego el usuario GeneXus debe copiar las imágenes a e:\images para poder visualizar correctamente el Theme al incorporarlo a la base de conocimiento, sin necesidad de algún otro procedimiento (como sería ir a cambiar uno por uno las imágenes utilizadas en el Theme para que apunten a la imágen correcta). Notas:  El valor por defecto de la propiedad Base Image Path es el directorio de la base de conocimiento. Se crea automáticamente un folder “CSSDesign” bajo el directorio del modelo (dataXXX). En el directorio CSSDesign se guardan los .css generados para usar en GeneXus, con paths absolutos; en el directorio Web se generan los css con paths relativos. Por lo tanto, no es correcto distribuir los .css que se encuentran bajo el directorio CSSDesign.  Panel de propiedades del Editor de Temas En este panel es posible configurar las propiedades de la clase seleccionada, o del HTML Tag seleccionado. Junto con estas propiedades, se incluyen todas las propiedades disponibles en GeneXus, bajo la categoría: “GeneXus Attribute Control Propierties”,como se visualiza en la figura: Nota: Además, el alcance de las propiedades disponibles dentro del Editor de Temas puede ser ampliado. El usuario podrá definir nuevas propiedades si lo necesita (en el caso de que no existan en el Editor). Las propiedades en el Editor de Temas están clasificadas de la siguiente manera:        Background Properties Box Classification Extensions GeneXus Attributes Control Properties Mouse and Keyboard Text Esa es la clasificación estándar de las propiedades de los CSS (Cascading Style Sheets), con la excepción del grupo “GeneXus Attributes Control Properties”, cuyo propósito es centralizar las propiedades que pueden ser editadas en GeneXus, para el control correspondiente a la clase. Clase Form El control Form, se modifica según la clase Form. Las propiedades bajo el grupo “GeneXus Form Properties” son las que pueden ser editadas en las properties del control Form en diseño, más algunas propiedades que complementan la funcionalidad de aquellas y se encuentran en el estándar de CSS, que son las siguientes:         Background BorderColor BorderStyle BorderWidth Font TextColor Height Width Las siguientes propiedades aún no es posible configurarlas en el Theme:    TooltipText WordWrap Caption Los colores de los links, se configuran agregando Tags HTML. Clase Button Dentro de las propiedades del grupo “GeneXus Button Control Properties”, se tienen las siguientes propiedades:          BackColor Background BorderColor BorderStyle BorderWidth Font ForeColor Height Width Clase Attribute Dentro de las propiedades del grupo “GeneXus Attribute Control Properties”, se tienen las siguientes propiedades, que si bien pertenecen a ese grupo, no se encuentran dentro de GeneXus para los atributos/variables:          BackColor Background BorderColor BorderStyle BorderWidth Font ForeColor Height ImeMode  Width Las propiedades tienen su definición correspondiente al pie del Editor de Temas. Clase Image La clase Image se puede asignar tanto a controles imagen, como a variables de tipo bitmap. Las propiedades del grupo “GeneXus Image Control Properties”, para imágenes son las siguientes:         BackColor BorderColor BorderStyle BorderWidth Font ForeColor Height Width En particular, el valor de la propiedad Margin del Editor de Themes, se suma al valor de las propiedades Hspace y Vspace de GeneXus (caso de imágenes). En la documentación del CSS se muestran que se maneja el siguiente concepto: Margin Border Padding Content Las propiedades hspace y vspace son similares a border, por eso se "suman" cuando se define un margin. Clase Table Las propiedades del grupo “GeneXus Table Control Properties”, para tablas son las siguientes:          BackColor Background BorderColor BorderStyle BorderWidth Height Width LinesColor LinesFont Clase Grid La propiedad que se encuentra en el grupo “GeneXus Grid Control Properties”, y no está en diseño en GeneXus, es:  BorderStyle Propiedades que están en diseño en GeneXus, y no están disponibles en el Editor de Themes:   BackColorStyle : Debe ser asignada en diseño. CellPadding, CellSpacing: A nivel del Editor de Themes, no existe la propiedad Cellpadding y Cellspacing, esto es porque no las soporta el CSS. Existe la propiedad Padding, que se compone de BottomPadding, LeftPadding, RigthPadding, TopPadding. En Internet Explorer a la propiedad Padding, se la interpreta como cellPadding cuando se le pone cellPadding en 0 en diseño, y se ignora si cellPadding es diferente de 0. Clase FreeStyleGrid Aplican las mismas observaciones que para la clase Grid. Clase TextBlock Las propiedades del grupo “GeneXus TextBlock Control Properties”, que no se encuentran disponibles en diseño en GeneXus para textblocks son las siguientes:        BackColor Background BorderColor BorderStyle BorderWidth Height Width Clase ErrorViewer Las propiedades del grupo “GeneXus Errorviewer Control Properties”, que no se encuentran disponibles en diseño en GeneXus para el control ErrorViewer son las siguientes:       Background BorderColor BorderStyle BorderWidth Height Width La propiedad BorderStyle, en el Tema, tiene una gama de valores más amplia que en el caso de la misma propiedad en GeneXus. Los valores que la propiedad acepta en el Tema son los que admite la tecnología CSS y son los siguientes:          None Dotted Dashed Solid Double Groove Ridge Inset Outset Preview del Editor de Temas En la barra vertical derecha del editor, hay una ventana “Preview” mediante la cual se puede mostrar o no, una vista previa de cómo se visualizaría un control asociado a dicha clase. La misma se puede ubicar en los diferentes lugares de la pantalla (arriba, abajo, izquierda, derecha). La vista previa del editor se puede personalizar, agregándole “Custom Views”, que son archivos .HTML. Para eso, agregar una nueva vista a través del menú contextual del nodo Custom Views, o presionando la tecla INS sobre el mismo. Para eliminar una vista personalizada basta con presionar DEL/SUPR. La vista consiste de varios tabs (HTML browser, HTML Source y CSS). Se puede modificar el source y ver los cambios reflejados en el HTML, pero no se salvan dichos cambios en el documento que esté activo. La siguiente figura muestra un ejemplo en el cual se agregó una vista previa llamada “Transacción”. Si se tienen diferentes clases form definidas (es decir, distintas clases hijas de la clase predefinida form), el preview para el resto de los controles se ve con un aspecto de fondo correspondiente a la configuración de aquella clase form que sea la default. HTML Tags Los HTML Tags complementan la funcionalidad de los Temas, en cuanto a que permiten definir las características de un Tag HTML, en un determinado contexto. Es decir, siempre que se quiera establecer la configuración de un determinado Tag dentro de un contexto, se puede hacer mediante el Editor de Temas. Por ejemplo, definir las propiedades de los links dentro de una tabla. La configuración de los Tags HTML, dada en el editor, se ve reflejada en la página Web si esos Tags están en el HTML de la página, en el mismo contexto con el cual fueron definidos en el editor. El contexto está determinado por la jerarquía con la cuál se definen los Tags. Para el ejemplo que mencionábamos anteriormente, de definir las propiedades de los links dentro de una tabla, se haría como se muestra en la figura: Se define un Tag A hijo de un Tag TD. Es decir, siempre que un tag A se encuentre anidado a un tag TD en el HTML generado, se tomará el forecolor definido en el ejemplo. Otro caso de ejemplo sería definir un tag body y la propiedad “ForeColor” del mismo, con lo cual el texto libre de la página tomará ese color. Demo: Temas Cuando se hace una aplicación Web es necesario que el sitio se vea “uniforme”. Esto implícitamente requiere de un alto costo de mantenimiento, ya que si por ejemplo hay que cambiar el color de un grid de azul a celeste, probablemente habría que hacerlo en todas las páginas del sitio para mantener la uniformidad del mismo. Antes, había que ir por cada uno de los controles de cada objeto. Hoy el cambio se realiza en un solo lado: el Tema. Todos los objetos basados en el Tema van a reflejar el cambio automáticamente. Cuando se salva un Tema con el Editor de Temas ejecutado desde dentro de GeneXus, se obtiene un archivo con extensión .CSS (Cascading Style Sheet) en el directorio Web del modelo. En tiempo de ejecución, ese archivo .CSS (que contiene la definición de las clases) es referenciado en el Header de las páginas generadas, y se transfiere al pc del cliente para almacenarse en su caché. Por lo cual, siempre que realicemos un cambio en el Tema asociado a un objeto, basta con llevar el archivo .CSS a producción, para que el usuario final perciba los cambios estéticos realizados (no es necesario generar ni compilar!!). Veamos un ejemplo con la aplicación del curso. Observe que los objetos de la base de conocimiento del curso están asociados al Tema “Default” (a través de la propiedad “Theme” del objeto), y los controles de cada uno de los objetos están asociados a la clase default correspondiente (propiedad “Class” de los controles). Realizaremos algunos cambios a las clases de Tema “Default” y veremos cómo se reflejan los cambios en ejecución. Note que en nuestro caso, el directorio de producción coincide con el directorio Web del modelo, por lo cuál no es necesario copiar el .CSS a ningún lado. Haga clic aquí para ver la demostración Crear un nuevo Tema Se puede crear un Tema de dos maneras: 1. 2. Desde el Editor de Temas Desde el menú de GeneXus Para crear un nuevo Theme desde dentro de GeneXus, se debe ir a la opción Object / New Object / Theme Un nuevo Theme consiste de los siguientes elementos:   Un nombre (nombre del nodo raíz) Un conjunto de elementos predefinidos, correspondientes a las clases, dentro del folder “Classes”. Un folder “HTMLNodes”  Como ejercicio, crearemos un nuevo Tema de nombre “Agency”. En ese Tema vamos a definir una clase “BtnLogin” para la cual definiremos algunas propiedades. En particular, vamos a asignarle una imagen a la propiedad “Background” de la clase. Observe que la propiedad “Base Image Path” del Tema coincide con la misma propiedad del modelo de diseño. Entonces, dado que vamos a usar una imagen que se encuentra bajo el “Base Image Path”, el path de la propiedad Background del Tema quedará relativo. Al Tema “Agency” lo vamos a asociar al Web Panel Login. Debemos cambiar la clase del botón “Login” para que sea “BtnLogin”. Haga clic aquí para ver la demostración Observe que en este caso sí es necesario generar/compilar antes de ejecutar, ya que cambiamos una property del objeto y una property del control. Herencia de las propiedades de una clase En el caso de que una propiedad de una clase esté marcada como “Inherited:False”, es posible revertir la situación. Haciendo clic con el botón derecho sobre la propiedad correspondiente, aparece un menú “Inherit Value”. Seleccionando dicha opción, la propiedad pasará a heredar el valor de la misma propiedad del padre. La derivación de clases, y en particular la "herencia" le brinda al usuario facilidades en la tarea de mantenimiento de las Clases y claridad en el diseño. Por ejemplo si se define una clase “Bullet” derivada de Texblock, con el fin de definir las propiedades de los textos en listas con viñetas. Supongamos que ahora se quiere tener otra clase para los textos anidados a aquellos que están asociados a la clase “Bullet”, y se desea que tengan las mismas características que la clase “Bullet” a excepción de la indentación. Llamemos a esa clase “SubBullet” y creémosla como hija de “Bullet”. Esta clase solo difiere con su padre en la propiedad “TextIndent”. Por lo cual, esa es la única propiedad que no hereda, y la única propiedad que habiéndose modificado en el padre no se refleja en la clase “SubBullet”. Demo: Herencia de Temas Como ejemplo del concepto de herencia en los Temas, edite el Tema “default” de la base de conocimiento, y modifique la propiedad “BackColor” de la clase Button. Observe que para todas las clases hijas de “Special Buttons”, que es a su vez hija de “Button”, la propiedad “Backcolor” está indicada como inherited:True, por lo cual, las clases hijas heredan esa propiedad del padre. Vea en la Transaction Web Users como todos los botones cambian el “Backcolor”, siendo que cada uno de ellos está asociado a una clase diferente derivada de “Button”. Haga clic aquí para ver la demostración Haga clic aquí para ver cómo se pierde la herencia de las propiedades, al ser modificadas en la clase hija. Uso del Editor de Temas El editor se puede ejecutar desde GeneXus y como un programa independiente. Dentro de la base de conocimiento es posible salvar los Themes como archivos con extensión .CSS (objeto Theme de la base de conocimiento). Asimismo, dentro y fuera de GeneXus, el editor permite trabajar con archivos con extensión XML. Esta última funcionalidad (trabajar con archivos XML) permite la integración entre el editor como aplicación independiente y como tool de GeneXus. Nomenclatura: Llamaremos “Template” a los archivos XML que tienen el formato de Themes, pero no son objetos GeneXus Theme. Cuando el editor es ejecutado en forma independiente de GeneXus, siempre se trabaja con Templates. Entonces, un usuario podrá diseñar un sitio utilizando el editor de temas independientemente de GeneXus; el producto de su trabajo serán archivos .XML que otro usuario (posiblemente quien desarrolle la aplicación) podrá integrar a la base de conocimiento, y salvar como objetos GeneXus Theme (archivos .CSS). Por otro lado, también se podrá desde la base de conocimiento salvar un Theme con extensión .XML de manera de poder editarlo y modificarlo por fuera de GeneXus. Con esto se logra independizar el trabajo de diseño de las páginas, del desarrollo de la aplicación. Dado un diseño en formato XML (un Template creado con el editor por fuera de GeneXus), se puede incorporarlo a la base de conocimiento rápidamente siguiendo los siguientes pasos:   Abrir el Template usando el editor desde dentro de GeneXus (opción File / Open Template) Salvar el Template como un Theme (opción File / Save As) Opciones del Editor para el manejo de Themes y Templates OPCIÓN SAVE AS Cuando el Editor es ejecutado desde dentro de GeneXus, mediante la opción del menú : File / Save As se puede:     Salvar un Template como un objeto GeneXus Theme Salvar un Template como otro Template Salvar un Theme como otro Theme Salvar un Theme como un Template Si se tiene el check “GeneXus” habilitado, se salva como un objeto Theme. De lo contrario (si el checkbox está deshabilitado), se habilita la opción File Name, para ingresar el nombre que se le dará al archivo XML generado. Si el Editor se ejecuta por fuera de GeneXus la única opción del File / Save As es guardar un Template como otro Template. OPTIONS / CUSTOMIZE / TEMPLATES En el Menú Options / Customize del editor de temas se presenta el siguiente diálogo: Mediante este diálogo se incorporan archivos XML al Editor, y se determina uno de ellos como “Default Template”. El default Template se usa para:   Inicializar el Theme que se crea automáticamente cada vez que se crea una nueva base de conocimiento. Para inicializar un Theme si se crea desde el menú de GeneXus (Object / New Theme). Los templates “Custom” se graban en el registry de la máquina, y por lo general solo va a ser necesario incorporar aquellos que se sepa que se van a usar habitualmente como base para crear Themes. FILE / NEW THEME Es posible crear un objeto GeneXus Theme desde dentro del editor de temas, cuando éste es ejecutado dentro de GeneXus. Mediante el siguiente diálogo (menú File / New del editor) se puede crear un nuevo Theme en base a alguno de los Templates (incorporados mediante el diálogo “Options / Customize / Templates”.) Por defecto el nuevo objeto se basará en el Template default. Mediante el combo box “Based On” se puede seleccionar un Template con el cual se inicializará el nuevo Theme creado (los Templates de esta lista son los incorporados mediante el diálogo “Options/Customize/Templates”) Notas:  Se puede optar por crear un XML o un objeto Theme GeneXus. Si el check “GeneXus” está seleccionado, se creará un objeto Theme, de lo contrario, se crea un Template. GeneXus distribuye nueve templates (archivos con extensión .XML) que podrán ser usados opcionalmente como default. Estos quedan en el folder “THEMES” de la instalación de GeneXus.  Los Templates que son incluidos con la versión son los siguientes:          Beach.xml Classic.xml Executive.xml Extreme.xml Fancy.xml Fantastic.xml Light.xml PinkPanther.xml Safari.xml Los cuatro primeros son “serios” y siguen las recomendaciones de "buen uso" del diseño en Internet, el resto son divertidos y radicales. OPTIONS / CUSTOMIZE / EDITORS Mediante el menú del editor Options/Customize/Editors es posible seleccionar el tipo de diálogo para los colores. Esta configuración se guarda por usuario. Las opciones son:   Default Designer Si se usa el diálogo "Designer", y se definen “Custom Colors” (botón “Add to Custom Colors”), estos valores son almacenados con el Theme. De esta forma si se define un conjunto de colores básicos para el Theme, estarán disponibles cada vez que se quiera editar. Por ejemplo: si se crea un Theme Gold (toda una combinación de amarillos y naranjas), en los custom colors quedan los colores definidos como custom. El editor como aplicación independiente Usando el editor desde fuera de GeneXus, se pueden salvar los Themes en archivos con extensión XML. Se puede llamar al editor desde fuera de GeneXus, haciendo doble clic en el GXThemeEditor.exe o desde línea de comandos pasándole como parámetro opcionalmente un archivo con extensión .XML. De forma de distinguir cuando se edita un Template de cuando se edita un Theme, la interfaz del editor cambia en el siguiente aspecto:  El color de fondo del Treeview es gris y no blanco como en el caso de cuando se edita un Theme GeneXus. Creación de un objeto Theme por defecto cuando se efectúa la creación de una base de conocimiento en GeneXus Cuando se crea una nueva base de conocimiento en GeneXus, se crea un objeto Theme por defecto. Para la inicialización de este objeto se utiliza el Theme definido como Default en el editor (“Default Template” como se vio anteriormente). Interacción diseñador – desarrollador de la aplicación Web Debido a las exigencias de un buen diseño estético del sitio, por lo general es necesario contratar el servicio de un diseñador gráfico. De ahí es que surge la necesidad de una buena interacción entre el diseñador y quien programa la aplicación, e incluso el hecho de paralelizar ambas tareas. Veremos en un ejemplo práctico, como a través del Editor de Temas, se logra independizar el diseño de las páginas, del desarrollo de la funcionalidad de la aplicación. El diseñador gráfico (sin tener GeneXus instalado en su máquina), se instalará el Editor de Temas a través de un setup de nombre GXThemeEditor.exe . Al ejecutar el setup, aparece la siguiente ventana: Los únicos requerimientos para instalar el Editor de Temas en un pc son: • .NET Framework 1.1 Redistributable Package • Internet Explorer 6.0 SP 1 o superior Vamos a crear un Template ejecutando el editor en forma independiente a GeneXus, y luego integraremos ese Template a la base de conocimiento del curso, para crear un Tema y asociarlo al modelo de la aplicación que estamos desarrollando. Lo primero, es ejecutar el GXThemeEditor.exe. Una opción es ejecutarlo desde la instalación de GeneXus, la otra posibilidad es instalarlo en un directorio aparte corriendo el setup del editor de temas. Una vez abierto el editor de temas como aplicación independiente a GeneXus, “diseñaremos” un Template y lo salvaremos en algún directorio (es un archivo con extensión XML). Haga clic aquí para ver como creamos el Template por fuera de GeneXus. Una vez salvado el Template en algún directorio, vamos a ejecutar esta vez el Editor de Temas desde adentro de la aplicación GeneXus (mediante la opción “Tools / Theme Editor”). Para editar el Template anteriormente creado, ir al menú del Editor de Temas “File / Open Template” y seleccionar el Template del directorio donde lo hemos guardado (con extensión XML). Para salvarlo como un Theme de la base de conocimiento, ir al menú “File / Save As”, y estando seleccionada la opción GeneXus del diálogo, salvarlo con el nombre “Agency”. Una vez que es un Theme de la base de conocimiento, lo podemos asociar a la propiedad “Theme” del modelo. Haga clic aquí para ver como integramos el Template anteriormente creado, al modelo del curso. INTRODUCCIÓN Los reportes definen procesos no interactivos de extracción –consulta– de datos. Son listados que pueden emitirse por impresora, visualizarse por pantalla, o grabarse en un archivo. Decimos que son procesos no interactivos, porque primero se extraen los datos y luego se muestran, no habiendo interacción con el usuario durante el proceso de extracción. El proceso es solo de extracción: no pueden actualizarse los datos leídos. En el presente capítulo estudiaremos las particularidades de este tipo de objetos en ambientes Web. Propiedades del objeto Report en Web Una solución para la generación de reportes en Web es trabajar con reportes PDF. Con este tipo de reporte, se cuenta con mayor potencialidad para el desarrollo de aplicaciones Web. El reporte generado como PDF puede visualizarse directamente desde el browser, así como también grabarlo en el disco del servidor para luego procesarlo. En este capítulo profundizaremos en la generación de reportes PDF. Invocación del reporte El reporte se podrá llamar desde el objeto Web tanto con el comando o función LINK como con el comando CALL. También es posible abrir el Acrobat Reader e ingresar directamente la URL. Configuración de propiedades Para generar reportes PDF se deben configurar las siguientes propiedades:    Main Program = “True” Call Protocol = “HTTP” Report Output = “Only to file” y la siguiente regla:  output_file( ‘xx.pdf’, ‘PDF’) Requerimientos del cliente El cliente que vaya a ejecutar el reporte ya sea que lo va a visualizar en el browser o que lo va a ejecutar luego de salvarlo a un archivo, tiene que tener instalado el Acrobat Reader. Observaciones En este tipo de reportes se debe tener en cuenta que no se pueden utilizar la regla o función msg, así como la regla ask. Al definir que un objeto es main (en este caso un Reporte, pero podría ser una Transacción, Web Panel, etc.), GeneXus genera un programa ejecutable con la lógica del objeto mismo y la de todos los objetos invocados directa o indirectamente por él. El programa ejecutable generado se podrá compilar y ejecutar de forma independiente, es decir, al seleccionar Build / Run se verá como programa independiente del Developer Menu y podrá compilarse y ejecutarse. La definición de un objeto como main se realiza editando las propiedades del objeto, y configurando la propiedad “Main program” del mismo con valor “True”. Demo: Reportes PDF Lo siguiente que haremos es crear un reporte en formato PDF que pueda ser visualizado desde el browser, y referenciado con un link desde el Web Panel Flights, de manera de poder imprimir todos los datos con respecto al vuelo. El nombre del objeto será Flight. Lo primero es crear un objeto reporte con el siguiente layout: (Puede diseñar el layout del reporte como Usted lo crea más conveniente) Lo que haremos es navegar por la tabla FLIGHTS para el número de vuelo recibido por parámetro y luego navegaremos por la tabla PRICES de dicho vuelo. Es necesario configurar las siguientes propiedades al objeto reporte recién creado:    Main Call Protocol = HTTP Report OutPut = “Only to File” Y la siguiente rule: output_file('Flight.pdf','PDF'); Haga clic aquí para ver la demostración Seguidamente, pongamos en el Web Panel Flights un link a este reporte. Para eso, agregar un textblock en el form del Web Panel, de nombre “PrintFlight”, y en el evento Start agregar: PrintFlight.Caption = 'Print Flight’ PrintFlight.Link = link(RFlight ) Haga clic aquí para ver la ejecución del reporte Se necesita el Adobe Acrobat Reader en el cliente, para visualizar el reporte PDF. INTRODUCCIÓN Una pregunta muy importante a la hora de desarrollar una aplicación para Internet, es la siguiente: ¿Es segura nuestra aplicación en Internet? Como la seguridad es un concepto muy amplio, la respuesta a esta pregunta no es sencilla. Sin embargo, dependiendo del tipo de aplicación que se está desarrollando, este punto puede ser crucial. Se puede decir que al publicar una aplicación en Internet, se tienen 3 niveles distintos de seguridad:    Seguridad a nivel del Servidor Web Seguridad a nivel de la base de datos Seguridad a nivel de la aplicación A lo largo de este capítulo se va a desarrollar cada uno de los puntos mencionados anteriormente. Seguridad a nivel del servidor Web Cuando se habla de la seguridad a nivel del servidor Web, se están enfrentando básicamente los siguientes riesgos:  Intercepción de información enviada a través de la red desde el browser al servidor o viceversa Errores o problemas de configuración del servidor Web, que permitan a usuarios no autorizados: o o Acceder a información confidencial que se encuentra en el servidor Ejecutar comandos que afecten el comportamiento del servidor y les permita ingresar al sistema  Intercepción de información El protocolo TCP/IP no fue diseñado para ofrecer servicios de comunicación seguros. En consecuencia, la información enviada desde el browser al servidor Web o viceversa puede ser interceptada por alguien. Es por esta razón que se debe agregar tecnología adicional para resolver problemas de seguridad. Desde siempre, existe una única tecnología que provee los principios para resolver estos problemas: CRIPTOGRAFIA. Existen servidores Web, que pueden trabajar como servidores seguros. Un servidor seguro es un servidor Web, al cual se le habilitó la posibilidad de encriptar los datos que se envían al browser, así como desencriptar la información recibida del mismo. El standard más conocido de autenticación y encriptación de datos para el Web es el SSL. Este standard fue propuesto por Netscape Communications Corporation y es el que soportan la mayoría de los browsers (Internet Explorer, Netscape). Para habilitar la encriptación de datos se necesita obtener un certificado de una autoridad certificadora (por Ej.: Verisign, El Correo (en Uruguay)), este certificado es instalado en el servidor Web, quedando habilitada la encriptación de datos. Finalmente, para activar la encriptación de los datos a transferir, todo lo que el usuario debe hacer es realizar la solicitud del recurso a través del protocolo HTTPS: en lugar de HTTP. La seguridad ofrecida por el servidor Web, depende en parte también del largo del certificado soportado. Cuanto más largo sea el mismo más segura es la comunicación de los datos. Hay que destacar que los servidores seguros protegen “únicamente” la información confidencial de ser interceptada por terceros, pero sin seguridad a nivel del sistema el servidor Web sigue siendo vulnerable a ataques. La property “Protocol Specification” aplica a la generación automática de links entre Web Panels, y el objetivo es identificar el protocolo por defecto a usar cuando se construyen los links (HTTP, HTTPS). Acceso de usuarios no autorizados La mayor parte de los riesgos que se presentan al tener un servidor Web público son asumidos por el administrador del sitio. Desde el momento que se instala un servidor Web en un sitio, se abre para la comunidad Internet una “ventana” a la red de área local. La mayor parte de los usuarios únicamente visitan el sitio, otros, sin embargo intentarán entrar por la “ventana” abierta. Los resultados pueden ser variados, desde el simple descubrimiento que la página principal del sitio Web fue cambiada, hasta el robo de la base de datos que contiene la información de sus clientes. Es entonces importante que el administrador del sistema defina políticas de seguridad, así como tome las medidas necesarias para evitar el acceso de usuarios no deseados. Estas medidas pueden ser a nivel del sistema operativo (restringir las operaciones que se pueden realizar, limitar los permisos sobre documentos y directorios, deshabilitar servicios no utilizados, etc.), como a nivel del servidor (aislamiento de la red, instalación de firewall). Existe abundante documentación sobre el tema, que es recomendable leer, para saber que pasos debería seguir al publicar documentos, o aplicaciones en su sitio Web. Bibliografía Verisign: http://www.verisign.com/products/site/faq/40-bit.html#6 El correo: http://www.correo.com.uy/CorreoCert/sitio_seguro.htm Microsoft: Internet Information Services (IIS) 6.0 security overview http://www.microsoft.com/resources/documentation/WindowsServ/2003/enterprise/proddocs/enus/Default.asp?url=/resources/documentation/WindowsServ/2003/enterprise/proddocs/enus/iis_security.asp Hardening Systems and Servers: Checklists and Guides http://www.microsoft.com/technet/security/topics/hardsys/default.mspx#XSLTfullModule1221211 20120 Apache Web Server: Securing Apache: Step-by-Step http://www.securityfocus.com/infocus/1694 Seguridad a nivel de la Base de datos La seguridad a nivel de la base de datos es también un punto sensible a la hora de publicar una aplicación en Internet. Es de fundamental importancia evitar que usuarios no autorizados puedan acceder a los datos corporativos, así como que un usuario autorizado realice operaciones que le deberían estar negadas. Desde el punto de vista de la configuración del modelo de GeneXus, no se deben realizar configuraciones específicas para mejorar la seguridad de la base de datos. Seguridad a nivel de la aplicación A nivel de la aplicación, la seguridad depende del tipo de aplicación que se esté desarrollando. La implementación de controles de seguridad, es importante en aplicaciones en las cuales los usuarios acceden a información confidencial, como por ejemplo sus datos personales. La razón por la cual son necesarios dichos controles, es que los parámetros que se pasan entre objetos Web (y entre páginas dinámicas en general) viajan visibles al usuario, como por ejemplo: http://www.artech.com.uy/cgibin/hmyapp.exe?1,’NOMBRE’. Por lo tanto, por más que se disponga de una página de login, donde se valida el usuario y su contraseña para ingresar al sistema, el usuario eventualmente podría saltearse la misma, ingresando en el navegador la URL de la siguiente página con un código de usuario válido. Para evitar que se burle el control de acceso y permitir que se acceda a información confidencial, es que se debe agregar algún tipo de control adicional de seguridad. A continuación, se van a discutir diferentes posibilidades que se encuentran disponibles. Manejo de sesiones Una de las posibles alternativas para solucionar el problema de seguridad mencionado anteriormente, es el uso de sesiones. El uso de sesiones se compone de una Transacción “Security” que almacena el usuario logueado, un número randómico de sesión y la fecha y hora del comienzo de la misma. Mediante este número de sesión se controla que un usuario no pueda acceder a los datos de otro usuario. Cada vez que el usuario ingresa a una página del sistema, se chequea el número de usuario y el número de sesión. Si estos no se corresponden con los datos almacenados en la tabla SECURITY, se muestra una pantalla indicando el error y se vuelve al usuario a la página donde se pide login y password nuevamente. Este número de sesión es válido por un tiempo determinado que se configura en el procedimiento. Si el usuario está logueado por más de dicha cantidad de tiempo, se muestra la misma pantalla de error. A continuación se presenta un ejemplo del funcionamiento de las sesiones. La página principal de la aplicación es Login, donde se controla la validez del usuario y su contraseña. La primera vez que un usuario ingresa al sitio debe registrarse al mismo, creando un nuevo usuario (navegando a través del link “Click here to complete a brief registration form”, el cual lo lleva a la Transacción “Users”). De esa forma se da de alta el usuario, y se crea un registro en la tabla SECURITY con el identificador del usuario, el número randómico de sesión, la fecha y hora de la registración. Luego se llama a la página donde se muestra la información a la cual únicamente los usuarios registrados pueden acceder, en este caso, ingresar al Web Panel “MainSearch” para hacer consultas sobre los vuelos. En el evento Start del Web Panel “MainSearch”, se llama al procedimiento “Checksesion”. Este procedimiento verifica que el número de sesión del usuario recibido se corresponda con el que se encuentra almacenado, así como su validez. Si alguna de las condiciones anteriores no se cumple, se llama a una página de error, donde se explica al usuario la causa del mismo. Hay que darse cuenta que en ese caso nunca llegaría a visualizarse la página “MainSearch”. El otro caso que queda por analizar, es cuando el usuario ya está registrado. En este caso en el evento que valida el usuario se realiza una llamada al procedimiento “GenSesNum” que actualiza en la tabla SECURITY el número de sesión asignado al usuario, así como la fecha y hora de generación del mismo. Igualmente que en el caso anterior, en el Web Panel “MainSearch” se invoca al procedimiento “CheckSession” para validar la sesión. Funciones de cookies El objetivo es proveer funciones que permitan leer y grabar cookies desde objetos Web generados por GeneXus. ¿Qué son las cookies? Las cookies son archivos pequeños que se graban desde un Web site en las máquinas de los clientes. Los programas CGI o cualquier aplicación que corre en un servidor, puede leer o grabar las cookies en el cliente. El uso más común de las cookies es la identificación de usuarios. Cuando un usuario se registra en un Web site (Portal o E-Store), el sitio graba una cookie en la máquina del cliente con la identificación del cliente. De este modo la próxima vez que el cliente visite este sitio, intenta leer la cookie y si la misma existe usa el valor de la cookie para identificar el usuario y recuperar sus preferencias desde una base de datos. También existen otros usos de las cookies, como rotación de contenido (especialmente avisos), mantener estado de una aplicación, etc. Incluso se pueden usar como método de almacenar el “carrito de compras” de modo que la información del mismo quede en la máquina cliente y se mantiene entre conexiones. Como se menciona anteriormente, generalmente se usa una cookie para identificar el usuario (en algunos casos, una para la sesión, en otros para el usuario), aunque se podrían poner todos los valores de las preferencias en cookies. Lo ideal es tener una clave que viaje y con esta clave leer la información del usuario. De este modo la información del usuario no viaja hacia el cliente, ni está en la URL. (Ej. tarjetas de crédito, nombre, dirección) simplemente permanece en el servidor. Hay que tener en cuenta que existe un límite en cuanto a la cantidad de cookies que el cliente puede aceptar. El máximo son 300 cookies en total por cliente (para todos los servidores juntos por cada browser/cliente) y 20 cookies por servidor o dominio lo cual quiere decir que si una aplicación graba más de 20 cookies las últimas van a borrar los valores de las primeras. Además existe un límite de tamaño de 4K por cookie, si una cookie supera ese límite es truncada. El usuario puede preferir no grabar la cookie permanentemente (por Ej. si está accediendo desde una máquina pública como podría ser un cybercafe) o incluso puede deshabilitar el uso de cookies, por lo cual esta no debe ser la única manera de identificar al usuario, sino que se debe poder usar un método alternativo en caso de que el browser no soporte o no tenga habilitado el manejo de cookies. Otra particularidad es que el lugar donde se almacenan las cookies (al menos en Windows) depende del browser, por lo que si un usuario tiene más de un browser, cada uno tendrá un conjunto independiente de cookies. El ciclo de vida de una cookie es como sigue: 1. El usuario se conecta a un servidor que por alguna razón quiere grabar una cookie. 2. En la respuesta (HTML Headers), se indica el nombre y valor de la cookie a grabar, así como otros valores (el más relevante es la fecha de expiración). 3. El browser recibe la respuesta y, si el valor de la fecha de expiración es en el futuro, la graba; en caso contrario busca una con ese nombre y la borra. 4. Cada vez que el usuario se conecte a una URL de este dominio el browser enviará al servidor las cookies que se hayan grabado desde el dominio y no hayan expirado. 5. Una vez pasada la fecha de expiración, las cookies se borran. Para obtener más información técnica sobre cookies y su uso : http://www.cookiecentral.com Descripción Se dispone de las siguientes funciones, las que pueden ser utilizadas en cualquier objeto GeneXus, el resultado tiene sentido únicamente si dicho objeto fue llamado en forma directa o indirecta por un objeto Web o está ejecutando en un ambiente Web. GETCOOKIE Permite leer una cookie, devolviendo un string con el valor. Si no encuentra la cookie (o no la puede leer por estar deshabilitada) devuelve el string vacío. Sintaxis &var_char = GetCookie(NombreCookie) NombreCookie: carácter &var_char: carácter SETCOOKIE Permite grabar una cookie. Devuelve 0 (cero) si el resultado es correcto, otro valor si hubo algún error. Sintaxis &var_num = SetCookie(NombreCookie, Valor, [path], [exp-date], [domain-name], [secure]) Los parámetros entre paréntesis rectos son opcionales. Si alguno de los parámetros va nulo se asume el default. &var_num: variable numérica NombreCookie: Carácter. Indica el nombre de la cookie. Valor: Carácter. Valor a almacenar. Path: Carácter. Camino que indica para qué Web Panels la cookie es válida. Si no se especifica, la cookie es válida para los Web Panels que están en el mismo directorio que el que la grabó, o en directorios subordinados. Si se indica “/” la cookie será válida para todo el dominio. Exp-date: Date/Datetime. Indica la fecha de expiración de la cookie. Si no se especifica, la misma expirará cuando se cierre la sesión en el browser. Domain-name: Carácter. Dominio donde es válida la cookie. Por defecto es el dominio desde donde se creó. Secure:Numérico. Si está en 1 la cookie se trasmite solamente si la conexión es segura (HTTPS). Si está en 0 se trasmite siempre. Nota: Si se activa el trace para el generador C/SQL, y se pone TraceLevel=4 o mayor se verá en el trace todas las cookies que llegan al programa. Se imprimen una por cada línea precedidos por la palabra cookie. Observaciones Las funciones mencionadas anteriormente siempre devuelven 0. La única forma de detectar si una cookie fue almacenada es leerla. En consecuencia no se puede obtener la configuración del browser. Ejemplos Algunos ejemplos sencillos sobre cómo grabar una cookie son: &Op= SetCookie(“ID_USER”, Str(UsrId), “/”, CTOD(“01/01/2002”) ) Aquí se está grabando una cookie -válida para todo el dominio- de nombre ID_USER con el valor correspondiente al atributo UsrId y que expirará el 1° de Enero de 2002. &OK= SetCookie(“SESSION_ID_GX”, &StrSession, “”, Nullvalue(&Fecha) ) Aquí se está grabando una cookie -válida para los Web Panels de la misma aplicación -de nombre SESSION_ID_GX- con el valor correspondiente a la variable &Strsession. La cookie expirará al cerrar la sesión del browser. &Op= SetCookie(“USR_PAIS”, “UY”, “/”, ADDYR(&Today, 1), “otrodom.artech.com.uy”, 1) Aquí se está grabando una cookie -válida para todo el dominio ‘otrodom’- de nombre USER_PAIS con el valor UY y que expirará exactamente dentro de un año. Tipo de Datos WebSession WebSession es un tipo de datos de GeneXus que permite almacenar datos en una sesión de usuario del servidor Web. De esta manera se pueden tener variables globales, accesibles mientras la sesión esté activa. Los mismos aplican a los siguientes objetos: Transacciones, Web Panels, Procedimientos; para el lenguaje Java. Descripción Los servidores Web permiten manejar el concepto de sesión. Una sesión se identifica por una clave única, que se mantiene mientras el usuario continúe en el sitio Web. El objeto WebSession permite almacenar información que será visible desde cualquier objeto Web dentro de la sesión activa como si fueran variables globales al sitio. Para utilizar el objeto WebSession, se debe definir una variable de este mismo tipo y aplicarles los métodos y propiedades adecuados. Propiedades Id Esta propiedad retorna un String que es el identificador de la sesión. Ejemplo: &Iden = &Session.Id Métodos Set(key, value) Permite hacer una entrada en la sesión activa. Key y value deben ser del tipo String. Ejemplo: &Session.set(“user”, &User) Get(key) Retorna un String correspondiente a la entrada key de la sesiones. En caso de que la clave no exista retorna el String nulo. Ejemplo: &User = &session.get(“user”) Remove(key) Permite remover un valor de una sesión. Ejemplo: &Session.remove(“user”) Destroy() Detruye el contenido de la sesión. Es recomendable utilizarlo cuando el usuario hace un “logout”, si es que existe este concepto en la misma. Ejemplo: &Session.destroy() Consideraciones Generales El ID de la sesión se guarda en una cookie en el cliente, aunque esto es transparente para el programador. La validez de la Websession es similar a la validez de las cookies que solo valen por la sesión. Esto quiere decir que si se abre una instancia nueva del browser, se pierde la sesión, pero si se abre en una ventana nueva se mantiene. Los datos y el ID de una sesión son diferentes para cada generador. Esto implica que no puedo hacer un link de un Web Panel .NET a un Web Panel Java y mantener los valores de la sesión Si no se ejecuta el “destroy()”, el servidor Web destruye la sesión cuando ha pasado un determinado tiempo desde la última vez que se utilizó. Esto depende del servidor Web/plataforma, y se configura de forma nativa en cada una. La forma en que se almacena la información de la sesión también depende de la plataforma, y condiciona la capacidad de tener la aplicación en más de un servidor Web. Básicamente, si la sesión se almacena de forma local al servidor Web, solo es visible en ese servidor Web, por lo que si el siguiente request del cliente va a parar a otro servidor Web, no va a tener disponible los valores de sesión. Encriptación de Parámetros Los objetos Web generados con GeneXus, permiten visualizar los parámetros que se pasan entre los objetos en la barra de dirección del browser. Esto hace que, si se pasa información reservada como parámetro entre objetos Web (Número de cliente, por ejemplo), las aplicaciones no sean muy confiables en cuanto a la seguridad, porque un usuario podría simplemente cambiar el valor de dicho parámetro en la URL y disponer de información sobre la que no debería tener acceso. No sucede lo mismo si se utilizan cookies, en este caso no hay problemas de seguridad. Es por eso que se hace necesario pasar los parámetros sin que el usuario de la aplicación los conozca o sea encriptar los parámetros. En GeneXus se implementa la encriptación de los parámetros de los objetos Web que van en la URL en forma automática y transparente para el usuario. Esto aplica a los siguientes objetos Web: Web Panels, Transacciones Web. Descripción Para poder realizar la encriptación de parámetros en objetos Web se implementaron funciones estándar que contienen las funciones básicas de encriptación y algunas funciones adicionales (las que requieren manejo de parámetros y cookies). Con respecto al diseño de los objetos la encriptación de parámetros no implica ningún cambio, se programan de la misma forma que hasta el momento. Las ventajas del uso de la encriptación de parámetros son:   Que los usuarios finales no sepan el o los datos que van en los parámetros Que los usuarios finales no puedan modificar el o los datos que van en los parámetros Se agrega la propiedad “Encrypt URL Parameters” a nivel de modelo, en el grupo “Web Information” y también a nivel de objeto. Para la propiedad a nivel de modelo los valores posibles son: No: Indica que No se van a encriptar los parámetros que van en la URL de los objetos Web, siendo éste el valor por defecto. Session Key: Indica que se van a encriptar los parámetros que van en la URL, utilizando una clave diferente para cada sesión. La encriptación se realiza a través del uso de cookies locales.Este valor ofrece un nivel de seguridad mayor, pero no permite compartir URLs. Esto significa que no es posible para un usuario X enviar una URL que tenga parámetros a otro usuario Y, ya que en este caso la URL no va a funcionar porque se necesita la cookie correspondiente para la desencriptación. Site Key: Se encriptan los parámetros que van en la URL de los objetos Web, pero la clave de encriptación va a ser la misma para todo el sitio. En este caso no se utilizan cookies. Esto da un nivel de seguridad menor pero facilita el traspaso de links. La propiedad a nivel de objeto, además de los valores mencionados tiene el valor “Use model’s property value”. Este valor indica que se va a tomar el valor de la propiedad del modelo para realizar la encriptación de ese objeto. Este es el valor por defecto. Consideraciones Generales SESIONES DEL BROWSER Una sesión del browser queda determinada por una instancia del mismo. Por ejemplo, si en un máquina se ejecuta el browser de Internet y a partir de ese browser se abre otra sesión (a partir de la opción de menú File/New/Window o a partir de un link), ambas sesiones pertenecen a la misma instancia del browser. En cambio, si se abre una sesión del browser, y luego se ejecuta nuevamente el exe del browser para abrir una nueva ventana, las dos ventanas no pertencen a la misma instancia. Con esto, si se ejecutan objetos Web, y se configuró la propiedad del modelo (o la propiedad a nivel de objeto) con el valor “Session Key”, la cookie que se defina para guardar este valor va a funcionar en las sesiones del browser que compartan la misma instancia. PREFERENCIA A NIVEL DE MODELO VS. PROPIEDAD A NIVEL DE OBJETO Los valores “Session Key” y “Site Key” a nivel de la propiedad del modelo, determinan que todos los llamados entre objetos Web se harán con parámetros encriptados. Para tener únicamente las llamadas entre algunos objetos con parámetros encriptados se debe indicar el valor “No” en la propiedad a nivel de modelo y el valor “Session Key” o “Site Key” en el objeto Web que lo requiera. Si se tienen valores configurados para la propiedad a nivel de modelo y la propiedad a nivel de objeto para encriptar parámetros, ésta última tiene prioridad sobre la primera. Cuando se utiliza la propiedad a nivel de objeto para encriptar parámetros, y se realizan varios llamados entre objetos Web, se debe tener en cuenta que los valores utilizados por todos lo objetos involucrados debe ser el mismo. Por ejemplo: Si se tiene un Web Panel que llama a otro pasándole parámetros, y se quieren visualizar estos parámetros encriptados, en ambos Web Panels se debe configurar el mismo valor para la propiedad “Encrypt URL Parameters”. Lo mismo sucede si el árbol de llamadas involucra a más objetos Web, todos (los llamados y los llamadores) deben tener configurada la propiedad “Encrypt URL Parameters” y todos deben tener el mismo valor en dicha propiedad. PROPIEDAD “ENCRYPT URL PARAMETERS” EN PROMPTS Los parámetros de los prompts asociados a las Transacciones Web no es posible encriptarlos. Esto es porque el llamado a los prompts se realiza desde el cliente y para realizar la encriptación se debe ir al servidor. Ejemplos Si se tiene un Web Panel que recibe parámetros y no se utiliza la encriptación de parámetros, la URL correspondiente al Web Panel será del estilo: http://localhost/HINGRESO_WebObj/hdospar.asp?2,3 Si, en cambio se utiliza encriptación de parámetros (propiedad “Encrypt URL Parameters” en “Session Key” ó “Site Key”), la misma URL se generará de la siguiente forma: http://localhost/HINGRESO_WebObj/hdospar.asp?lQ/tK1lefxCZMVoXrnmrTQ== Comparación de alternativas de seguridad en la aplicación A continuación se realiza una comparación entre las soluciones disponibles para agregar seguridad a una aplicación Web. Cookies Ventajas  No es necesario el pasaje de parámetros entre Web Panels, ya que los valores se graban en la cookie. Si las cookies no son temporales, se puede saber si el usuario ya accedió anteriormente a la aplicación.  Desventajas  Tienen limitaciones en cuanto al tamaño máximo, cantidad de cookies que se pueden grabar. Se tiene dependencia de la configuración del browser. Manejo de sesiones Ventajas  Es independiente de la configuración del browser del PC del cliente. Desventajas   Mayor complejidad de programación Pérdida de información: si el usuario pasa a una página estática, y luego vuelve a ingresar la URL en el browser, debe volver a loguearse. Tipo de datos Web Session Ventajas  Presenta las mismas ventajas que el uso de cookies. Desventajas  Depende de la configuración del browser. No permite compartir datos si los objetos son generados en diferentes lenguajes. Por el momento no es soportado por C/SQL. No es posible compartir la información de sesión entre diferentes servidores, ya que es local al servidor Web. La destrucción de los datos depende del browser utilizado.   Encriptación de la URL Ventajas  No se requiere programación alguna, simplemente se modifica el valor de una propiedad. Desventajas  El tamaño de la URL aumenta al ser encriptada, por lo tanto si el pasaje de parámetros es importante, se puede llegar al máximo aceptado por el browser. Requieren del uso de cookies en el caso de “Session Key”. Características por Generador Además de los temas vistos anteriormente, existen algunas características particulares para cada generador que permiten brindar mayor seguridad a las aplicaciones. Generador .NET Para el Generador .NET existen las siguientes propiedades a nivel del modelo:   Generate strong named assemblies SessionState La primera, determina que los objetos main y/o dlls (assemblies) generados tengan un nombre único o no. Esto permite acceder a un conjunto de ventajas importantes que provee el Framework .NET, como ser la configuración de seguridad para el assembly. En cuanto a la propiedad SessionState, se refiere a la implementación del manejo de sesiones (Tipo de dato Websession) el generador utiliza el HttpSessionState provisto por el Framework. Por lo que existen diversos modos de almacenar la session state. Con lo cual es posible configurar por ejemplo, el tiempo que viven las variables de sesión. Por más información: http://www.gxtechnical.com/gxdlsp/pub/iehelp.htm?genexus/csharp/docum/manuals/9.0/manualn et90.htm Generador Java Con el Generador Java existe la posibilidad de conectar un servidor Web al motor de servlets, de forma de que los requerimientos vayan directamente al servidor Web (al puerto 80). Luego éste los redirecciona al motor de servlets (puerto 8080 por defecto), quien es que los resuelve, y manda la respuesta al servidor Web. El motor de servlets ejecuta los servlets, y es quien establece la conexión a la base de datos. El servidor Web solo sirve de "intermediario" como una capa más de seguridad, pero allí no se ejecuta nada. Este servidor puede estar en el DMZ entre dos firewalls, uno que lo une a Internet, y otro a la red local. Por más detalles técnicos de este tema, se recomienda acceder al siguiente link: http://www2.gxtechnical.com/portal/hgxpp001.aspx?15,4,61,O,S,0,,17187;S;0;A;0;0;;;;;;;;;;;;;;;;;A;%2 0%20/%20%20/%20%20;;0;9;;17187;;99;;0;1;%200;N;N;S;B;B Demo: Uso de Cookies Como hemos visto hasta el momento, si bien el Web Panel MainSearch permite realizar consultas para que pueda ver los detalles de un vuelo se exige que el usuario ya se haya identificado y que sea por supuesto un usuario válido. En caso de ser un usuario registrado y haberse identificado, se mostrarán los detalles del vuelo y precios del mismo, pero en caso contrario se le dará al usuario un mensaje diciéndole que "Debe identificarse antes de realizar alguna compra". Todo esto es lo que tenemos que implementar en el Web Panel MainSearch. Es decir, que a partir del link asociado al atributo FlightDsc se requiere que la aplicación sea segura. Utilizaremos cookies “temporales” para evitar que todo usuario que se registre al sitio desde el mismo computador utilice la misma información de conexión. Disponemos de un Business Object (security.xpz) que brinda los objetos necesarios para definir la “seguridad” en las aplicaciones Internet utilizando cookies. Implementación de la seguridad en nuestra aplicación El control de la seguridad lo implementaremos utilizando:  Una tabla denominada Security donde se almacena para cada nuevo usuario el número generado en forma aleatoria para su sesión, así como la fecha y hora de la última sesión activa. La estructura de la tabla sería entonces la siguiente: SecId* SecRnd (Número de sesión randómico) SecDate (Fecha de Inicio de Sesión) SecHour (Hora de Inicio de Sesión)  Una cookie denominada SECURITY que concatena (separados por una coma) el número identificador del usuario (atributo UserId), así como un número generado en forma aleatoria de la sesión de este usuario (atributo SecRnd). Descripción de Objetos del archivo security.xpz A los efectos de una buena comprensión del xpz, se describen los objetos que lo integran y utilizaremos. SECURITY Es la Transacción que define la tabla de SECURITY. INSERTSEC Este Procedimiento da de alta en la tabla SECURITY la primera vez que el usuario inicia una sesión en el Web. CHECKSESSION Este procedimiento valida el número de sesión recibido con el usuario que está logueado, y devuelve el código de validación resultante. A la sesión se le da una validez de 1 día. Se distinguen tres casos: cuando el usuario tiene iniciada una sesión vigente (valor S), cuando el usuario tiene una sesión vencida (valor V) y cuando el usuario tiene una sesión, pero no coincide el número randómico de sesión (valor I). GENSESNUM Este procedimiento actualiza el número randómico de sesión del usuario, junto con la fecha y hora en que se logueó por última vez. RETSTR Este procedimiento devuelve los dos valores almacenados en la cookie: el número de usuario y el número de sesión. ERROR Este Web Panel se invoca siempre que sea necesario cancelar la ejecución de la aplicación (por ejemplo: cuando la sesión ya no está vigente se invoca automáticamente a este Web Panel, desplegándole al usuario el mensaje correspondiente). Lo primero a hacer entonces es consolidar en la base de conocimiento del curso el archivo security.xpz. ¿Dónde dentro de la aplicación tenemos que grabar las cookies? o lo que es lo mismo ¿dónde dentro de la aplicación tenemos que invocar a la función SetCookie? La cookie se debe grabar cuando el usuario se registra en el sitio por primera vez (en la Transacción TUsers) y cada vez que se identifique. 1) Cuando el usuario se identifica,luego de chequear que el usuario y password ingresados son válidos, tenemos que grabar una cookie (con la función SetCookie), y luego en el evento Start del Web Panel Flights de “acceso limitado a usuarios registrados” tenemos que leer la cookie (con la función GetCookie). Como definimos anteriormente un web component para encapsular el procedimiento de login, simplemente debemos editar el evento “Enter” del Web Panel definido como web component y realizar la siguiente modificación: Event Enter For each where UserNickName = &UserNickName &UserId = UserId If UserPwd = &UserPwd &SecRnd = Udp(PGenSesNum,UserId) &CookieVal = Concat(trim(Str(UserId)),trim(Str(&SecRnd)),',') &result = SetCookie('SECURITY',&CookieVal) Msg( 'Welcome') Else Msg('Invalid Password') EndIf when none Msg( 'Invalid User') Endfor 2) El otro lugar donde tenemos que grabar una cookie es cuando se da de alta un usuario nuevo. Es decir, que en la Transacción Users (TUsers), luego de dar de alta el usuario, tenemos que grabar una cookie en el PC Usuario con el UserId del usuario nuevo y el número de sesión randómico. Para esto vamos a crear un procedimiento Login con el siguiente código: &SecRnd = Udp(PGenSesNum,&UserId) &CookieVal = Concat(trim(Str(&UserId)),trim(Str(&SecRnd)),',') &result = SetCookie('SECURITY',&CookieVal) Este procedimiento debería recibir como parámetro la variable &UserId. En la Transacción TUsers, deberíamos agregar en las reglas: Call(Plogin,UserId) on AfterComplete; Hagamos entonces estas modificaciones necesarias ¿Dónde tenemos que leer las Cookies? Es decir ¿dónde debemos invocar a la función GetCookie? Como ya dijimos antes, todos los Web Panels del sitio de “acceso limitado a usuarios registrados”, deben realizar el control de la seguridad leyendo la cookie y comparando los valores obtenidos con los valores almacenados en la tabla de SECURITY. En nuestro caso, en el link asociado al atributo FlightDsc. Hagamos el control en el Web Panel “FLIGHTS” de que el usuario tiene que ser un usuario “registrado” para poder VER DETALLES Y PRECIOS ... El evento asociado al link del atributo FlightDsc quedaría entonces: Event Flights.Load &interesting = Loadbitmap("int_unsel.bmp") &CookieVal = GetCookie('SECURITY') Call(PRetStr,&CookieVal,&UsrStr,&SecStr) &UserId = Val(&UsrStr) &SecRnd = Val(&SecStr) &result = Udp(PCheckSession,&UserId,&SecRnd) If &result = 'S' // si la sesión de dicho usuario está vigente FlightDsc.Link = Link(Hflights, FlightId) Else // si la sesión de dicho usuario no está vigente Call(HError) Endif EndEvent Haga clic aquí para ver la demostración Notas:  Observe que para el usuario de prueba que se estaba usando en los ejercicios anteriores, al momento de creado no se tenía en cuenta la seguridad del sistema, por lo cual no fue dado de alta en la tabla de seguridad, y cualquier intento de realizar una compra con él va a dar error. Entonces, para probar el ejercicio hecho en este capítulo, dé de alta un nuevo usuario a través de la Transacción Users.  El Web Component Login, es el que tiene la lógica de seguridad y es importante que el usuario en cualquier parte del sitio se pueda logear, y navegar por toda la aplicación hasta que opte por ver detalles y precios de los vuelos. Por tal motivo, el Web Component Login está presente en la Master Page y por lo tanto está en todos los objetos del sitio. INTRODUCCIÓN Patterns es una herramienta, que se puede utilizar tanto desde GeneXus como en forma independiente. Permitiendo aplicar a una base de conocimiento cierto patrón (pattern), y que se generen todos los objetos GeneXus necesarios para implementar el patrón, para aquellas instancias que se hayan seleccionado. En este capítulo profundizaremos en los patterns y las formas de utilizar dicha herramienta como medio para obtener una mayor productividad en el desarrollo de las aplicaciones Web. Aplicaremos la herramienta en nuestra base de conocimiento para definir nuevos objetos. Generalidades Es común sentir al desarrollar aplicaciones que algunas partes son muy similares pero no exactamente iguales. Por ejemplo, si se tienen clientes y productos, si bien los actores de la realidad (clientes y productos) son totalmente diferentes, los “Trabajar con” para cada uno de ellos tienen muchas cosas en común:     grid en el form un conjunto de variables para utilizar en filtros ordenamiento de los datos que se muestran acciones que se ofrecen de actualización de la base de datos, consultas, etc. Esta situación es llamada “Pattern” (patrón) y ha sido un tema muy popular en la industria del software recientemente. Dado que con GeneXus trabajamos a nivel de conocimiento y no de código, aplicamos el concepto de patrones a reusar conocimiento. Hemos desarrollado un marco de trabajo con las siguientes características: • Activo: Se generan objetos GeneXus que implementan cierto patrón para una o varias instancias elegidas. • Reutilización de conocimiento: Se trata de un nuevo nivel de reutilización de conocimiento, ya que el mismo conocimiento puede utilizarse para diferentes situaciones. • Abierto: Cualquier persona puede crear un patrón o modicar uno existente. • De fácil uso: (A excepción de la creación de nuevos patrones). Descripción de la herramienta Patterns es una herramienta que es parte de GeneXus 9.0 (Tools / Patterns), que puede ejecutarse también como aplicación independiente. El objetivo de esta herramienta es el incremento de la productividad y calidad en las aplicaciones. Básicamente la herramienta Patterns permite aplicar a una base de conocimiento cierto patrón (Pattern), y generar todos los objetos GeneXus que implementen el Pattern para aquellas instancias que se hayan seleccionado. Es importante tener en cuenta que la base de conocimiento debe estar en diseño para poder utilizarla. Existe un conjunto de Patterns muy útiles ya definidos (al instalar la herramienta se instalan) para que el desarrollador pueda comenzar a usar dichos patrones rápidamente. A su vez la herramienta permite crear Patterns nuevos, siendo esta una tarea un poco más compleja. Requerimientos Esta herramienta se puede utilizar únicamente con los generadores .NET y Java. Para obtener más detalles de los requerimientos de software de instalaciónla ver la siguiente página: http://wiki.gxtechnical.com/wiki/tiki-index.php?page=PatternsInstallation Patterns existentes Hasta ahora los Patterns con los que contamos son: Work With: “Trabajar con” en Web; genera a partir de una Transacción (o para todas aquellas Transacciones que se deseen), todos los objetos necesarios para tener una aplicación Web: trabajar con, views, seguridad, etc.. Bill of materials: Permite generar a partir de una Transacción, otra que representa la relación compuesto–componente. OAV: Objeto-Atributo-Valor; genera a partir de una Transacción otras dos Transacciones que permiten extender la original, con el objetivo de permitir definir atributos en tiempo de ejecución. Además, seguimos trabajando en la definición de nuevos Patterns. Tenemos un catálogo con una lista de Patterns, algunos de los cuales ya están implementados y otros sugeridos para una futura implementación. Para acceder al catálogo: http://wiki.gxtechnical.com/wiki/tiki-index.php?page=Business+Patterns+Catalog Demo: Configuración de Patterns y definición de instancias Una vez abierta la base de conocimiento en GeneXus, en el modelo de diseño, se dispone de la opción Tools / Patterns para acceder a la herramienta. Una vez ubicados en la herramienta veremos los pasos a seguir para aplicar el Pattern Work With. 1) Tools / Change Pattern Configuration. Desde esta ventana vamos a modificar algunas de las propiedades del archivo WorkWith.config, de forma tal que al momento de aplicar el Pattern ya tome en cuenta dichos cambios en el patrón. Para ello haremos los siguientes cambios:      Template / Update transaction = Apply WW Style Grid / SaveGridState = True Grid / EnableDisablePaging = True MasterPage = MyMPage Standar Actions / Export = False Haga clic para ver la demostración 2) A continuación, mostraremos cómo hacer para modificar los “Instance File”. En este caso quitaremos algunos atributos del grid de los Work With. Haga clic aquí para ver la demostración 3) Build / Configure GeneXus Integration. Desde esta pantalla configuraremos las opciones de la integración del resultado de aplicar el pattern Work With en nuestra base de conocimiento. Haga clic para ver la demostración 4) Procederemos a aplicar y generar los objetos resultantes de aplicar el pattern. Para ello, marcaremos todas las Transacciones y con el botón derecho seleccionamos “Generate, Apply and Consolidate”, como se muestra aquí. Uso de la herramienta A continuación veremos los distintos pasos a seguir para el uso de la herramienta Patterns y como obtener rápidamente una aplicación Web ejecutando en este caso el Pattern Work With. Donde los objetos generados estarán basados en la definición que se realizó para ese patrón y a su vez quedarán generados con código de calidad, y con lo cual se podrá visualizar el aumento de productividad que se obtiene al utilizar la herramienta. Paso 1 Una vez abierta la base de conocimiento en GeneXus, en el modelo de diseño, se dispone de la opción Tools / Patterns para acceder a la herramienta. Cuando se trabaja con la herramienta Patterns con una base de conocimiento por primera vez, se presenta un diálogo cuyo título es “Workspace Configuration”. Este diálogo permite configurar algunas opciones relacionadas a la base de conocimiento, otras opciones relacionadas al pattern a ser aplicado, y otras opciones relacionadas a operaciones de GeneXus (impactar, especificar, etc.) que pueden ejecutarse utilizando la herramienta Patterns. En este punto inicial puede cerrarse este diálogo si se desea, y posteriormente es posible ingresar al mismo, mediante el ítem Build / Configure GX Integration (ver paso 8). Paso 2 Se despliega información de la base de conocimiento utilizando GXPublic . Dado que muchos Patterns usan Transacciones, se muestra una lista de las Transacciones disponibles en el tab KB Explorer: GxPublic es el componente de GeneXus que permite acceder a la información de la base de conocimiento programáticamente. Paso 3 Se debe seleccionar en el combo box mostrado en la barra de herramientas, el pattern que se desea aplicar: Se ofrece por defecto la lista de patterns predefinidos. Paso 4 Debemos obtener un “Instance File” por cada caso al cual queramos aplicar el pattern. El “Instance file” es un archivo XML con los datos propios de la instancia. Si bien es posible crear cada “Instance File” de cero, los patterns suelen proveer una funcionalidad para crear “Instance Files” por defecto, y luego poder modificarlos fácilmente. Esto se puede lograr de dos formas posibles en el tab KB Explorer:  Teniendo una Transacción (o varias) seleccionada(s) se presiona botón derecho opción Generate Instance File.  Doble clic en una Transacción. Llamamos proceso de instanciación de un patrón al proceso de aplicar un patrón a una o varias situaciones (instancias). En el proceso de instanciación de un patrón las entradas son: • Instance files: por cada situación o instancia a la cual se quiera aplicar el patrón, habrá que crear un instance file con la información propia de esa instancia en particular (atributos a mostrar, etc.). Cada instance file es en definitiva un archivo XML con los datos propios de la instancia. Template files: contienen la implementación del patrón y de su aplicación a las instancias. • El resultado que se obtiene del proceso de instanciación de un patrón (procesando los instance files y template files) es: un conjunto de objetos GeneXus para ser consolidados en la base de conocimiento. Paso 5 Cada “Instance File” es un archivo XML con estructura jerárquica, conteniendo cada uno de sus nodos un conjunto de propiedades. La herramienta Patterns ofrece dos editores, para editar cada “Instance File” en el panel derecho: el editor XML View y el editor Tree View. El editor XML View permite editar los instance file directamente en su formato XML. Por su parte el editor Tree View es mucho más amigable, sencillo de usar, y con interfaz en alto nivel que provee mayor funcionalidad para ayudar en el proceso de edición. Por todo esto el editor Tree View es el más usado y recomendado para usuarios no avanzados. Paso 6 Los “Instance Files” se deben grabar. Para ello, bajo el ítem Instance se ofrecen las opciones Save (salva el “Instance File” con el que se esté trabajando) y Save All (salva todos los “Instance Files” en el caso que ya existan, pregunta si se desea reemplazar). Los “Instance Files” que no se han salvado aún se visualizan con el nombre: <Transaction Name.Pattern>*. Una vez salvados se visualizan con el nombre: Transaction Name.Pattern (ej: Country.WorkWith). ¿Dónde se almacenan físicamente los “Instance Files”? En el subdirectorio Templates bajo el directorio de la base de conocimiento. Seleccionando el tab Folder Explorer se pueden visualizar estos archivos: Es importante tener en cuenta que si se generan los “Instance Files” por defecto nuevamente a partir de las Transacciones, serán sobrescritos. Paso 7 Una vez creados y editados los “Instance Files”, el siguiente paso es que la herramienta genere los objetos GeneXus que implementan el pattern para las instancias. Para lo cual se cuenta con las siguientes opciones :    Build / Apply Pattern Build / Apply and Consolidate (posibilita que se consoliden a continuación) Estando posicionado en el tab Folder Explorer, luego de haber seleccionado los “Instance Files” (.workwith files), con botón derecho, se pueden ejecutar las opciones Apply Pattern o Apply and Consolidate. A su vez es importante tener en cuenta que si se selecciona la opción Apply and Consolidate se efectuarán también las siguientes acciones:    Se configurará como Tema por defecto de la aplicación al Tema Fantastic. El directorio Images será copiado automáticamente bajo el directorio KBPath\Templates. La propiedad del modelo de diseño "Base image path" se configurará con el valor anterior. También es posible seleccionar una Transacción o un grupo de Transacciones estando posicionado en el tab KB Explorer, y ejecutar la opción Generate, Build and Import. Pero es importante entender que seleccionando esta opción, se generarán los “Instance Files” por defecto nuevamente para las Transacciones seleccionadas, y luego de ello, se generarán los archivos <TransactionName>.xpz.xml correspondientes y se consolidarán en la base de conocimiento. Si se está seguro de que los “Instance Files” por defecto no necesitan ser editados, es posible seleccionar esta opción directamente. Paso 8 Para hacer más fácil todo el proceso, desde la herramienta Patterns, es posible ejecutar las acciones que se realizan con GeneXus: impactar el modelo, especificar, generar, compilar y ejecutar. Estas acciones se configuran en el diálogo “Workspace Configuration” que se abre en el momento de abrir la base de conocimiento con la herramienta Patterns, o seleccionando luego la opción Build / Configure GX Integration. OPCIONES DISPONIBLES EN EL DIÁLOGO Model: Muestra los modelos definidos en la base de conocimiento, y permite seleccionar uno de ellos. Se requiere tener los modelos generados. Apply and Consolidate: Al seleccionar dicha opción, es posible ejecutar más acciones además de la generación de objetos y consolidación. Este combo ofrece las siguientes posibilidades:      Consolidate Only (Apply and Consolidate) Impact Model (Apply and Consolidate + Impact Model) Impact, Specify (Apply and Consolidate + Impact + Specify) Impact, Specify, Compile (Apply and Consolidate + Impact + Specify + Compile) Impact, Specify, Compile, Run (Apply and Consolidate + Impact + Specify + Compile + Run) GeneXus Version: La versión de GeneXus correspondiente a la base de conocimiento se detecta automáticamente (puede ser 8.0 o 9.0). El modelo se especificará / generará con dicha versión. Build Actions: Permite seleccionar qué objetos deben especificarse y generarse al seleccionar Specify and Generate. Las opciones disponibles son:    Build All Build Pending (updated since last specification) Specify Consolidated Objects Specification: Permite seleccionar el tipo de especificación / generación a ser ejecutado al seleccionar. Specify and Generate: Las opciones disponibles son:    Full Specification Check Specification Force Generation Run Command: En esta opción se debe indicar la URL que se ejecutará si se seleccionó la opción Impact, Specify, Compile, Run. Por ejemplo, se debe escribir: “http://localhost/services/hwwsocios.aspx”. La URL debe incluir todo el camino, incluyendo el objeto que se va a ejecutar. La herramienta Patterns genera un Web Panel homepage y un Procedimiento para listar todos los objetos del pattern Work With usados. Para ejecutar la homepage, se debe configurar la propiedad “Run Command” de la siguiente manera:  para aplicaciones .NET la propiedad “Run Command” en “http://localhost/services/hhome.aspx” para aplicaciones Java la propiedad “Run Command” en “http://localhost:8080/servlet/hhome”  ¿Cómo modificar los objetos? En muchas oportunidades surge la necesidad de modificar los objetos resultantes de la aplicación de cierto pattern. A continuación veremos las formas posibles de realizar las modificaciones. Mediante GeneXus Modificando los objetos GeneXus generados. Esta solución presenta la siguiente desventaja: en caso de querer volver a generarlos con Patterns, se regeneran los objetos, perdiendo los cambios hechos a los mismos. Mediante la herramienta Patterns  Modificando las propiedades de las instancias (en la medida que ofrezcan lo que se desea). Modificando el pattern, personalizándolo para que ofrezca configurar propiedades que implementen las necesidades.  ¿CÓMO MODIFICAR LAS PROPIEDADES DE LAS INSTANCIAS? Tomando como ejemplo del pattern Work With, veremos cómo se pueden modificar las propiedades de una instancia. Son muchas las propiedades que se ofrecen en los archivos de instancia correspondientes al pattern Work With para personalizar el comportamiento de los objetos que se generarán. A continuación describimos algunas de ellas. Nodo Selection El nodo “Selection” ofrece las propiedades relacionadas al Web Panel Work With que se generará para la instancia. Sus sub-nodos son: Modes Este nodo permite definir en cuáles modos se ofrecerá invocar a la Transacción. Las posibilidades y sus valores por defecto son: Insert: True Update: True Delete: True Display: False Export: True (exportación a planilla Excel) Para cada modo podrá especificarse una condición. Se proveen las siguientes propiedades para ese propósito: Insert Condition Update Condition Delete Condition Display Condition Si se define una condición asociada a un modo, la invocación para ese modo sólo se habilitará si la evaluación de la condición es verdadera (Ejemplo: CountryId=10). Attributes Este nodo permite definir cuáles atributos se desean mostrar en el grid (y para cada atributo, se pueden personalizar varias propiedades). Orders Permite ofrecer al usuario final varios órdenes posibles para ver el resultado de la consulta (es decir, las líneas mostrando los datos en el grid). Utilizando el botón derecho del mouse se puede definir un nuevo orden (su nombre y composición). Cada orden puede estar compuesto por varios atributos (pudiendo indicar para cada uno de ellos si se desea orden ascendente o descendente). Se presentará un combobox en el Web Panel Work With ofreciendo todos los órdenes posibles de seleccionar, para que el usuario final elija uno y los datos se presenten en el grid ordenados por el mismo. Filters Permiten definir condiciones de filtro, para que se muestren en el grid sólo los registros que cumplan con las mismas. Nodo View El nodo “View” por su parte, ofrece las propiedades relacionadas al Web Panel View que se generará para la instancia. El Web Panel View muestra toda la información de un registro, que fue seleccionado en el grid del Web Panel Work With (la información del registro es mostrada en una solapa de un tab control, y además hay una solapa con un grid por cada tabla directamente subordinada, para mostrar la información relacionada). Nodo Prompt El nodo “Prompt” permite modificar las propiedades realcionadas a cada Prompt que es generado por cada Transaccion de cada Work With. Este Prompt contiene toda la información necesaria para permitir la ejecución del mismo desde la Transacción y mantiene el mismo estilo que los objetos generados. Para invocar este objeto, se debe agregar la regla prompt(…) a la correspondiente Transacción. Archivos de Configuración Al crear cada “Instance File” por defecto, podemos observar que las distintas propiedades del “Instance File” se inicializan con valores por defecto. Dichos valores por defecto para las propiedades, se especifican en un archivo denominado NombrePattern.config (en nuestro caso WorkWith.config). El archivo NombrePattern.config se encuentra donde está instalada la herramienta Patterns, bajo el subdirectorio del pattern particular que se esté utilizando. Para el caso del pattern Work With estará bajo: Patterns\WorkWith (recordar que bajo el directorio de la herramienta Patterns, existe un subdirectorio por cada patrón predefinido (Work With, Bill of Materials, OAV) así como deberá haber un subdirectorio por cada patrón definido por el usuario. Si deseamos tener un archivo de configuración NombrePattern.config por cada base de conocimiento, debemos copiar este archivo al directorio Templates que se crea bajo la base de conocimiento al usar la herramienta Patterns; así la herramienta Patterns utilizará dicho archivo ubicado en la base de conocimiento para inicializar las propiedades de los “Instance Files” que se creen. Si la herramienta Patterns no encuentra el directorio Templates con este archivo bajo la base de conocimiento, utilizará el archivo NombrePattern.Config (en nuestro ejemplo WorkWith.config) ubicado en el directorio Patterns\WorkWith. El archivo WorkWith.Config permite configurar algunos aspectos generales que aplicarán a todos los objetos. Por ejemplo, las Master Pages a ser utilizadas por los objetos Web, los Web Components utilizados como header y footer, etc.. Para editar este archivo de configuración, la herramienta Patterns ofrece el ítem: Tools/Change Pattern Configuration, tal como se muestra a continuación: En este archive se pueden configurar diversas propiedades tales como: WW Configuration THEMECLASSES Esta opción indica las clases a ser utilizadas por el tema por defecto. Se puede utilizar cualquier otra clase ya definida. GRID Page = Page.Rows – Indica cuantas filas se visualizarán en el grid. SaveGridState – Indica si los Orders, Current Page y Filtros se guardarán para los Web Panels Work With o no. EnableDisablePaging – Indica si los botones de paginado serán deshabilitados o no, cuando la correspondiente acción no está habilitada (por ejemplo, el botón “Next” cuando se está visualizando la última página). TAB MaxTabs – Indica cuantos Tabs serán visualizados en un View. Si hay más Tabs que los indicados en MaxTabs, se generará un Scroll para permitir navegar a través de los mismos. StandardActions DefaultMode – Indica cuando incluir la acción en un grid por defecto. Aplica a las acciones insert, update, delete y display. Context Esta propiedad implementa el manejo del contexto. Por defecto, la implementación incluye una variable llamada &Context basada en el SDT Context y un procedimiento llamado LoadContext, que es invocado en el evento Stara e cada Web Panel. Esta característica puede ser usada, por ejemplo, para mantener información sobre el usuario conectado a la aplicación (especialmente para la autenticación/autorización), la empresa corriente para sistemas multi-empresa, etc.. Se puede modificar la variable y el procedimiento invocado, modificando la sección Context en el archivo WorkWith.Config. Por ejemplo, se puede usar la variable Context para definir un filtro: EmpCod = &Context.CurrentEmpCod. Security Esta propiedad implementa la seguridad a nivel del objeto. Por defecto, la implementación incluye un procedimiento llamado IsAuthorized, que es invocado en el evento Start de cada Web Panel, para controlar la autorzación del acceso a dicho recurso. Si el procedimiento retorna false, significa que el usuario no tiene autorización para ejecutar la aplicación, y por lo tanto el Web Panel de usuario no autorizado (NotAutorized) es invocado. En a implementación de ejemplo, este procedure siempre retorna True, se debería modificar según las necesidades del caso. Es posible modificar el objeto invocado,modificando la sección Security en el archivo WorkWith.Config. Demo: Patterns y Seguridad Después de haber aplicado el pattern Work With seguiremos avanzando en cuanto a la seguidad de la aplicación. Para lo cual, reutilizaremos el procedure IsAuthorized para mostrar como se programaría el acceso a los distintos objetos: Call(PLoadContext, &Context) If (&GxObject = 'TUsers' and &Context.Profile <> 'ADMINISTRATOR' ) &Authorized = Boolean.False Endif. Veamos entonces como quedaría dicho procedimiento: Además de la siguiente regla: parm(in:&GxObject, out:&Authorized); Haga clic aqui para ver la demostración INTRODUCCIÓN Cada vez más, el uso masivo de Internet propicia el desarrollo de aplicaciones de mayor versatilidad y complejidad para el ambiente Web. Es por esto que está surgiendo la necesidad de aplicar una reingeniería a las aplicaciones existentes y también, en muchos casos, la necesidad de desarrollar nuevas aplicaciones para Internet. Existen varias diferencias entre los ambientes GUI (aplicaciones con Interfaz de Usuario Gráfica) y Web, las que deberán evaluarse al momento de determinar la conveniencia del tipo de aplicación a desarrollar. La migración no debería verse como una conversión objeto a objeto sino que normalmente es una modernización de la aplicación usando otras herramientas tales como Patterns, GXPortal, GXFlow, Reporting, etc.. En este capítulo veremos los principales aspectos a ser tenidos en cuenta por los usuarios GeneXus. INTRODUCCIÓN En el desarrollo de una aplicación Web, la calidad de la interfaz con la que interactúa el usuario determina el éxito de la aplicación. La calidad de la misma está definida por una serie de pautas y técnicas. A este conocimiento se le llama “Usabilidad”. La interfaz de una aplicación Web está determinada a grandes rasgos por la estructura de la aplicación, el diseño de la misma y de su contenido. Con estructura de la aplicación nos referimos a la ubicación de los diferentes elementos para que sean encontrados de forma intuitiva por el usuario y utilizados de forma correcta. Hay que tener esta estructura bien definida antes de aplicar un diseño. El diseño de la aplicación es la parte gráfica de la misma, el conjunto de imágenes, colores, formas que va a tener la aplicación. El diseño del contenido permite que el mismo sea cómodamente leído y correctamente interpretado. A lo largo de este capítulo desarrollaremos cada uno de estos puntos para lograr aplicaciones Web exitosas y fáciles de usar.    Estructura de la aplicación Diseño de la aplicación Diseño del contenido Estructura de la Aplicación Con estructura de la aplicación nos referimos a la ubicación de los diferentes elementos para que sean encontrados de forma intuitiva por el usuario y utilizados de forma correcta. Hay que tener esta estructura bien definida antes de aplicar un diseño. Es importante que la estructura del sitio esté reflejada en todas las páginas en forma consistente. A la hora de definir la estructura en sitios corporativos, en general es recomendable no reflejar el organigrama de la empresa, sino reflejar una estructura de acciones a realizar o de información a encontrar. Siempre que pueda aprenda de sitios exitosos de su misma área para realizar una estructura similar, que resulte intuitiva para el mismo público objetivo. Es recomendable:     Mostrar las barras de navegación en todas las páginas. No cambiar la ubicación de las opciones de los menúes según cambien las páginas (mantener consistencia). Aplicar los mismos conceptos para las mismas acciones (links, botones, bullets, etc.). No poner links a la misma página en la que me encuentro.   Permitir que el usuario siempre controle la navegación: no deshabilitar botones estándares de los navegadores ni botones del mouse. Si usa un mapa del sitio (Sitemap) brinde la información de donde está el usuario en cada momento. Puede incluir una pequeña descripción de qué ofrece cada opción del menú. Navegación La navegación de una aplicación permite ir a las distintas partes, sectores, páginas de la aplicación rápidamente y en forma intuitiva. La estructura del sitio se debe reflejar en la navegación permitiendo contestar las siguientes interrogantes: ¿Dónde estoy? Dentro del universo de sitios/ aplicaciones Web: Esto se logra mostrando el logo del sitio/ aplicación Web en todas las páginas. La ubicación habitual del mismo, y por lo tanto el lugar donde el usuario lo irá a buscar, es la esquina superior izquierda. Esta imagen debe tener siempre un enlace a la página de inicio de la aplicación o la página principal del sitio. Dentro de la estructura de la aplicación Web. Para ello se recomienda:   Marcar la opción seleccionada en la barra de navegación. Usar títulos en cada una de las páginas, dentro del área de contenido de forma que el usuario sepa dónde se encuentra. Nombrar las páginas en el cabezal de las mismas para que se identifiquen en el grupo de páginas que tiene abiertas el usuario. En GeneXus esto se hace usando la propiedad “Caption” del Form (Form.Caption). Para mostrar el nombre de la aplicación y de la página se puede usar un formato como los siguientes:    Sitio: página (Ej: GeneXus: Capacitación) Sitio – página Sitio > página   Usar nombres cortos para las páginas igual que para los sitios de modo que se puedan visualizar bien en el cabezal de la página. ¿Dónde estaba? Para indicar las páginas que el usuario ya visitó, conviene dejar los colores de los enlaces con los colores por defecto del navegador. ¿A dónde puedo ir? Mostrar todas las opciones a donde puede ir el usuario desde la página actual, sin marearlo con demasiadas opciones. Si las opciones son muchas, conviene agruparlas por áreas o sectores y dentro de los mismos mostrar submenúes. Herramientas de búsquedas (search) Si usa una herramienta de búsqueda, ésta debe de estar en todas las páginas del sitio, en un lugar siempre visible sin tener que usar las barras de desplazamiento. El lugar más intuitivo es el cabezal superior derecho, o la columna del menú izquierdo. Se recomienda hacer esta funcionalidad lo más simple posible de manera que sea fácil de usar. Lo más sencillo es tener una caja de texto y un botón que diga buscar. El uso de iconos, etiquetas, etc. necesita que el usuario las interprete y por lo tanto demore unos segundos en entender su uso. El resultado de la búsqueda debe ser claro, debe mostrar la cantidad de instancias encontradas, el texto usado para realizar la búsqueda, el título de cada página que contiene el texto buscado y un enlace en ese título a la página correspondiente. Menúes MENÚ SUPERIOR Tanto en sitios corporativos como en Intranets y Extranets se usa comúnmente un menú superior que contiene por lo general las siguientes opciones: 1. Página de Inicio Si bien hay un enlace en el logo de cada página, nunca está de más repetirlo ya que la página inicial es a la que se retorna con más asiduidad. 2. Acerca de, Acerca de Nosotros, Acerca de La Empresa, La Empresa, Quiénes somos, etc. Siempre es válido un enlace a información sobre la empresa que representa ese sitio, el producto que se vende a través del sitio, etc. que respalde la seriedad y veracidad del contenido presentado en el mismo. 3. Mapa del sitio, Mapa, etc. En la zona superior derecha se ubican las herramientas para encontrar páginas y contenido dentro del sitio, la ubicación de la herramienta de búsqueda y del mapa del sitio. 4. Contacto, Contáctenos, Contáctese, etc. Este enlace debe conducir a una página que contenga información para contactar a la empresa a través de teléfonos, emails y direcciones físicas. Esta opción del menú no debe ser un enlace a un correo electrónico, ya que incomoda al usuario porque ejecuta su aplicación de manejo de emails. En aplicaciones Web, este menú generalmente contiene:   Enlace a la página de inicio de la aplicación. Enlaces a información importante, no relativa a la aplicación en particular o a la parte de la aplicación desplegada en la página, pero que sirva para la aplicación entera, que sirva de respaldo, etc.. Ejemplo: información de registro del usuario (a la izquierda), idiomas de la aplicación, área de ayuda, contacto con soporte, página de la información de la empresa, etc.. MENÚ DE ÁREAS Muchas veces se usa el área de cabezal para ubicar un menú de áreas o categorías dentro de la aplicación o del sitio. Generalmente se utiliza cuando hay demasiadas opciones para ubicar en el menú izquierdo (más de 10). Categorizar los enlaces y agruparlos en áreas simplifica la navegación haciéndola más intuitiva. MENÚ IZQUIERDO Este menú contiene las opciones de navegación del sitio, todos los lugares del sitio a donde se puede acceder. En muchos sitios el menú izquierdo cambia según el área en la que el usuario se encuentre. Se debe mantener el mismo diseño del menú, independientemente de las opciones, para que al usuario sepa cómo usarlo ya que aprendió su uso en otras áreas del sitio. Links Hay tres tipos de links:    Links estructurales (de navegación) Links asociativos. Los clásicos links que se asocian a una palabra para ver más información relacionada a la misma. Links de información relacionada (Related links) Algunas recomendaciones para la definición de links:    Cuando se definen links subrayar las palabras importantes y brindar información suficiente para que el usuario se sienta atraído a seguir el link. Relacionar la información con links del tipo "más sobre tal tema", o sobre el autor, etc.. Usar “link title” siempre que no sea obvio a donde va el link, para que aparezcan los tooltips: o Si el link es externo, el nombre del sitio o Si es interno, el nombre del subsitio o Información adicional que se aplique o El tooltip debe tener menos de 60 caracteres Mantener siempre el color predeterminado para los diferentes links. Siempre usar los mismos nombres para acceder al mismo contenido.   Diseño de las páginas de la aplicación El diseño de la aplicación es la parte gráfica de la misma, el conjunto de imágenes, colores, formas que va a tener la aplicación. Se debe diseñar pensando en:     Velocidad de carga Público objetivo Uso de la aplicación Máximo aprovechamiento de los temas Velocidad de carga El tiempo que demora en cargarse la totalidad de una página determina la percepción que va a tener el usuario de ese sitio o aplicación. Si la aplicación demora en cargarse, el usuario pensará que no es buena, que no le solucionará sus problemas de forma correcta. Si la demora es excesiva, el usuario puede llegar a pensar que la empresa no es fiable. Para mejorar los tiempos de carga se recomienda:       Usar texto en vez de imágenes siempre que se pueda (Ej.: para los menúes) El formato de las imágenes siempre debe de ser .gif o .jpg, nunca .bmp, ya que este formato pesa mucho más que los anteriores. Usar herramientas para disminuir el peso de las imágenes. Ej: http://www.netmechanic.com/GIFBot/optimize-graphic.htm No usar imágenes animadas. No usar flash, ya que no sólo demora más la carga de la página, sino que muchas veces requiere que el usuario instale la tecnología. No hacer páginas que requieran el uso excesivo de las barras de desplazamiento horizontal. Esto no sólo ahuyenta al usuario por el tiempo que le consume, sino también por la cantidad de contenido que se le presenta. Es mejor hacer páginas más cortas, con la información suficiente, o armar más páginas a partir de una. Público objetivo Debe tener en cuenta quién será el público objetivo –a quién se dirige, quiénes serán los usuarios- a la hora de diseñar y elegir los colores, los tamaños de las letras y tamaños de las pantallas. Por ejemplo, si el público objetivo está integrado por desarrolladores, se puede hacer un sitio o una aplicación con letras de tamaño 8 puntos, pero no se recomienda usar este tamaño para un público masivo. Uso de la aplicación Cuando está diseñando también debe considerar cuál es la finalidad de la aplicación para no entorpecer el uso del servicio que se desea brindar. Si se trata de un sitio Web donde se ofrece bastante texto para leer no es recomendable que las páginas tengan sectores que llamen más la atención que el contenido principal de la página. Por ejemplo, las imágenes animadas son centros de atención. Es realmente molesto tener imágenes moviéndose en distintas partes de la página cuando se tiene que leer. Se pueden usar imágenes animadas si su movimiento se detiene una vez presentada la animación. De esta forma, se logra captar la atención del usuario que ingresa a la página para transmitir el mensaje que se desea con esas imágenes, y luego, se facilita al usuario la concentración para la lectura del texto principal. Si el sitio Web es un portal, donde se espera encontrar muchos focos de atención (textos cortos, muchos links) es más adecuado usar imágenes animadas. Máximo aprovechamiento de los temas (Themes) Maximizar el uso de los temas permite ajustar el diseño en tiempo de ejecución. Es recomendable que cada ítem que se use esté definido en el tema, de forma por ejemplo, que todos los títulos tengan la misma apariencia y si más tarde se quiere agregar espacio entre el título y el contenido se pueda modificar automáticamente en todos los títulos de la aplicación. Esto es válido para cada tabla usada en la aplicación, desde la que contiene las opciones del menú hasta la que contiene el contenido, los grids, las etiquetas de los formularios, etc.. Diseño del contenido La forma de escribir en Internet difiere a la usada en publicaciones físicas, principalmente porque es más difícil leer en la pantalla y el público es más exigente con el tiempo que le consume obtener una información. Debido a esto hay que escribir para Internet teniendo en cuenta las siguientes pautas:   Escribir lo más corto y conciso posible. Se dice que en Internet hay que escribir entre un 50% y un 25% menos de lo que se escribiría en papel. Poner las conclusiones al principio y una opción para ver el detalle de esa conclusión. Tipo de letras Se deben tener las siguientes consideraciones a la hora de elegir el tipo de letra a utilizar en una aplicación Web:    El tipo de fuente debe estar instalada en las máquinas destino El tamaño debe ser adecuado para el público objetivo y para la resolución más usada Elegir un estilo de letra (Serif o Sans Serif) y no mezclar estilos Los tipos de fuentes que en general se encuentran instaladas en todas las máquinas son Arial, Verdana y Times New Roman. Legibilidad Definición de Legibilidad: f. Capacidad o posibilidad de ser leído, por su claridad. La buena tipografía depende -entre muchas otras variables- del contraste visual entre una fuente y otra, y entre los bloques de texto, los títulos, y el espacio en blanco alrededor. Lo que más atrae al ojo es el contraste fuerte con patrones distintivos. Seguir patrones que conserven la forma de organizar el texto y las imágenes en las distintas páginas de un sitio o una aplicación permite entender la organización de la información, intuir la ubicación de más información y se aumenta la legibilidad de la misma. La lectura va a ser más cómoda cuanto mayor sea el contraste de los colores. El mayor contraste se logra con fondo blanco y letras negras. Se pueden establecer las combinaciones de colores en el editor de temas, en la clase "Form" y jugar con las mismas sin tener que cambiar ni una línea de código. Márgenes Los márgenes definen el área de lectura de una página, separando el texto principal de lo que lo rodea. Los márgenes y el espacio en blanco se usan para delinear el texto principal de otros elementos de una página, y usados de igual manera en todas las páginas proveen uniformidad a través del sitio creando una estructura consistente y una identidad visual. Es recomendable que los textos principales tengan un margen de 5 a 10 píxeles. Esto se logra en GeneXus poniendo el texto dentro de una tabla con “BorderWidht” en “0” y “Cellpadding” en “10”. La propiedad “Cellpadding”: especifica la distancia en píxeles entre el contenido y los bordes de la celda. La propiedad “Cellspacing”: especifica el ancho en píxeles de los bordes de la celda. Alineación de los textos La alineación izquierda de títulos y contenidos es la más recomendable para el público occidental. Los usuarios en Internet en general no leen los textos palabra a palabra, sino que escanean las páginas tomando algunas palabras de cada párrafo para entender la idea general de la página. La alineación izquierda facilita este tipo de lectura. Links de interés Usabilidad Sitios con artículos sobre usabilidad y temas relacionados con mejora en los sitios Web: EN ESPAÑOL http://usalo.es/ http://www.ciw.cl/ http://www.masterdisseny.com/ http://www.alzado.org/ http://www.cadius.org/ http://accesibilidadweb.blogspot.com/ http://www.proyectoweb.org/ http://www.microsoft.com/spain/empresas/guias/usabilidad/experiencia_usuario.mspx http://www.pdaexpertos.com/tutoriales/internet_movil/10_puntos_de_usabilidad_y_diseno_web_ para_pdas.shtml EN INGLÉS http://www.useit.com/ http://www.usabilitynet.org/ http://usableweb.com http://www.w3.org/TR/WCAG20/ http://www.handheldusability.info/ http://www.usability.gov/guidelines/ http://www.webusability.com/ http://www.userfocus.co.uk/resources/index.html http://www.humanfactors.com/downloads/10tips.asp http://www.htmlcenter.com/ Herramientas HERRAMIENTAS PARA REDUCIR EL PESO DE LAS IMÁGENES http://www.netmechanic.com/GIFBot/optimize-graphic.htm http://www.creatingonline.com/ http://www.gifworks.com/ TOOLBAR DE USABILIDAD http://www.southbourne.com/accessibility-toolbar.htm http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e2d5e1db91038&DisplayLang=en HERRAMIENTAS DE CHEQUEO DE LINKS ACTIVOS http://validator.w3.org/checklink http://www.anybrowser.com/linkchecker.html HERRAMIENTAS QUE MUESTRAN EL SITIO EN DISTINTOS NAVEGADORES http://www.anybrowser.com/siteviewer.html HERRAMIENTA PARA MEDIR LA VELOCIDAD DE CARGA DEL SITIO http://www.webperf.org/breakdown.html http://zing.ncsl.nist.gov/WebTools/ HERRAMIENTAS PARA TESTEAR LA USABILIDAD http://zing.ncsl.nist.gov/WebTools/ HERRAMIENTAS PARA CHEQUEAR EL CÓDIGO HTML Y MÁS http://zing.ncsl.nist.gov/WebTools/tech.html INTRODUCCIÓN Muchos años atrás visualizamos que las soluciones Web serían la respuesta a muchos problemas (distribución, disponibilidad, accesibilidad, escalabilidad, etc). Por eso a partir de la versión 6.1 de GeneXus incluimos generadores para esta plataforma. La evolución de la plataforma y el acompañamiento que GeneXus hizo de la misma, permitió que dejara de ser una plataforma para "páginas estáticas" y se convirtiera en una plataforma para soluciones de negocio reales tanto Internet como intranets. En la versión 9.0, además de los generadores para esta plataforma con los cuales se cuenta desde hace años, se incluyen tecnologías de punta (como Ajax) viabilizando funcionalidades nuevas para el ambiente Web, muchas de ellas "implícitas" en la versión (sin costo de desarrollo) y extremadamente complejas de desarrollar "a mano". El proceso de conversión de una aplicación GUI (Interfaz de Usuario Gráfica) a Web implica conocer algunas características de esta última plataforma y su relación con las funcionalidades y características de las soluciones GUI. Muchas veces no se trata de "convertir" la aplicación o parte de la misma, sino del desarrollo de un nuevo módulo en esa plataforma. En cualquier caso existe un "paralelismo" entre lo conocido por el desarrollador (ambiente GUI) y la plataforma nueva a la cual se está enfrentando (Web), lo cual requiere considerar las diferencias. En este capítulo profundizaremos tanto en las diferencias como en la conversión de GUI a Web. Comparación GUI – Web Objetivo El objetivo de este documento es brindar una herramienta de referencia, para asistir en la decisión de migrar o desarrollar una aplicación GUI, o una aplicación Web. Para analizar las diferencias entre los dos tipos de aplicaciones se compararán las ventajas y desventajas de las aplicaciones Web frente a las aplicaciones GUI. Existe otro artículo (Conversión de Aplicaciones GUI a Web) sobre esta misma temática en donde se dan los detalles técnicos de cómo realizar esta tarea, por lo que aquí no se mencionarán esos detalles. Introducción APLICACIONES CON INTERFAZ DE USUARIO GRÁFICA Las aplicaciones con Interfaz de Usuario Grafica (GUI) están compuestas por uno o varios programas GeneXus que utilizan objetos de tipo: Transacción, Work Panel, Procedimientos y Reportes. APLICACIONES WEB Se entenderá por aplicaciones Full Web a aquellas aplicaciones en las que la interfaz del usuario es únicamente realizada utilizando el lenguaje HTML y son accedidas desde un browser. En GeneXus estas aplicaciones se implementan con objetos Web como ser: Web Panels o Transacciones Web. El lenguaje HTML es un lenguaje de marcas (tags) para la estructuración de un documento. Si bien el lenguaje es estándar, en la práctica, cada browser toma algunas partes de la especificación, agrega e ignora otras. Como consecuencia de esto una aplicación Web puede quedar levemente distinta según el browser que se utilice. Características de las aplicaciones Web VENTAJAS DE LAS APLICACIONES WEB Una aplicación Web tiene diversas ventajas frente a las aplicaciones GUI. Instalación Las aplicaciones Web presentan varias ventajas tanto en la instalación y actualización como en los requerimientos necesarios para utilizarlas. Cliente ‘fino’. Para utilizar la aplicación Web solo se necesita un browser. Los browsers son distribuidos por Internet y no tienen costo. Generalmente vienen incluidos al instalar el sistema operativo. Adicionalmente se pueden instalar plugs-in, que son programas que agregan funcionalidades adicionales al browser. Un ejemplo muy común es el plug-in de Acrobat, utilizado para visualizar archivos en formato PDF o plugs-in para video o sonido. Flexibilidad en software y hardware en el cliente. En las aplicaciones Web, el cliente puede tener instalado cualquier sistema operativo en cualquier versión. Las aplicaciones Web no utilizan tantos recursos de hardware por lo que el costo de las computadoras clientes es menor y no necesita actualizaciones frecuentes. La aplicación solo se instala en el servidor. Generalmente la instalación y actualización de aplicaciones GUI en arquitecturas cliente / servidor implica, alguna instalación en las computadoras cliente. En el caso de aplicaciones Java GUI, esta instalación es automática, pero también existe ya que es necesario bajar la aplicación. En el caso de una aplicación Web no se requiere ninguna instalación adicional a la del browser, para poder accederla o acceder a otras aplicaciones Web. Escalabilidad Las aplicaciones Web utilizan una arquitectura de tres capas compuesta por la capa cliente, donde está únicamente el browser, la capa del Servidor Web donde está la aplicación y la capa de datos donde se encuentra la base de datos. BD Arquitectura en tres capas. Esta arquitectura presenta varias ventajas en cuanto a la escalabilidad. Escalabilidad de usuarios. En la concepción de la aplicación, no se tiene en cuenta la cantidad de usuarios que van a utilizarla. Es decir que la misma aplicación puede ser utilizada por algunos pocos usuarios o varios cientos. El límite estará determinado por el desempeño de la aplicación, que depende principalmente de la potencia de los servidores y de las características de la red. Una ventaja de la arquitectura en tres capas es que no es necesario pagar nuevas licencias por cada nuevo usuario que accede a la aplicación (por ejemplo los drivers de acceso a la base de datos se pagan por cantidad de usuarios concurrentes). Escalabilidad de servidores. El desempeño de la aplicación depende directamente de la potencia de los servidores en la que este instalada. Se puede migrar la aplicación a servidores más potentes, sin necesidad de que los usuarios cambien el modo en que acceden a la aplicación. Independencia Acceso. La aplicación puede ser accedida desde cualquier lugar que cuente con acceso a Internet. Esto puede tener un fuerte impacto en el modo de trabajo ya que se pueden acceder a las aplicaciones desde la oficina, el hogar o incluso desde otros países. Hosting Services Provider (HSP). La aplicación puede ser instalada en un centro de cómputos propio o puede contratarse un Hosting Service Provider (son empresas que proveen un centro de cómputos para aplicaciones Web) e instalarla en los servidores del HSP. Para los usuarios, el acceso a la aplicación es independiente de donde esté instalada. Interfaz gráfica Uniformidad. La forma de navegar por la aplicación Web será siguiendo links o presionando botones y si bien hay más opciones, estas son las más comunes y se mantendrán por toda la aplicación. Si bien este modo de interacción es limitado con respecto a las aplicaciones GUI, al ser tan simple y uniforme en toda la aplicación, al usuario final le resultará sencillo e intuitivo aprender a utilizar nuevas funcionalidades. El diseño gráfico es realizado por expertos. Un aspecto sumamente importante en la interfaz grafica de una aplicación Web es el diseño grafico. Este aspecto sumamente delicado se deja a cargo de diseñadores gráficos especializados, que hacen que las aplicaciones tengan aspectos atractivos y funcionales. El trabajo con los diseñadores gráficos sigue pautas similares a la metodología de prototipación utilizada en el desarrollo de aplicaciones GeneXus. Cuando los diseñadores tienen listo un prototipo, es conveniente que los desarrolladores lo evalúen para validarlo desde el punto de vista del desarrollo. Para esto se cuenta a partir de la versión 8.0 de GeneXus, con el Editor de Temas, herramienta que puede ser usada tanto desde GeneXus como en forma independiente, por lo cual flexibiliza notablemente la interacción con el diseñador gráfico, además de todas las ventajas adicionales que trae el uso de Temas en el diseño de la aplicación Web. Por detalles sobre Temas ver el documento Themes. Al evaluar un diseño hay que tener en cuenta ciertos aspectos:  Impacto del diseño de las páginas Web finales. Si se utilizan demasiadas imágenes, con muchos botones, el tamaño final de la página, puede ser excesivamente grande, por lo que se demorará mucho el acceso. La recomendación es cuidar de que las imágenes sean de pocos Kbytes. Los links de texto son muy livianos, en el caso de una aplicación muy accedida, puede ser conveniente utilizarlos. Los sitios Web de Amazon y Yahoo, son buenos ejemplos de interfaces livianas, con pocas imágenes y muchos links de texto. El diseño debe ser consistente. Por ejemplo la tipografía, los colores, la ubicación de botones, etc. debe seguir una pauta bien definida, que los desarrolladores deben respetar al máximo. El diseño debe ser simple y sencillo. El exceso de detalles gráficos, puede complicar el desarrollo y evolución del sitio. El diseño debe ser robusto de modo de poder soportar evoluciones, y nuevos requerimientos. Componentización. Es muy importante que la estructura de las páginas pueda ser separado en componentes, de modo de poder reutilizar los mismos objetos para simplificarle al usuario el conocimiento del sitio. En GeneXus esto, se implementa utilizando Web Components.     Mantenimiento. La posibilidad de desarrollar una página dividida en Web Components, permite tratar cada componente en forma independiente. Esto no solo hace las interfaces más robustas frente a cambios y extensiones, sino que además al cambiar un componente, se reflejan los cambios en todas las páginas que lo incluyen. O sea que no es necesario reprogramar todas las páginas, solo el componente adecuado, haciendo del mantenimiento de la aplicación sencillo. Integración de nuevas aplicaciones. La interfaz con el usuario se puede personalizar dinámicamente, de acuerdo a las características del usuario. Por ejemplo con menúes donde las opciones se cargan dinámicamente, según las aplicaciones a las que puede acceder el usuario. De este modo se logran aplicaciones más integradas y donde es más sencillo incorporar nuevas aplicaciones. Interfaz multimedia. Es muy sencillo incluir en las aplicaciones Web características multimedia como audio, video, imágenes, etc. Application Service Providers y servicios Web Los Application Service Providers (ASP), son empresas que brindan servicios y soluciones, basadas en software, a través de Internet. Ejemplos muy comunes de ASP en portales de Internet son los proveedores de noticias, banners, clima, etc.. Tener aplicaciones Web habilita a la empresa a funcionar como ASP, brindando como servicio el uso de las aplicaciones Web desarrolladas. También habilita a contratar a otros ASP para potenciar las aplicaciones propias. Integración de aplicaciones Internet e Intranet Las aplicaciones Web desarrolladas pueden ser utilizadas en Internet o en una Intranet, para uso interno. Además las aplicaciones Web ya existentes, utilizadas en la Intranet pueden ser integradas a las nuevas aplicaciones Web desarrolladas. Extensiones con Java y JavaScript En las aplicaciones Web se pueden incorporar extensiones en lenguajes como Java y JavaScript. Para controlar distintos aspectos de la interacción con páginas Web se utiliza el lenguaje JavaScript. El código escrito en este lenguaje es incorporado en el HTML e interpretado por el browser. Java es un lenguaje de programación muy potente, entre sus propiedades, se destaca la de ser multiplataforma. Esto quiere decir que las aplicaciones desarrolladas en Java pueden ejecutarse en cualquier sistema operativo y cualquier plataforma de hardware. Esta propiedad lo hace especialmente atractivo para aplicaciones que ejecutan a través de Internet. Por lo tanto se pueden incorporar aplicaciones GUI desarrolladas en Java, para potenciar la aplicación Web. Múltiples formas de acceso Múltiples tecnologías como computadores de bolsillo y teléfonos celulares están teniendo un fuerte desarrollo, principalmente como formas alternativas de acceso a Internet. Las características de hardware de estos dispositivos hacen que las aplicaciones Web sean las más adecuadas. La principal diferencia con las aplicaciones Web para estos dispositivos es el tamaño reducido de la pantalla. Si bien es necesario crear una versión particular para el dispositivo, se puede reutilizar mucho conocimiento de una aplicación Web ya desarrollada. INCONVENIENTES DE LAS APLICACIONES WEB En la siguiente sección se discuten las desventajas que presentan las aplicaciones Web frente a las aplicaciones GUI. Es necesaria una reingeniería de la aplicación. El lenguaje HTML presenta ciertas limitaciones que implica que migrar aplicaciones GUI a aplicaciones Web no sea una tarea automática. Entre los puntos que deben tenerse en cuenta al realizar la reingeniería de la aplicación se destacan los siguientes: Seguridad. Es imprescindible tener un esquema de seguridad en la aplicación, de modo de restringir el acceso a determinadas aplicaciones. Este puede basarse en definir roles con determinados accesos o un esquema en el cual a cada usuario se le asignan permisos particulares. Por otro lado la aplicación puede requerir que algunas aplicaciones particulares necesiten un esquema más fuerte de seguridad y requieran páginas Web seguras y servidores seguros. Transacciones e Integridad transaccional. Las Transacciones Web utilizan la misma arquitectura que los Web Panels. En la figura se ve la secuencia de acciones que ocurren al someter las Transacciones Web al servidor. Funcionamiento de las Transacciones Web y Web Panels. El tiempo de vida de las UTLs (Unidades de Trabajo Lógicas) en los objetos Web, se mantiene únicamente durante la ejecución del objeto. Cuando la ejecución termina se deben hacer commit o roll back. Por lo tanto no es posible definir una UTL a través de varias Transacciones Web. Sin embargo, es posible mantener la UTL a través de varios procedimientos que se invoquen unos a otros, siempre que se mantengan dentro de la misma ejecución. En las aplicaciones GUI es común encontrar que durante varias transacciones se van ingresando datos y luego en la última transacción se hace el commit de todos los datos ingresados, por lo que se deben contemplar estos casos en la reingeniería de la aplicación. Las alternativas posibles a esta situación son:   Unificar todas las Transacciones GUI en una sola Transacción Web. Dividir el proceso de ingreso en varias etapas y utilizar múltiples Transacciones Web. Al finalizar el ingreso podría tenerse un procedimiento que valide que el ingreso en varias etapas es consistente. Ingresar toda la información en tablas temporales y luego ingresar la información a la base de datos mediante procedimientos.  Limitación entre la interacción de objetos GeneXus. La interacción entre objetos GeneXus, en aplicaciones Web es más limitada que la interacción en aplicaciones GUI. Las Transacciones Web y los Web Panels pueden ser invocados entre sí, y ambos pueden invocar a procedimientos. Desde objetos Web no es posible invocar objetos no Web como Transacciones, Work Panels y Reportes, aunque para los reportes existe la posibilidad de generarlos en formato PDF. Este tipo de comportamiento que puede encontrarse en una aplicación GUI, debe ser tratado en la reingeniería de la aplicación. Diferencias en los Web Panels “Trabajar con”. En las aplicaciones Web, los Web Panels de tipo “Trabajar con” presentan algunas diferencias que en las aplicaciones GUI. El alto de la pantalla cambia, dependiendo de la cantidad de líneas del grid. En las aplicaciones GUI, el tamaño de los formularios se determina en el diseño de este y queda fijo en el momento de ejecución. En las aplicaciones Web, el tamaño de la página Web se puede extender (horizontal o verticalmente) si se presentan muchas líneas en los grids. La selección de líneas es diferente. En las aplicaciones GUI, las líneas se seleccionan al hacer clic en ellas, además se puede seleccionar un rango de líneas, continuo o con líneas salteadas, todo esto sin necesidad de programación extra. En las aplicaciones Web, la selección múltiple de líneas debe programarse mediante campos de chequeo. Una posibilidad es permitir la selección de múltiples líneas y utilizar el carrito de compras (se describe más adelante). Se puede usar la propiedad “AllowSelection” de los grids para que sea posible seleccionar de a una línea. El modelo del carrito de compras. El carrito de compras, es muy utilizado en los sitios Web con ecommerce y permite “recordar” los objetos que compran los usuarios. En el carrito de compras se van seleccionando distintos ítems que se desean comprar. El carrito mantiene almacenado el contenido hasta que el dueño decide comprar alguno o todos los ítems. Esta idea resulta práctica en casos como este: Factura de compras. La factura se va armando seleccionando los elementos que la componen: lista de productos disponibles, lista de clientes, formas de pago, monedas, etc. Cuando se termino de armar, se construye la factura con toda la información del carrito. Si se quiere realizar alguna acción a una serie de líneas en un “Trabajar con”, se pueden ingresar en el carrito y luego automáticamente se van presentando una a una las páginas adecuadas para la acción determinada, hasta vaciar el carrito. Ejecución en el servidor. En Web con el uso de la tecnología Ajax las aplicaciones cada vez se asemejan más a Win, ya que se ejecutan acciones tanto en el cliente como en el servidor. Por más detalles ver Tipos de diálogo. Infraestructura de hardware. La performance de una aplicación Web depende en gran medida de la cantidad de usuarios concurrentes accediendo a la aplicación, el ancho de banda de la conexión y la potencia de los servidores. Por lo tanto los servidores (Web y de base de datos) y el ancho de banda de “salida” debe ser adecuado a la cantidad de usuarios esperada. También es imprescindible un esquema fuerte de seguridad principalmente de la base de datos. Una aplicación Web debe estar disponible los 7 días de la semana, durante las 24 horas del día. Esto implica un servicio de alta disponibilidad en el cual posiblemente se maneje redundancia de servidores y de información. Conclusiones Las aplicaciones Web son una nueva alternativa a las aplicaciones de interfaz gráfica. Ambos tipos de aplicación tienen sus características propias por lo que en cada aplicación se debe evaluar si conviene realizarla como Web o GUI. Los puntos discutidos en este artículo pueden ser considerados como una guía para tomar esta decisión. Como requisito para tomar una decisión correcta se debe comprender:   El funcionamiento de la interfaz Web y las limitaciones que ello trae como consecuencia. Las limitaciones en la integridad transaccional. Algunos puntos a tener en cuenta para evaluar la creación o migración a aplicaciones Web son:     Requerimientos y proceso de instalación de la aplicación final. Ambiente en donde se ejecute la aplicación. Requerimientos en el acceso. Interfaz gráfica en cuanto a facilidad de uso, diseño gráfico atractivo y capacidades multimedia. Acceso desde múltiples plataformas como computadoras de bolsillo, etc.. Requerimientos de seguridad en la aplicación. Tipo de diálogo en las Transacciones GeneXus, especialmente en la validación de datos y disparo de reglas, considerar las acciones que se dispararán en el cliente y cuales en el servidor. Restricciones en la interacción de objetos GeneXus. Debe ser evaluado cuidadosamente en el caso de migrar una aplicación GUI a Web.     Como punto final hay que tener en cuenta la evolución de la aplicación en cuanto a la creación de nuevos módulos, cantidad de usuarios y mantenimiento. Conversión de aplicaciones GUI a Web Objetivo El objetivo de este documento es describir los principales aspectos técnicos a tener en cuenta al momento de convertir una aplicación GeneXus de tipo GUI-Windows a una aplicación Web. Introducción APLICACIÓN GUI Entendemos como aplicación GUI (Graphic User Interface) a toda aquella que tiene interfaz gráfica Windows, compuesta básicamente por los objetos Transacciones, Work Panels, Procedimientos y Reportes, generadas con los generadores GeneXus Visual Basic, Visual Fox, Java y .Net. APLICACIÓN WEB Una aplicación Full Web tiene una interfaz HTML (HyperText Markup Language) y se ejecuta dentro de un browser. Este tipo de aplicaciones se desarrolla básicamente con los objetos Web de GeneXus: Web Panels y Web Transactions. Se generan con cualquiera de los generadores Web: Java, .Net. Reingeniería de la aplicación La premisa fundamental para convertir una aplicación Win a Web es que los ambientes implicados (gráfico, html) son diferentes y por lo tanto la conversión implicará algo más que la mera conversión de los objetos. Deberá programarse con “estilo Web”. En este documento centralizamos consideraciones a tener en cuenta para los diferentes objetos y modalidades de programación. La conversión de los objetos implica: 1. 2. 3. Conversión de Work Panels Conversión de Transacciones Conversión de Reportes 1. CONVERSIÓN DE WORK PANELS A WEB PANELS Una posibilidad para realizar la conversión de los Work Panels a Web Panels es utilizar la facilidad de SAVE AS que brinda GeneXus. De esta forma, se convierte en forma automática el form gráfico al form HTML y se mantiene toda la lógica del objeto. Algunos controles Win no son soportados en Web (por ejemplo el tab control), con lo cual no siempre es automática la conversión de un form a otro. Otra posibilidad es crear un nuevo objeto (Web Panel) y copiar la lógica del Work Panel hacia el Web Panel. Observe que se debe revisar la lógica ya que existen ciertas diferencias en la interfaz que obligan a cambios en la programación. Se recomienda leer el documento Comparación entre Web Panels y Work Panels donde se comparan generalidades de ambos tipos de objetos. Luego de convertir el objeto, se debe editar el código HTML del mismo y quitar los tags <pre> y </pre> que quedan al principio y al final respectivamente del mismo. Hay que tener en cuenta que la conversión no crea una tabla con los controles dentro, por lo tanto al quitar los tags mencionados anteriormente la pantalla se “desarma” y quedan todos los controles juntos. Se aconseja por lo tanto, crear primero una tabla donde se pueda “arrastrar” los controles y finalmente quitar los tags <pre> y </pre>. 2. CONVERSIÓN DE TRANSACCIONES A TRANSACCIONES WEB Se cuenta con un form HTML default por cada Transacción Web (con los atributos de la Transacción, así como los controles propios de Transacciones Web, como ser el Error Viewer). Luego ese form se puede modificar a gusto del programador. En algunos aspectos, el comportamiento de las Transacciones Web es diferente al de las Transacciones con interfaz gráfica por lo tanto se recomienda la lectura del documento Transacciones Web. 3. CONVERSIÓN DE REPORTES Una posibilidad para manejar reportes es programar un Web Panel, de forma que el usuario final pueda imprimirlo con las opciones de impresión del browser. Otra posibilidad como solución a la necesidad de implementar un reporte en ambiente Web es generar un reporte con salida PDF. Diferencias entre los ambientes y como manejarlas WORK PANEL “TRABAJAR CON” Es muy común el uso de Web Panels del estilo “Trabajar con” donde se despliega un grid con registros y una cantidad de opciones aplicables a cada una de las líneas del mismo. Por ejemplo: 2 – Modificar, 3 – Visualizar, etc.. Manejo de opciones En el objeto Web Panel, existen algunas alternativas para implementarlo: 1. Agregar en el grid una variable de tipo Combobox y programar las diferentes acciones en el evento Clic de la misma. 2. Definir una imagen o un text block en el grid por cada una de las opciones y programar la acción en el evento clic. 3. Si se utiliza un grid Free Style, puede utilizarse en lugar de una imagen con el evento clic, un botón para cada una de las opciones. 4. Configurar la propiedad AllowSelection del grid. Filtros Si un Web Panel “Trabajar con” tiene variables que se aplican como filtro a los registros desplegados en el grid, al seleccionar un registro y llamar a otro objeto (por ej. Transacción Web) que tiene un Return, se vuelve al Web Panel “Trabajar con” pero se pierden los valores ingresados en los filtros. Para poder mantener el comportamiento de los Work Panels “Trabajar con” se deberían utilizar cookies que almacenen los filtros ingresados. Refresh En Work Panels “Trabajar con”, es común tener un comando Refresh o Refresh keep dentro de un evento, luego de llamar a una Transacción. Cuando estos se convierten a Web Panels “Trabajar con” el Refresh no es necesario, ya que al ejecutar el comando Return hay un Refresh implícito del Web Panel. Por lo tanto, los comandos Refresh y Refresh keep deben ser eliminados de los eventos mencionados anteriormente. PROCESAMIENTO DE VARIAS FILAS EN GRID - FOR EACH LINE SELECTED En Web Panels, no existe la forma de seleccionar con el mouse varias líneas del grid ya que no existe posicionamiento en ninguna parte del form. Para implementar la selección múltiple, se debe definir una variable en el grid y asignarle un valor a cada una de las líneas que se quieren procesar. Luego, se debe usar el comando For each line para procesar cada una de las líneas y filtrar por las que estén seleccionadas (&valor = X). Debe considerarse que se puede utilizar únicamente para invocar a objetos sin interfaz. Si se invoca a otro Web Panel, solamente se ejecuta para el último registro del grid. Para la selección de una línea se cuenta con la propiedad “AllowSelection”. CALL DE UN OBJETO SIN INTERFAZ A OTRO CON INTERFAZ En las aplicaciones GUI puede definirse una cadena de llamadas entre objetos del estilo: Work Panel -> call Procedure -> call Work Panel. En las aplicaciones HTML esto no puede usarse. Las llamadas a un Web Panel solamente pueden realizarse desde otro Web Panel (mediante el call o el link). Por lo tanto, deberá modificarse la programación a algo del estilo: Web panel -> call Procedure -> Call Web Panel INTEGRIDAD TRANSACCIONAL: MANEJO DE UTLS Las Transacciones Web siempre hacen commit, por lo que el manejo de Transacciones anidadas, con la propiedad “Commit on exit” en “No” no se puede lograr. En muchos casos la alternativa es utilizar la lógica del modelo del “Carrito de Compras” USO DE TAB DIALOGS En las aplicaciones GUI, se pueden definir tab dialogs para organizar los datos del form en varias secciones. En las aplicaciones HTML no se tiene este control por lo que será necesario rediseñar el form. Una alternativa puede ser definir un objeto por cada Tab Dialog. Otra alternativa es usar código HTML externo que permite simular estos tabs. MASTER PAGE En las aplicaciones Web se recomienda la utilización de Master Pages, de forma que permita centralizar el diseño y el comportamiento de la aplicación en un solo objeto y reutilizarlo en otros objetos sin requerir programación. Para profundizar en los temas de conversión de aplicaciones GUI-Windows a aplicaciones Web se recomienda acceder a la dirección: http://www.gxopen.com/commwiki/servlet/hwiki?ConversionWinWeb INTRODUCCIÓN En este capítulo veremos GXportal, herramienta que permite diseñar, administrar y mantener portales escalables, sin necesidad de programar. Por lo tanto el usuario de GXportal no necesita tener conocimientos específicos de programación o diseño. GXportal brinda una interfaz Web amigable desde la cual el usuario, en pocos pasos, construye y publica la información en el portal. La practicidad de GXportal asegura la reducción de los costos de desarrollo y mantenimiento, así como también de los tiempos en llevar las nuevas ideas al mercado (time-to-market). GXportal ofrece un marco de trabajo para la integración de conocimiento, información y aplicaciones a través de un portal, buscando unir los distintos actores de la organización y las comunidades. GXportal GXportal permite la integración de su personal, clientes y socios de negocios a través de la Web, compartiendo información y aplicaciones en forma interactiva y segura. GXportal es la herramienta para construir portales para organizaciones que necesitan conectar a sus miembros, socios, y clientes a través de Internet en forma rápida, segura y eficiente. Construido utilizando la tecnología GeneXus, GXportal incorpora vistas de diseño y gestión de contenido independientes, y funciones de gestión automática del contenido y del diseño que lo hacen único dentro de las herramientas de colaboración. GXportal le permite a su organización integrar fácilmente conocimiento, contenido, y aplicaciones, brindando una solución integral para la gestión de su Front End y Back End en la Web. Principales Características SIMPLE La administración de la información del portal puede ser realizada por personal no especializado, accediendo al Back End del portal desde cualquier PC conectado a Internet. El proceso de administración de contenido guía al usuario en el ingreso y mantenimiento de la información. Permite definir dónde y cuándo se publicará el contenido y cuáles son los roles para cada tarea, lo que asegura el manejo confiable de la información. DISEÑO Y CONTENIDO INDEPENDIENTES El contenido y el diseño del sitio se gestionan en forma independiente. El proceso de diseño se basa en plantillas de publicación que se administran en forma independiente del proceso de ingreso y publicación del contenido. Las plantillas son estilos de páginas pre-definidas o definidas por el usuario que se aplican a las páginas del portal. Cuando se modifica una plantilla, en forma automática se modifican las páginas que están basadas en ella. El uso de las plantillas reduce el mantenimiento y tiempo de desarrollo de las páginas del sitio. GESTIÓN AUTOMÁTICA DEL CAMBIO El uso de plantillas y componentes Web hace que la tarea de diseño se concentre en pocas páginas, ya que al modificar una plantilla los cambios se propagan automáticamente a todas las páginas creadas en base a ella. SINGLE SIGN ON El módulo Single Sign On permite la unificación del control de usuarios de GXportal y aplicaciones externas. ARQUITECTURA ESCALABLE GXportal le permite implementar soluciones que van desde un servidor único para base de datos y servidor Web, hasta configuraciones con múltiples servidores en diversas ubicaciones. ADMINISTRACIÓN DE COMUNIDADES GXportal cuenta con las siguientes herramientas para lograr un ámbito de interacción entre los distintos integrantes de las comunidades: • Encuestas • Foros • Listas de noticias • Preguntas Frecuentes SEGURIDAD La seguridad está basada en roles, dependiendo de los roles que tenga asignado el usuario se le presentarán las funcionalidades del Back End a las cuales puede acceder para realizar tareas de administración. Figura 2: Seguridad Gxportal. El acceso a la información dependerá de los roles que se le asignen, es posible restringir el acceso de los usuarios Web a contenidos, menúes, páginas o canales. De esta forma se logra controlar y segmentar el público del portal. Principales Beneficios DISEÑO WEB El primer paso en la creación de un sitio Web efectivo es la creación de páginas visualmente atractivas. El diseño de las páginas Web en GXportal se realiza en forma independiente del contenido y de la funcionalidad del sitio. Los diseñadores Web no necesitan tener conocimientos de programación ni limitaciones funcionales a la hora de diseñar el “look & feel” de su sitio. El diseño se realiza en base a plantillas que pueden ser actualizadas en cualquier momento. Las plantillas son estilos de páginas pre-definidas o definidas por el usuario que se aplican a las páginas del portal. Cuando se modifica una plantilla, el diseño de las páginas que se basan en ella se actualiza en forma automática. El diseño independiente del contenido y el uso de plantillas posibilita la creación sitios cuyo “look & feel” puede evolucionar junto con las necesidades de sus visitantes, al tiempo que reduce drásticamente los costos y tiempos de desarrollo y mantenimiento del sitio. GESTIÓN DE CONTENIDOS El segundo paso en la creación de un sitio efectivo es asegurar que la información que contiene sea correcta, esté actualizada, y sea pertinente para sus visitantes. Las funcionalidades de gestión de contenido de GXportal permiten delegar las tareas de generación de contenido a sus creadores. Para ello, incorpora workflows para gestionar el proceso de creación, edición, y traducción de contenidos, y mecanismos de publicación por fecha, de segmentación de contenidos, y de personalización del sitio por parte de sus visitantes. La gestión de contenidos de GXportal permite obtener un portal totalmente actualizado, sin intervención de técnicos ni procesos de subida de información en los servidores. GESTIÓN DE COMUNIDADES El tercer componente fundamental en la creación de un sitio efectivo es la interacción con sus visitantes. GXportal cuenta con herramientas para lograr un ámbito de interacción óptimo entre los miembros de su comunidad como newsletters, foros de discusión, encuestas, preguntas frecuentes, etc.. Las herramientas de gestión de comunidades de GXportal le permiten interactuar con sus visitantes en forma óptima. INTEGRACIÓN DE APLICACIONES El grado máximo de desarrollo de los sitios es el acceso cualquier aplicación en forma remota y segura a la vez. Los conectores habilitan la integración a sus páginas de componentes externos tales como código HTML, Flash, Javascript, XML, aplicaciones o páginas Web externas y Web services. Descripción del Producto Figura 3: Descripción de GXportal CONTENIDO El módulo de contenido permite administrar y gestionar de forma ágil, segura y ordenada los contenidos que serán publicados en el portal. Guía al usuario en el proceso de ciclo de vida de la información mediante un workflow asegurando la consistencia de los datos en el momento de su publicación. Toda la gestión del contenido se realiza a través de una interfaz Web permitiendo al usuario tener una visión organizada y centralizada de la información independientemente de donde será publicada. DISEÑO GXportal ofrece a través del módulo de diseño una interfaz amigable e intuitiva mediante la cual el usuario, sin necesidad de programar, puede diseñar las páginas del portal. Esta tarea se realiza personalizando cada página, pudiendo reutilizar los diseños de otras. El usuario puede definir sus propias plantillas y asociarle un conjunto de páginas. De esta manera se obtiene una reducción en los costos de mantenimiento y permite que los cambios se hagan de manera rápida, pues los cambios en la plantilla impactan en forma automática en todas las páginas asociadas. COMUNIDAD Las comunidades surgen a partir de los intereses en común que tienen las personas que navegan un sitio. Por lo tanto, el sitio deberá proveer de las herramientas que hacen posible la creación y funcionamiento de las comunidades, como ser: foros de discusión, lista de noticias, preguntas frecuentes, encuestas, etcétera. GXportal cuenta con las herramientas necesarias para lograr un ámbito de interacción entre los distintos integrantes de las comunidades. SEGURIDAD Contar con herramientas de segmentación permite controlar a que tipo de información puede acceder cada usuario y controlar el acceso a determinadas áreas del portal que son privadas y destinadas a determinados usuarios. La seguridad definida por GXportal le permite contar con la definición de roles que desee de manera de poder segmentar el público objetivo de la mejor manera posible y además de contar con el soporte de protocolo seguro que le dé la tranquilidad al usuario de que la información se envía de manera totalmente privada y segura. Tecnologías Soportadas • Plataformas de ejecución: Java, Microsoft .NET • Sistemas Operativos: LINUX, UNIX, Windows 2000/2003 Servers, Windows 2000/XP • Sistemas de Administración de Bases de Datos (DBMS): IBM DB2 UDB, Microsoft SQL Server, Oracle, MySQL • Servidores Web: Microsoft IIS, Apache, WebSphere, etc. Ver la lista actualizada de plataformas soportadas en http://www.gxportal.com/technologies Utilizando GXportal 1. DISEÑO En esta etapa se realiza un análisis con el fin de determinar objetivos del portal, público o comunidades a las cuales se dirigirá el portal, que información se quiere publicar y de que forma se segmentará dicha información. De este análisis se debe obtener lo siguiente: • Visión del portal (modelo de negocio) • Mapa de navegación del portal • Diseño gráfico del portal • Gestión de contenido (workflow) • Arquitectura (hardware y software) 2. CONSTRUCCIÓN Durante esta etapa se trabaja directamente desde el Back End de GXportal definiendo las plantillas de diseño que surgieron del diseño gráfico de la etapa anterior. Luego en base a estas plantillas se crean las páginas del portal basándolas en las plantillas definidas. Además se realiza el ingreso de los contenidos del portal mediante los grupos de usuarios que se definieron y utilizando las herramientas de workflow provistas por GXportal para este cometido. 3. PUESTA EN PRODUCCIÓN DEL PORTAL Una vez que se tiene todo el diseño de las páginas del portal y todo el contenido que se quiere publicar en el portal aprobado se puede realizar la publicación del portal. Para esto simplemente se debe utilizar la herramienta de publicación del portal que permite a través de la acción de un clic publicar todo los componentes de diseño del portal. El contenido debe haber sido autorizado y publicado anteriormente para que el portal muestre toda la información. 4. MANTENIMIENTO DEL PORTAL Cuando una organización comienza a operar el Portal, es necesario hacer un seguimiento postinstalación para asegurarse que el mismo esté siendo bien asimilado. En esta etapa se debe culminar con la capacitación de los usuarios involucrados en la administración del contenido. Y se debe hacer un seguimiento de la evolución del contenido y de los usuarios en el portal para analizar cuales son los cambios a realizar en el portal de manera de estar en constante evolución y poder dar un mejor servicio a través de él. INTRODUCCIÓN Existen otras características interesantes para el desarrollo de aplicaciones Web, que presentamos en este capítulo.       Menú de Opciones Funciones de acceso al header de un objeto Web Manejo HTTP WAP Web Services WebWrapper Menú de Opciones A la hora de crear los menúes de opciones en las aplicaciones Web, básicamente surgen dos formas de implementarlos desde GeneXus. Una de las soluciones posibles es implementarlo con JavaScripts y otra solución es con grids FreeStyle. Siendo la primera la más utilizada hasta el momento. En la siguiente URL www.gxopen.com.uy se pueden bajar proyectos con menúes ya implementados a modo de ejemplo para cualquiera de las dos soluciones. Como otra alternativa se puede contar con Gxportal, herramienta que brinda soluciones para los menúes e incluso Patterns aunque no genera menúes, si genera una serie de links que permiten navegar por toda la aplicación (tanto en el header y como los recents links). Tipo de Datos HttpClient, HttpResponse y HttpRequest Introducción Esta funcionalidad provee a los usuarios GeneXus una forma de poder utilizar el protocolo HTTP en sus programas. Para ello se crearon los tipos de datos HttpClient, HttpResponse y HttpRequest. Descripción Los tres tipos de datos que se definen para interactuar con http son: HttpClient Permite armar un request, enviarlo a una URL y leer los resultados. HttpResponse y HttpRequest Permiten leer los datos del request y grabar el response. Son objetos disponibles sólo en Procedimientos Web. HTTPCLIENT Este objeto refleja una conexión http. Puede usarse desde cualquier objeto GeneXus. Propiedades A continuación se detalla la lista de propiedades: Host Define el nombre del host. Tipo- String Port Define el puerto del host. Tipo- String Secure Indica si el protocolo es http o https. Tipo- Boolean Timeout Determina el Timeout de la conexión. Tipo- Integer BaseURL Indica la URL base de los request que se hagan al host. Tipo- String StatusCode Retorna el código de error HTTP. Tipo- Integer ReasonLine Retorna el texto del error HTTP. Tipo- String ErrCode Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero. Tipo- Integer ErrDescription Retorna el mensaje del error si ocurrió alguno en algún comando. Tipo- String Basic y Digest Son constantes que determinan un tipo de autenticación. Se utilizan en el método AddAuthentication. Basic=0 : Para autentificar se envía el usuario y password sin encriptar. Digest=1: Para autentificar se envía el usuario y password encriptados. ProxyHost y ProxyPort Permiten especificar un proxy http. En ambiente windows se utiliza automáticamente el que esta configurado en la máquina. ProxyHost- String ProxyPort- Integer Métodos AddHeader(<Name>, <Value>) Agrega un header con el valor dado. Ejemplo: AddHeader(“User-Agent”, “GeneXus”) <Name>String <Value>String AddVariable(<Name>,<Value>) Agrega una variable al ‘form’. Ejemplo: AddVariable(“CliCod”, &CliCod) <Name><Value>String String AddString(<Value>) Agrega el contenido del string al buffer de datos a enviar. <Value>String AddFile(<Value>) Agrega el contenido del archivo al buffer de datos a enviar. <Value>String Execute(<Method>,<URL>) Ejecuta un método en la URL definida. Se pondría solo la parte final de la URL Ejemplo: execute("POST", "/servlet/awebproc") <Method>String <URL>String ToString() Retorna un String con todo el “cuerpo” del response. ToFile(<FileName>) Graba en un archivo el contenido del stream. <FileName>- String GetHeader(<Name>,<Value>) Retorna en <Value> el valor del header convertido al tipo de la variable. <Name>String <Value>Anytype AddAuthentication(<Method>, <Realm>, <User>, <Password>) Se autentifica con <User> y <Password> al dominio <Realm> utilizando el tipo de autenticación <Method>. <Method>- Integer (Pueden utilizarse las propiedades Basic y Digest) <Realm>- String <User>- String <Password>- String HTTPREQUEST Este objeto permite leer el request http. Puede instanciarse solo en el contexto de un WebProc. Propiedades Method Retorna el método HTTP. Tipo- String ServerHost Retorna el nombre del servidor Tipo- String ServerPort Retorna el puerto en el servidor Tipo- Integer Secure Indica si se esta utilizando HTTPS. Si el valor retornado es 1, se está utilizando HTTPS; si es 0, se está utilizando http. Tipo- Integer ScriptPath Retorna la porción de URL correspondiente el nombre del directorio virtual. Tipo- String ScriptName Retorna el nombre del objeto con la extensión correspondiente que se esta ejecutando, tal como aparece en la URL. Tipo- String Referrer Retorna la URL del llamador. Tipo-String QueryString Retorna la porción de la URL que está después del signo “?”; o sea los parámetros. Tipo- String RemoteAddress Devuelve la dirección del cliente. Tipo- String ErrCode Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero. Tipo- Integer ErrDescrption Retorna el menaje del error si ocurrió alguno en algún comando. Tipo- String Métodos GetVariable(<Variable>) Retorna en un String el valor con el que viene cargada la <Variable> en el post. <Variable>- String GetHeader(<Header>) Retorna un String con el valor del header <Header>. <Header>String ToString() Retorna un String con todo el ‘cuerpo’ del request. ToFile(<FileName>) Graba en un archivo el contenido del stream. <FileName>- String HTTPRESPONSE Este objeto permite escribir el response http. Puede instanciarse sólo en el contexto de un Procedimiento Web. Propiedades ErrCode Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero. Tipo- Integer ErrDescrption Retorna el menaje del error si ocurrió alguno en algún comando. Tipo- String Métodos AddHeader(<Name>,<Value>) Agrega un header con el valor dado. Ejemplo: AddHeader(“User-Agent”, “GeneXus”) <Name>- String <Value>- String AddString(<Value>) Agrega el contenido del string al buffer de datos a enviar. <Value>- String AddFile(<Value>) Agrega el contenido del archivo al buffer de datos a enviar. <Value>- String INTERACCIÓN CON XML Estos objetos permiten la interacción con los objetos XMLReader y XMLWriter. Para ello existen los siguientes métodos: XMLReader.openRequest(HttpRequest) Se utiliza en un WebProc para leer un xml que viene en el body del http request. XMLReader.openResponse(HttpClient) Se utiliza en cualquier objeto para leer como XML lo que devolvió un request. XMLWriter.openRequest(HttpClient) Se utiliza para enviar un XML en el body de un http request. XMLWriter.openResponse(HttpResponse) Se utiliza en un Procedimiento Web para escribir un XML que se retornara en el body del http response. Ejemplo Este ejemplo muestra como un objeto GeneXus llama a otro vía http, pasándole parámetros en un XML y recibiendo los mismos también en un XML. El XML a enviar tiene la forma: <parameters> <a>valor</a> <b>valor</b> </parameters> El XML que se devuelve es igual, con los valores de ‘a’ y ‘b’ modificados. El programa “cliente” sería: &Client de tipo HttpClient &Writer de tipo XMLWriter &Reader de tipo XMLReader // Determino el host y el puerto a donde hacer el request &client.host = "localhost" &client.port = 88 // Agrego el XML al request &writer.openRequest(&client) &writer.WriteStartElement("parameters") &writer.WriteElement("a", &A) &writer.WriteElement("b", &B) &writer.WriteEndElement() &writer.close() // Hago el POST al webproc &client.execute("POST", "/servlet/awebproc") // Leo el XML que devuelve y lo cargo en las variables internas &reader.openResponse(&client) &reader.read() &reader.read() &a = val(&reader.value) &reader.read() &b = val(&reader.value) &reader.close() El programa “servidor” sería el siguiente Procedimiento Web: &Request de tipo HttpRequest &Response de tipo HttpResponse &Writer de tipo XMLWriter &Reader de tipo XMLReader // Leo los parámetros del XML &reader.openRequest(&Request) &reader.read() &reader.read() &a = val(&reader.value) &reader.read() &b = val(&reader.value) &reader.close() // Le sumo uno a cada valor &a = &a + 1 &b = &b + 1 // Grabo los parámetros en el response &writer.openResponse(&Response) &writer.WriteStartElement("parameters") &writer.WriteElement("a", &A) &writer.WriteElement("b", &B) &writer.WriteEndElement() &writer.close() Consideraciones para el generador Java En el caso de que se ejecute el motor de servlet en Windows, la aplicación obtendrá automáticamente la configuración del proxy http y la lista de hosts para los que no se debe utilizar el proxy. En caso de que se ejecute en otra plataforma, es necesario especificar el proxy como una ‘System Property’ desde la línea de comandos del intérprete, por Ej.: java -Dhttp.proxyHost=your.proxy.com -Dhttp.proxyPort=XX <mainclass> Internet Móvil (WAP) Introducción En los últimos años tanto Internet como la telefonía celular han tenido un gran crecimiento y se han hecho accesibles a millones de personas. Es posible ahora unir estas dos tecnologías accediendo de forma fácil y rápida a la información que brinda Internet desde los teléfonos celulares (ó móviles). GeneXus permite generar salidas para Internet móvil, generando objetos con contenido WML. Esto aplica a Web Panels, generando tanto para Java como .NET. Algunas definiciones WAP (WIRELESS APLICATION PROTOCOL) Es el protocolo más común de Internet Móvil. Internet móvil es el término comercial para acceder a información de Internet a través de dispositivos móviles. Los dispositivos móviles más comunes son los teléfonos celulares con “microbrowser” pero también entran en esta categoría, los dispositivos de tipo palm y cualquier dispositivo de información portátil, que pueda disponer de una conexión inalámbrica. Este protocolo consiste en un modelo de capas que incluyen un IP inalámbrico, capas de seguridad (WSL) y lenguajes de descripción de contenidos entre ellos WML. WML Lenguaje de Tags basado en XML. Es interpretado por los celulares WAP compatibles. Es parecido al HTML, pero tiene menos potencia y soporta algunas cosas que el HTML no y es bastante más estricto en la sintaxis. WML VS HTML Por el tamaño de la pantalla, es imposible traducir o ver de forma satisfactoria una página de Web normal (HTML) en un celular. El tamaño, los tipos de letra, las imágenes y la cantidad de información que se soporta en el Web no se puede soportar en un microbrowser y no es práctico hacerlo. La navegación, además, es diferente, el usuario no tiene mouse, ni teclado por lo que el ingreso de datos debe ser limitado y la navegación, mucho más simple. MICROBROWSER Es un software instalado en el teléfono o dispositivo inalámbrico que interpreta el WML (y el WMLScript, WTAI, etc.) y despliega la información en la pantalla. Es posible acceder a emuladores de celulares y sus microbrowser. Algunos de los más conocidos son UP Browser (Unwired Planet) de Phone.com, RS380 Ericsson, Nokia, etc.. Arquitectura La arquitectura es similar a Internet. El cliente es el teléfono celular con MicroBrowser y en el servidor se encuentra la lógica en objetos (ejecutables o ASP) con contenido WML o sea que al ser interpretados por los browsers generan WML. Descripción Para generar Web Panels con contenido WML, se implementó una nueva propiedad (a nivel de objeto) denominada “Tag Language”. Los valores de la propiedad son:   HTML WML El valor por defecto es HTML para cualquier objeto Internet. Con el valor WML es posible generar objetos con contenido WML, estos podrán ser vistos desde un browser WAP. Requerimientos Para testear esta característica directamente en la máquina de desarrollo es necesario tener instalado el emulador de microbrowser. Recomendamos el UP Browser (UP.SDK version 4.0) que es posible bajarlo de: http://www.openwave.com/products/developer_products/sdk/ El producto es sin cargo, para acceder al mismo se debe realizar la registración en dicha página. El archivo ocupa aproximadamente 7 MB. Diseño Se deben definir los Web Panels como hasta el momento y configurar la propiedad “Tag Language” en “WML”. En el diseño del objeto se deben tener en cuenta las siguientes limitaciones del lenguaje generado (WML):  Los objetos WML están limitados en el tipo y cantidad de controles que se soportan así como en el tamaño de las páginas debido a la cantidad de memoria de los móviles y el tamaño de la pantalla. Las pantallas permiten entre 4 a 8 líneas de texto, dependiendo del móvil, por lo que no se recomienda que las pantallas superen estos tamaños. No es conveniente que se tenga scroll en una pantalla de teléfono celular. Sólo se soportan los siguientes controles: o o o o o   Edit Textblocks Texto libre Tablas simples Grids Free Style simples  No se soportan: o o Variables dentro de tablas Ninguna anidación de tablas y/o grids Free Style o o o o o o o  Grids estándar Campos LongVarchar La letra ñ Tag <BR> Botones Cookies Encriptación de parámetros Las propiedades de runtime soportados son: o o o o Link Ispassword Visible Enabled  El softbutton del teléfono (botón que se encuentra en la parte superior izquierda), se asocia al Evento Enter. Ejecución Luego de generado el objeto se debe ejecutar desde el emulador celular, esto se realiza escribiendo la dirección donde se encuentra el Web Panel en la barra de direcciones del mismo. Ejemplo Se desea desplegar un texto de prueba en un teléfono celular, los pasos a seguir son los siguientes: 1. Insertar el texto en un textblock en el form de un Web Panel. Es aconsejable verificar el código generado, en el Tab “Source”, teniendo en cuenta las consideraciones. 2. 3. 4. Especificar, generar y compilar el Web Panel desde GeneXus. Ejecutar el UP.Simulator. Escribir la dirección donde se encuentra el objeto (por ej. http://localhost/cgibin/hPrueba.exe) en “Go”, y presionar Enter o el Softbutton. 5. En el teléfono celular se visualizará el texto ingresado en el Web Panel. 6. Si se producen errores en la pantalla del teléfono celular siempre se despliega el siguiente mensaje: “Compile error: See info windows for details.” El texto completo del error se debe visualizar en el “Phone information’” (ventana DOS que se ejecuta detrás del emulador). Hay un ejemplo disponible en : http://www.gxtechnical.com/main/Hdcenter.aspx?2,5,36,408 Errores comunes Error “Error : Invalid element ‘PCDATA’ in contents of card.” “Error : Invalid element ‘br’ in contents of card.” “Error : Uncompiled data from http <head>.” Síntoma Se debe a la ausencia de <P> en textblock o variable. Se debe a un tag <BR> en el Source del objeto La página no es WML es HTML, se debe configurar la preference ‘Tag Language=WML’ Se esta usando un longvarchar o un char de varias líneas. Hay algún dato con la letra ñ y el microbrowser no lo puede interpretar. Se introdujo algun tag <P> anidado, esto no es válido en WML “Error : Invalid element ‘textarea’” “Error : Missing entity “ntilde” “Error : Invalid element ‘P’ in content of ‘p’. excpectde PCDATA | em | b …” Consideraciones Consideraciones a tener en cuenta con el editor:  El editor no toma en cuenta algunas restricciones necesarias para WML y puede generarse código no válido, es preciso en estos casos modificar el source en el editor de diseño de GeneXus.  No es posible hacer cut & paste de controles y/o del Source.  Existen algunos Tags HTML (no válidos en WML) generados por el editor. Por ejemplo el Tag <BR> es generado por la combinación de teclas Shift+Enter en el editor.  Textblock y variables deben generarse entre <P> y </P>. La generación de estos Tags se da con un enter al final del edit o modificando Código en el Tab “Source”.  Grids o tablas no deben limitarse por tags <P>. Es posible generar este código con algunas combinaciones de teclas.  Igualmente no es recomendable modificar el código WML (bajo el tab “HTML Source” ) pues pueden dar errores en ejecución.  No se reciben correctamente variables por parámetro en los llamados realizados mediante “call”. INTRODUCCIÓN Cada vez se escucha más el concepto de “Web Services”, fundamentalmente relacionado con Internet y el futuro de una arquitectura orientada a servicios. Es por esta razón, que GeneXus incluye la posibilidad de desarrollar y consumir Web Services. Comenzaremos con una introducción al concepto de Web Services para luego realizar ejercicios prácticos que permitan profundizar los conocimientos adquiridos. Web Services En los últimos tiempos ha surgido con mucha fuerza el concepto de Web Services, incluso afirmándose que el mismo cambiaría la forma de programar las aplicaciones orientadas a Internet hacia una arquitectura orientada a servicios. Todo esto se ha visto potenciado luego del anuncio de Microsoft de su nueva estrategia .NET que está basada en el modelo de Web Services. Este documento describe qué son los Web Services y cómo es la arquitectura general del modelo, adicionalmente se provee una introducción de los estándares en los cuales se basa este modelo como ser SOAP, WSDL y UDDI. ¿Qué es un Web Service? Un Web Service es una aplicación que puede ser descripta, publicada, localizada e invocada a través de una red, generalmente Internet. Combinan los mejores aspectos del desarrollo basado en componentes y la Web. Al igual que los componentes, los Web Services son funcionalidades que se encuentran dentro de una caja negra, que pueden ser reutilizados sin preocuparse de cómo fueron implementados. A diferencia de la actual tecnología de componentes, no son accedidos por medio de protocolos específicos del modelo de objetos como ser RMI, DCOM o IIOP; sino que son accedidos utilizando protocolos Web como ser HTTP y XML. La interface de los Web Services está definida en términos de los mensajes que el mismo acepta y retorna, por lo cual los consumidores de los Web Services pueden ser implementados en cualquier plataforma y en cualquier lenguaje de programación, sólo tiene que poder crear y consumir los mensajes definidos por la interface de los Web Services. El modelo de Web Services La arquitectura básica del modelo de Web Services describe a un consumidor, un proveedor y ocasionalmente un corredor (broker). Relacionados con estos agentes están las operaciones de publicar, encontrar y enlazar. La idea básica consiste en que un proveedor publica su servicio en un corredor, luego un consumidor se conecta al corredor para encontrar los servicios deseados y una vez que lo hace se realiza un lazo entre el consumidor y el proveedor. Cada entidad puede jugar alguno o todos los roles. Por todo lo anterior hay ciertos requerimientos a la hora de desarrollar o consumir un Web Service:  Una forma estándar de representar los datos XML es la opción obvia para este requerimiento.  Un formato común y extensible de mensajes SOAP es el elegido en este caso; SOAP es un protocolo liviano para el intercambio de información. Más adelante en este documento lo veremos con más detalle.  Un lenguaje común y extensible para describir los servicios La opción en este caso es WSDL. Es un lenguaje basado en XML desarrollado en forma conjunta por IBM y Microsoft. Lo veremos con más detalle más adelante en este documento.  Una forma de descubrir los servicios en Internet UDDI se utiliza en este caso; el mismo especifica un mecanismo para publicar y localizar los servicios por parte de los proveedores y consumidores respectivamente. Se verá con más detalle más adelante en este documento. Ventajas y retos Los Web Services apuntan a ser la piedra fundamental de la nueva generación de sistemas distribuidos. Estos son algunos puntos para fundamentar esta afirmación:  Interoperabilidad Cualquier Web Service puede interactuar con otro Web Service. Como los Web Services pueden ser implementados en cualquier lenguaje, los desarrolladores no necesitan cambiar sus ambientes de desarrollo para producir o consumir Web Services.  Ubicuidad Los Web Services se comunican utilizando HTTP y XML. Por lo tanto cualquier dispositivo que soporte estas tecnologías puede implementar o acceder Web Services. Muy pronto estarán presentes en teléfonos, autos e incluso máquinas expendedoras, las que avisarán a la central cuando el stock sea menor al indicado.  Encapsular reduce la comlejidad Todos los componentes en un modelo de Web Services son Web Services. Lo importante es la interface que el servicio provee y no cómo está implementado, por lo cuál la complejidad se reduce.  Fácil de utilizar El concepto detrás de los Web Services es fácil de entender, incluso existen toolkits de vendedores como IBM o Microsoft que permiten a los desarrolladores crear Web Services en forma rápida y fácil.  Soporte de la Industria Todas las empresas de software importantes soportan SOAP, e incluso están impulsando el desarrollo de Web Services. Por ejemplo la nueva plataforma de Microsoft .NET está basada en Web Services, haciendo muy simple el desarrollo de los mismos que luego podrían ser consumidos por un Web Service desarrollado utilizando VisualAge de IBM y viceversa. A la vez hay ciertos retos técnicos que los Web Services tienen que sortear para poder tener éxito. Muchos de estos retos están relacionados con el ambiente abierto en el que tienen que sobrevivir. Estos son algunos de esos puntos:  Descubrimiento ¿Cómo se anuncia un Web Service para ser descubierto por otro servicio? ¿Qué pasa si el servicio se cambió o se movió luego de ser anunciado? WSDL y UDDI son dos nuevos estándares que manejan este punto. Confiabilidad Algunos Web Services son más confiables que otros. ¿Cómo puede ser medida esa confiabilidad y comunicada? ¿Qué pasa cuando un Web Service está off-line en forma temporaria? ¿Localizamos y utilizamos un servicio alternativo brindado por otra empresa o esperamos a que el servicio esté de nuevo on-line? Seguridad Muchos Web Services son publicados para ser utilizados sin ninguna restricción, pero muchos otros van a necesitar autenticación para que los utilicen sólo los usuarios autorizados. ¿Cómo autentifica a los usuarios un Web Service? ¿Lo hace a nivel del método que lo implementa o utiliza otro Web Service para realizar la autenticación? Responsabilidad En caso de que el Web Service no sea de acceso libre, ¿Cómo puedo definir cuántas veces un consumidor puede acceder al Web Service una vez contratado? ¿Cómo se cobra su uso? ¿Cómo se indica que un servicio ya no está más en línea?    Tecnologías asociadas El modelo de Web Services está basado en ciertas tecnologías emergentes que es el resultado del trabajo de varias compañías y organizaciones entre las cuales se destacan IBM y Microsoft. Estas tecnologías son SOAP, WSDL y UUDI. SOAP (SIMPLE OBJECT ACCESS PROTOCOL) SOAP es un protocolo para el intercambio de información en un ambiente descentralizado y distribuido. Es el protocolo más utilizado para realizar el intercambio de información en el modelo de Web Services. Está basado en XML y potencialmente puede ser utilizado en combinación con una variedad de protocolos de comunicación, siendo el más utilizado HTTP. Por lo tanto se utiliza HTTP para transportar la información, y XML para representar la misma. El protocolo completo se puede encontrar en http://www.w3.org/TR/soap El modelo de comunicación de SOAP El modelo de comunicación de SOAP es muy similar al de HTTP. Un cliente hace un requerimiento (request), el servidor que está escuchando los requerimientos lo atiende y responde (response) brindando la información solicitada o enviando un mensaje de error en caso de que el requerimiento no haya sido válido. El mensaje SOAP consiste en un elemento envelope SOAP obligatorio, un cabezal SOAP opcional y un cuerpo SOAP obligatorio como un documento XML. El cabezal SOAP es utilizado para definir información acerca del requerimiento, mientras que el cuerpo SOAP contiene el método llamado y los parámetros con los que se llama al mismo. Todo esto es un modelo de mensajes request/response con una forma de describir un conjunto de métodos y pasarle a los mismos parámetros. Esto parece la base del protocolo RPC y de hecho es el uso más común de SOAP. El potencial es entregar esto sobre Internet utilizando HTTP para realizar comunicaciones entre organizaciones permitiendo realizar comunicaciones entre aplicaciones con diferente plataforma, sistema operativo y lenguaje de programación. A continuación se muestra un mensaje SOAP embebido en un request HTTP: Este ejemplo invoca al servicio StockQuote llamando al método GetLastTradePrice con el símbolo DIS por parámetro. Esta es la respuesta al requerimiento anterior, el cual retorna el precio de la acción solicitada: Si usted quedó asustado por la aparente complejidad del protocolo SOAP pensando lo engorroso que sería armar los mensajes de requerimiento y parsear los mensajes de respuesta despreocúpese; la mayoría de los lenguajes de programación proveen o proveerán soporte para realizar esto. La idea fundamental consiste en utilizar algún objeto al cual se le brinda un WSDL y se le indica qué método se quiere llamar y con qué parámetros. Esto arma en tiempo de ejecución el mensaje SOAP, lo manda y parsea el resultado adjudicándoselo a alguna variable en forma trasparente para el usuario como si hubiera hecho un call común. WSDL: WEB SERVICES DESCRIPTION LANGUAGE WSDL es un lenguaje basado en XML que se utiliza para describir un Web Service. Ha sido suministrado por la W3C por estandarización. Un archivo con formato WSDL provee información de los distintos métodos (operaciones) que el Web Service brinda, muestra cómo accederlos y qué formatos deben de tener los mensajes que se envían y se reciben. Es como un contrato entre el proveedor del servicio y el cliente, en el cual el proveedor se compromete a brindar ciertos servicios sólo si el cliente envía un requerimiento con determinado formato. Es el documento principal a la hora de documentar un Web Service, pero puede no ser el único. En la mayoría de los casos es conveniente que esté acompañado por un documento escrito en lenguaje natural que brinde información de qué es lo que hace cada uno de los métodos brindados por el Web Service así como también ejemplos, tales como los mensajes SOAP que espera y responde el servicio. En forma resumida podríamos decir que un archivo WSDL describe lo siguiente:    Mensajes que el servicio espera y mensajes que el servicio responde. Protocolos que el servicio soporta. A dónde mandar los mensajes. Formato de un archivo WSDL A continuación se muestra cómo es el formato básico de un archivo WSDL. La especificación completa de este lenguaje se puede encontrar en http://www.w3.org/TR/wsdl.html. Un archivo con formato WSDL básicamente contiene los siguientes elementos: Type: Describe los tipos no estándar usados por los mensajes (Message). Message: Define los datos que contienen los mensajes pasados de un punto a otro. PortType: Define una colección de operaciones brindadas por el servicio. Cada operación tiene un mensaje de entrada y uno de salida que se corresponde con algún Message antes definido. Binding: Describe los protocolos que se utilizan para llevar a cabo la comunicación en un determinado PortType; actualmente los protocolos soportados son SOAP, HTTP GET, HTTP POST y MIME, siendo SOAP el más utilizado. Port: Define una dirección (URL) para un determinado Binding. Service: Define una colección de Ports. El siguiente es un ejemplo de archivo WSDL: El mismo define dos mensajes (Simple.foo y Simple.fooResponse), luego define un método llamado “foo” el cual recibe el mensaje Simple.foo y retorna el mensaje Simple.fooResponse. A continuación se define un binding para el método foo asociándolo con el protocolo SOAP. Por último se da una URL física que implementa lo antes descrito. Interfaz e implementación La estructura básica de archivo con formato WSDL podría ser dividido en dos partes lógicas: la interfaz del servicio, y la implementación del mismo. Esta división lógica divide los elementos de la siguiente forma: Interfaz del servicio Type, Message, PortType, Binding. Contiene una definición abstracta y reusable del servicio que puede ser instanciada y referenciada por distintos proveedores del mismo. Implementación del servicio Port, Service. Contiene una implementación de una determinada Interfaz del servicio. A partir de esta división lógica se puede definir por medio de una Interfaz del servicio un estándar para realizar, por ejemplo, órdenes de compras que puede ser reutilizada e implementada por todas las empresas, sin tener que redefinir cada una de ellas la interfaz. Si al igual que con SOAP se siente preocupado por la complejidad de los archivos WSDL de nuevo despreocúpese; la mayoría de los lenguajes de programación proveen o proveerán herramientas para generar en forma automática el archivo WSDL a partir de un determinado método o función. UDDI (UNIVERSAL DESCRIPTION, DISCOVERY AND INTEGRATION) UDDI (www.uddi.org) es un proyecto inicialmente propuesto por Ariba, Microsoft e IBM; es un estándar para registrar y descubrir Web Services. La idea es que las distintas empresas registran su información acerca de los Web Services que proveen para que puedan ser descubiertas y utilizadas por potenciales usuarios. La información es ingresada al registro de empresas UDDI, un servicio lógicamente centralizado, y físicamente distribuido a través de múltiples nodos los cuales replican su información en forma regular. Una vez que una empresa se registra en un determinado nodo del registro de empresas UDDI la información es replicada a los otros nodos y queda disponible para ser descubierta por otras empresas. El esquema UDDI El modelo de información base utilizado por los registros UDDI es definido en un esquema XML. Este esquema define cuatro tipos básicos de información, cada uno de los cuales proveen la clase de información que un usuario necesita saber para utilizar un Web Service de otra empresa. Los cuatro tipos de información son:  Información del negocio Este tipo de información está definido en el elemento businessEntity. Contiene información de la empresa, como ser su nombre, los contactos, el tipo de empresa, etc.  Información del servicio Dentro del elemento businnessEntity se encuentran los elementos businessServices, estos elementos contienen información sobre Web Services generalmente agrupados por procesos de negocio o categorías de servicios.  Información del enlace (binding) Dentro de cada elemento businessServices se encuentran los elementos bindingTemplate. Cada uno de ellos brinda una dirección fisica para hacer contacto con los servicios descriptos anteriormente.  Información sobre las especificaciones del servicio Cada bindingTemplate tiene asociado un tModel, el cual brinda informacíon sobre las especificaciones del servicio, por ejemplo, cómo tienen que ser los mensajes que el servicio espera y responde, etc. Un tModel puede ser asociado con elementos bindingTemplate de distintas empresas que brindan la misma especificación del servicio. Utilizando entonces los tModels se pueden encontrar todas las empresas que brindan tal servicio. Por más información sobre el esquema UDDI: http://www.uddi.org/pubs/ProgrammersAPI_v2.pdf API UDDI El acceso al registro UDDI, ya sea para realizar búsquedas o para ingresar o modificar un registro, se puede realizar a través de una página Web que implemente el acceso o utilizando ciertas interfaces (Web Services) que provee la especificación de UDDI. Estas interfaces están descriptas en una API, que puede ser dividida en dos partes lógicas, la API de consultas y la API de publicación. Por más información sobre la API UDDI: http://www.uddi.org/pubs/ProgrammersAPI_v2.pdf Un ejemplo Las formas en que se pueden realizar negocios utilizando Web Services son muy variadas. El consumidor podría pagar por utilizar los servicios brindados por un proveedor, o el proveedor podría pagar para que aparezcan los servicios que él ofrece en un determinado consumidor, o incluso existen casos en los cuales ni el consumidor ni el proveedor pagan por consumir o proveer los servicios en forma respectiva. Este es el caso que se presenta a continuación. El ejemplo es tomado de la vida real y es sobre la compañía aérea Southwest. En su portal http://www.southwest.com/ , esta compañía aérea permite hacer reservas de boletos, pero además como valor agregado a los clientes permite hacer reservas de hoteles y reservas de alquileres de autos. Los datos para poder realizar estas reservas están tomados de Web Services que brindan los distintos hoteles y rentadoras de autos. Este es un ejemplo de uso de Web Services en el cual ni el consumidor ni los proveedores pagan; a ambos les sirve este intercambio ya que la compañía de aviones le brinda un valor agregado a sus clientes, y los hoteles y rentadoras de autos están expuestos a ser contratos por potenciales clientes. Es más, estas empresas no publicaron sus servicios para que fueran exclusivamente utilizados por la compañía aérea, sino que los mismos pueden ser descubiertos y utilizados por cualquier empresa que los necesite. Claramente se muestra en este ejemplo el gran poder de los Web Services, y la ventaja que tendrán las empresas que los sepan utilizar en forma adecuada con respecto a las otras. Imagínese en este caso si usted fuera a reservar boletos de avión y pudiera elegir por una compañía que además de reservar los boletos le permitiera hacer la reserva de hotel, y otra que no; ¿por cual haría la reserva? Por otro lado imagine que usted es dueño de una rentadora de autos y sabe que su competencia está brindando sus servicios en un portal de una compañía aérea y usted no, ¿qué haría? XML Introducción Hoy en día, se pueden encontrar muchísimos sitios Web que brindan servicios on-line como por ejemplo reservas de asientos para espectáculos, aviones, reportes meteorológicos, etc.; para poder brindar estos servicios a los usuarios, los diseñadores y los programadores Web deben combinar los datos y la presentación en un documento HTML. Muchas veces el proveedor de determinada información no es quien la va a “procesar” (sea esto publicarla en un sitio, ingresarla en una aplicación, etc). La necesidad de generar grandes cantidades de datos dinámicos y complejos por un lado y la necesidad de procesarlos y publicarlos por otro, han provocado la definición de un formato de datos universal: XML. Descripción La idea principal detrás de XML es el desarrollo de un lenguaje estándar de etiquetas (similar a HTML) para describir datos en forma estructurada. Este lenguaje debe poder ser interpretado tanto por computadoras como por seres humanos. Si una aplicación en el servidor del servicio meteorológico graba un documento XML con el reporte del tiempo y luego otro sitio Web puede leer dicho documento, se puede publicar el estado del tiempo en forma automática, sin necesidad de ingresarlo dentro de la aplicación del sitio Web cada día o convertir la información recibida. El lenguaje XML está compuesto por etiquetas que describen el contenido del documento. Un elemento XML queda definido por una etiqueta de comienzo y otra de fin con el valor del elemento entre ambas etiquetas. Los elementos pueden estar anidados y además pueden contener en forma opcional, uno o más atributos. Los atributos son usados para adjuntar información secundaria a los elementos. A continuación se visualiza un ejemplo de un documento XML: <weather-report> <date>March 25, 2000</date> <time>08:00</time> <area> <city>Montevideo</city> <country>Uruguay</country> </area> <measurements> <skies>partly cloudy</skies> <temperature>26</temperature> <wind> <direction>SW</direction> <windspeed>6</windspeed> </wind> <humidity>87</humidity> <visibility>10</visibility> </measurements> </weather-report> El ejemplo anterior está compuesto únicamente por elementos XML, pero el mismo podría redefinirse, de forma que la información correspondiente al área estuviese representada por atributos, como se representa a continuación: <weather-report city=Montevideo country=Uruguay> <date>March 25, 2000</date> <time>08:00</time> <measurements> <skies>partly cloudy</skies> <temperature>26</temperature> <wind> <direction>SW</direction> <windspeed>6</windspeed> </wind> <humidity>87</humidity> <visibility>10</visibility> </measurements> </weather-report> Si bien el hecho de estar compuesto por etiquetas hace que sea parecido a HTML, hay una diferencia muy importante: en un documento XML no hay información acerca de cómo deben ser presentados los datos. Así, como HTML provee etiquetas específicas para formatear un documento, XML provee un marco para crear etiquetas. Resumiendo, XML es un lenguaje estándar definido por el Consorcio World Wide Web para permitir grabar y leer datos en forma estructurada con formato estándar independiente de aplicaciones y vendedores. En GeneXus, se cuenta con funciones para el manejo de XML: XMLWriter, XMLReader. Protocolo SOAP Introducción SOAP es un protocolo “liviano” basado en XML, para invocar procedimientos en forma remota (Remote Procedure Call). Utiliza cualquier protocolo que permita transportar mensajes de texto, siendo HTTP el más utilizado. Su especificación describe el contenido que debe tener un mensaje XML para ser usado en una invocación remota. Cualquier aplicación que cumpla la especificación puede invocar y proveer servicios sin importar en que lenguaje o plataforma esté implementado, lo único necesario es que la aplicación sea capaz de interpretar el mensaje SOAP que recibe, realizar el procesamiento que el mensaje requiera, y devolver otro mensaje SOAP con la respuesta. En las aplicaciones generadas por GeneXus se utiliza SOAP para invocar a objetos en forma remota, usando HTTP como protocolo de transporte. Alcance OBJETOS LLAMADORES (CLIENTES) Aplica a todos los objetos, generando tanto para Java como para .NET. Los objetos llamadores son los que invocan servicios mediante SOAP. OBJETOS LLAMADOS (SERVIDORES) Aplica a los objetos: Procedimientos y Reportes, generando tanto para Java como para .NET. Los objetos llamados son los que brindan un servicio invocado mediante SOAP. Descripción Algunas de las ventajas de utilizar este protocolo en aplicaciones GeneXus son la posibilidad de desarrollar servicios Web, así como el poder hacer invocaciones entre objetos de diferentes generadores (por ej. llamar desde Java a .NET). Servidor Para indicar en GeneXus que un objeto main va a ser llamado utilizando el protocolo SOAP, se deberá seleccionar el valor “SOAP” en la propiedad “Options/Call Protocol”. Nos referiremos en adelante a dichos objetos como “Servidores” o “Servicios Web”. Solo pueden ser reportes o procedimientos, sin ningún tipo de interfaz con el usuario. Se requiere un servidor Web que haga el hosting de los servicios a ser invocados. Los programas Servidores reciben la invocación http, procesan el mensaje SOAP que envía el Cliente con sus parámetros, realizan la acción requerida, y generan otro mensaje SOAP de respuesta (eventualmente con los parámetros modificados). Cliente Los objetos que van a invocar al servicio Web, a los que llamaremos “Clientes”, pueden ser cualquier objeto GeneXus. La invocación se hace con el comando call() de GeneXus. Los programas Clientes realizan las tareas necesarias para ensamblar el mensaje SOAP, hacer la invocación http, y desensamblar la respuesta, obteniendo los parámetros modificados en forma automática. Todo esto se realiza en forma automática y transparente para el usuario. Locations Para indicar cual va a ser la ubicación de los servicios invocados se utiliza un esquema conocido como Locations. Manejo de errores COMPORTAMIENTO FRENTE A UN ERROR Si al hacer un llamado SOAP desde un objeto GeneXus se produce un error, normalmente la ejecución del llamador se cancelará mostrando el error que ocurrió. Si el objeto llamado es un procedimiento o reporte GeneXus, es posible indicar que se detenga la ejecución de los programas llamadores en caso de fallar la llamada. Esto se hace mediante la propiedad “Cancel Caller Execution on Error”: Esta propiedad se habilita solamente cuando la propiedad “Call Protocol” tiene el valor “SOAP”. El valor por defecto es “Yes”. De tener valor “No”, la ejecución no se cancelará y se podrá obtener el código numérico de error con la función GetSOAPErr(), y el mensaje de error mediante la función GetSOAPErrMsg(). CÓDIGOS DE ERROR EN EL CLIENTE Los posibles códigos de error que pueden ser retornados mediante la función GetSOAPErr() son los siguientes:   0: Operación completada con éxito. Mayor que 0 y menor que 10000: Algún parámetro retornado por el servidor no tiene el nombre esperado. El código de error indica la posición del parámetro que ocasionó el conflicto. Menor que 0 y mayor que -10000: Sucedió un error al interpretar el XML de respuesta. Sucederá por lo general si la respuesta no es XML o no es XML bien formado. Si se toma el valor absoluto del código de error el resultado corresponderá a un código de error del objeto XMLReader. De todas formas, getSOAPErrMsg() retornará una descripción del error.   Menor que -10000: Sucedió un error en la comunicación HTTP. Si se toma el valor absoluto del código de error y se le resta 10000 el resultado corresponderá a un código de error del objeto HTTPClient. De todas formas, getSOAPErrMsg() retornará una descripción del error. -20001: La respuesta recibida es un XML válido pero no es un mensaje SOAP válido. -20004: El servidor retornó que hay un error en el pedido SOAP realizado por el cliente. En este caso getSOAPErrMsg() retornará un mensaje conteniendo el código y el mensaje de error retornados por el servidor. Si el servidor es un procedimiento o reporte GeneXus, retornará alguno de los códigos de error descriptos más abajo. -20006: Sucedió un error no identificado. En este caso getSOAPErrMsg() retornará un mensaje conteniendo el código y el mensaje de error retornados por el servidor. -20007: Nombre de location no válido. Sucede cuando se llama a la función GetLocation(Nombre) con un nombre de location que no está definido para ningún objeto en la base de conocimiento.     CÓDIGOS DE ERROR EN EL SERVIDOR Un procedimiento o reporte GeneXus que es llamado mediante SOAP puede retornar alguno de los siguientes códigos de error:   -20000: No se recibió un mensaje SOAP. -20001: El mensaje recibido es un XML válido pero no es un mensaje SOAP válido (igual que en el cliente). -20002: El método llamado no es el esperado. (El método SOAP de los objetos GeneXus siempre se llama “Execute”).  CONSUMIDORES A WEB SERVICES EXTERNOS El WSDL Inspector permite importar la definición del servicio que se desea consumir. Por más detalles ver WSDL Inspector. Web Services con GeneXus A continuación se detallan los mecanismos para proveer y consumir Web Services con GeneXus. Proveer Para proveer Web Services con GeneXus se debe definir un objeto Procedimiento o Reporte, que debe ser de tipo main, y asociado a un generador Web. Se debe configurar la propiedad de objeto “Call protocol” con el valor “SOAP”. Se debe publicar el objeto en un servidor Web, con lo que el Web Service queda operativo para ser invocado. El WSDL del servicio queda disponible agregando el parámetro wsdl a la URL del mismo. Por ejemplo: http://server/baseurl/aservice.aspx?wsdl Consumir Se utiliza el WSDL Inspector, que permite importar la definición del servicio que se desea consumir. Se debe indicar el WSDL del mismo, y el utilitario definirá los tipos de datos necesarios para poder consumirlo desde GeneXus. En el caso de que el Web Service utilice tipos de datos estructurados, los mismos serán agregados a la base de conocimiento al importar la definición con el WSDL Inspector. Además, es necesario configurar la propiedad de objeto Location. Esto servirá luego para configurar, en los objetos GeneXus que vayan a invocar al Web Service, la ubicación del mismo (host, port, etc.). Práctico: Creación de Web Service Genexus En esta sección crearemos un Web Service GeneXus, y veremos como consumirlo desde una aplicación GeneXus. Supongamos que quisiéramos publicar un servicio de nuestro sitio Web, por ejemplo un ranking con los 10 destinos más elegidos. Vamos a definir entonces un Web Service al que llamaremos “Ranking”. Lo primero es definir un SDT con las siguientes características, que nos permita almacenar la información de los destinos que nos interesa publicar: Nombre: Destinationsdt Structure Type CountryId CountryName CityId CityName Identifier Character(20) Identifier Character(20) Destinationsdt será una Collection. Para programar el procedimiento “Ranking” se recorre la tabla COUNTRIES1 en forma descendente por CityQtity, que indica para una ciudad de un país en particular, qué cantidad de veces que ha sido elegida en vuelos que la tienen como ciudad destino. De esa forma, obtendremos las 10 más elegidas. Definiremos una variable que nos permita contar la cantidad de ciudades: &Qty, más una variable que permita almacenar toda la colección de destinos más elegidos (Destination) junto con una variable que cargue cada uno de los items de esa colección de destinos (DestinationItem). Las variables a definir entonces son las siguientes: Name Type Qty Destination DestinationItem N(2) S(Destinationsdt) S(Destinationsdt.DestinationsdtItem) &Qty = 1 for each (CityQtity) &DestinationItem.CityId = CityId &DestinationItem.CityName = CityName &DestinationItem.CountryId = CountryId &DestinationItem.CountryName = CountryName &Destination.Add(&DestinationItem) &DestinationItem = new Destinationsdt.DestinationsdtItem() &Qty +=1 if &Qty > 10 exit endif endfor Rules: parm(out:&Destination); Resulta necesario que el procedimiento sea main, y configurar la propiedad “Call protocol” con el valor “SOAP”. Luego de generar y compilar el procedimiento Ranking, verifique el Web Service generado automáticamente por GeneXus, digitando la siguiente URL en el browser: http://localhost/practico/aranking.aspx?wsdl Creación del Consumidor del Web Service A continuación crearemos un Web Panel que será el consumidor del Web Service “Ranking” recientemente creado. En general un Web Service será externo a la base de conocimiento, por lo cual vamos a crear una nueva base de conocimiento para crear ese Web Panel al que llamaremos ViewRanking. Como se describe a continuación. 1. Creación de una nueva base de conocimiento, de nombre “Consumer”. 2. Desde diseño, ejecutar el WSDL Inspector: Tools / WSDL Inspector. En “Web service URL” colocar la siguiente URL http://localhost/practico/aranking.aspx?wsdl y luego hacer clic en el botón “Inspect”· Observe que el método del Web Service es “Execute” y el tipo de datos que devuelve es “Destinationsdt”. Cuando se hace clic en el botón “Add Reference” se definen los tipos de datos además de toda la información necesaria para poder consumir el Web Service. Pasar a prototipo forzando el impacto. 3. Creación del Web Panel ViewRanking, para eso definiremos las siguientes variables: Name Type CityId CityName CountryId CountryName Destination DestinationItem Rank Character(3) Character(20) Character(3) Character(20) S(Destinationsdt) S(Destinationsdt_DestinationsdtItem) O(org_tempuriaction_.Ranking) Observe que los tipos de datos Destinationsdt (colección de destinos), Destinationsdt_DestinationsdtItem (cada item de la colección) y org_tempuriaction_.Ranking (Web Service) se crearon automáticamente al inspeccionar el servicio con el WSDL Inspector. El form del Web Panel ViewRanking contendrá un grid con las variables &CityId, &CityName, &CountryId y &CountryName. Y se deberá programar los eventos Refresh y Load del Web Panel, como se muestra a continuación: Event Refresh &Destination = &Rank.Execute() //aquí se invoca la ejecución del Web Service y se carga la colección en la variable &Destination EndEvent // Refresh Event Grid1.Load for &DestinationItem in &Destination //se recorre la colección y se carga el grid &CityId = &DestinationItem.CityId &CityName = &DestinationItem.CityName &CountryId = &DestinationItem.CountryId &CountryName = &DestinationItem.CountryName load endfor EndEvent // Grid1.Load Ejecute el Web Panel ViewRanking y observe como se obtiene la información requerida. Demo: Cómo consumir un Web Service externo Una de las características interesantes de los Web Services, es que podemos agregar valor a nuestro sitio Web, sin necesidad que el usuario deba ir a otro sitio. Es importante evitar “perder” el usuario al llevarlo a otras páginas Web. Lo que queremos ver en esta sección es como incluir un Web Service externo no GeneXus en nuestra aplicación (ya hemos visto en este capítulo un ejemplo de como crear y consumir un Web Service hecho con GeneXus). Lo que haremos es importar un Web Service que provée Google. Google es una compañía especializada en la búsqueda de información en la Web. En su página Web (http://www.google.com) se puede ingresar una lista de palabras por las cuales buscar y retorna todos los sitios Web en las cuales encontró esas palabras. Esta misma funcionalidad Google la provee por medio de un Web Service. El WSDL de dicho Web Service es: http://api.google.com/GoogleSearch.wsdl El WSDL Inspector permite a partir del WSDL de un Web Service definir los tipos de datos necesarios en GeneXus para poder consumir el Web Service en forma transparente, sin tener que preocuparse de los protocolos involucrados en el proceso y la definición del mismo. Entonces, el procedimiento a seguir para incluir el Web Service de Google en el sitio Travel Agency es el siguiente: 1. 2. 3. Ejecutar el WSDL Inspector (Tools / WSDL Inspector en el modelo de diseño). En “Web Service URL” ingresar: http://api.google.com/GoogleSearch.wsdl Presionar el botón “Inspect”. Notar que el WSDL Inspector determinó que el Web Service tiene los siguientes métodos: doGetCachedPage, doSpellingSuggestion y doGoogleSearch (este último es el que luego vamos a consumir). Notar en el costado inferior izquierdo los tipos de datos complejos que va a crear GeneXus para consumir el Web Service en forma adecuada. 4. 5. 6. Presionar el botón “Add Reference” para que GeneXus cree en la base de conocimiento todo lo necesario para consumir el Web Service. Cerrar el WSDL Inspector. Impactar el modelo de diseño. Haga clic aquí para ver la demostración A continuación es necesario consolidar el “GoogleSearch.xpz”, que contiene el Web Panel GoogleSearch donde vamos a consumir el Web Service de Google. En ese Web Panel, crear las siguientes variables: Nombre Ws Return ResultElements ResultElement Tipo GoogleSearch.GoogleSearchService GoogleSearchResult ResultElementArray ResultElement Ya están definidas en el xpz el resto de las variables necesarias para hacer el ejercicio. Luego, debemos programar el evento search.click de la siguiente forma: Event search.click &Key = "3yHXpPZQFHKdexiyPjqTPYNqVvnYj8cZ" &MaxResult = 10 &Filter = 1 &SafeSearch = 1 &Return= &Ws.doGoogleSearch(&Key,trim(&Query),&Start,&MaxResult,&Filter,&Restrict,&Safesearch,&Lr,& Ie,&Oe) &ResultElements = &Return.resultElements &searchTime = &return.searchTime EndEvent En este evento se realiza la invocación al método doGoogleSearch del Web Service. Los resultados son devueltos en una Collection de un tipo de datos estructurado, el que es definido automáticamente en GeneXus por el WSDL Inspector. Programar el evento Load del grid de la siguiente forma: Event Grid1.Load For &ResultElement in &ResultElements Title.Caption = &ResultElement.title &url = &resultElement.URL Title.LinkTarget = "_BLANK" Title.Link = link(&ResultElement.URL) &Summary = &ResultElement.snippet &cachedsize = &resultelement.cachedSize grid1.Load() Endfor EndEvent En este evento se recorre la Collection con los resultados devueltos por el Web Service y se realiza la carga del grid. Haga clic aquí para ver la demostración Especificar, generar, compilar y ejecutar el Web Panel GoogleSearch. Haga clic aquí para ver la ejecución Nota: La especificación del Web Service del ejemplo, se puede leer de: http://www.google.com/apis/reference.html Debug de una llamada SOAP Introducción Cuando se produce un error al realizar una llamada SOAP desde GeneXus, es bastante difícil en ocasiones saber donde se encuentra el problema. Es necesario contar con alguna forma de poder efectuar un debug. En este documento se presentan una serie de pasos para verificar cuando se produce una situación de este tipo, así como también se detalla el uso de un utilitario de libre distribución que puede resultar de utilidad. Se recomienda la lectura previa de los documentos Protocolo SOAP y Locations. Aunque este documento está orientado específicamente a las llamadas SOAP, también aplica en forma general a la detección de problemas utilizando los tipos de datos HTTP. Descripción Cuando se produce un error en una llamada SOAP, es conveniente verificar ciertos puntos en el siguiente orden: 1) Verificar que el servicio esté funcionando Una causa obvia del fallo puede ser el hecho de que el Web Service al que se está invocando no esté operativo, ya sea porque el servidor está caído u otras causas. Para verificar esto se puede invocar al archivo WSDL, en el caso de que el Web Service haya sido desarrollado con GeneXus, se deberá llamar a la siguiente URL en un browser: http://servidor:port/url_base/servicio?wsdl Por ejemplo, para invocar al servicio que devuelve la Edición de las noticias de ARTECH, sería: http://www.gxtechnical.com/cgi-bin/adevedicion.exe?wsdl Deberá visualizarse un archivo XML válido y no un error HTTP . Por ejemplo algo como: <?xml version="1.0" encoding="iso-8859-1" ?> - <definitions name="DevEdicion" targetNamespace="http://www.gxtechnical.com/cgibin/adevedicion.exe?wsdl" xmlns:wsdlns="http://www.gxtechnical.com/cgibin/adevedicion.exe?wsdl" xmlns:typens="http://www.gxtechnical.com/cgibin/adevedicion.exe?type" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/"> - <types> <schema targetNamespace="http://www.gxtechnical.com/cgibin/adevedicion.exe?type" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" elementFormDefault="qualified" /> </types> - <message name="DevEdicion.Execute"> <part name="Ediid" type="xsd:integer" /> <part name="Idioid" type="xsd:string" /> </message> . . . 2) Verificar que la llamada se hace a la URL correcta Otro punto a verificar es que la URL a la que se está invocando sea la correcta. Podría suceder que el archivo LOCATION.XML no estuviera en el directorio correcto en tiempo de generación o ejecución (en caso de que se configurara la llamada mediante archivo), o que las propiedades de la variable de tipo Location tuvieran valores incorrectos (en caso de que la configuración se hiciera mediante código en tiempo de ejecución). Entonces se deben verificar los valores de dichas propiedades, para lo cual se deberá definir una variable de tipo Location (en caso de que no existir) y asignarla al location del objeto llamado, utilizando la función GetLocation(). Se pueden entonces evaluar las propiedades, asignándolas por ejemplo a variables que se despliegan por pantalla. Algo similar a: . . &Loc &Host &Port &URLBase = GetLocation(“<Nombre_location>”) = &Loc.Host = &Loc.Port = &Loc.BaseUrl call(PMiServicio,......) . . Otro valor a considerar es la extensión agregada al nombre del objeto, esto dependerá del generador asociado al main correspondiente. Para tener la seguridad de que la invocación se está realizando con la extensión correcta, remitirse al punto 4. 3) Obtener la descripción del error La descripción del error también nos da una pista del problema la mayoría de las veces. Es posible obtener el código y descripción del error utilizando las funciones GetSOAPErr() y GetSOAPErrMsg(), invocándolas luego del call(). Combinándolo con el ejemplo del punto anterior, quedaría: . . &Loc &Host &Port &URLBase = GetLocation(“<Nombre_location>”) = &Loc.Host = &Loc.Port = &Loc.BaseUrl call(PMiServicio,......) &ErrCode = GetSoapErr() &ErrCodeDsc = GetSoapErrMsg() . . 4) Analizar el Request y el Response HTTP Si los puntos anteriores no nos llevaron a la solución del problema, es conveniente verificar el Request y el Response HTTP que se generan. Existen varias herramientas con las que se puede hacer esto, en particular mostraremos tcpTrace, un utilitario de libre distribución que puede obtenerse en http://www.pocketsoap.com/tcptrace/. El mismo no necesita instalación, es solamente un ejecutable. Al ejecutar el archivo tcpTrace.exe se presenta el siguiente diálogo: Se deberá completar lo siguiente: Local Port # Destination Server Destination Port # - un número cualquiera de puerto local, por ej. 8085 - el servidor destino - el Puerto del servidor destino (por defecto es 80). Luego clickear OK. A continuación se deberá ejecutar la llamada SOAP, modificando previamente los parámetros de la misma para que se realice al servidor localhost y al puerto especificado en Local Port #. Esto se deberá realizar ya sea modificando el archivo LOCATION.XML o bien modificando las propiedades de la variable de tipo Location (dependiendo del modo de configuración utilizado). Al efectuar la llamada, en la ventana del tcpTrace se visualizará: En la ventana de la izquierda aparecerá una línea por cada llamada. Al hacer clic sobre una línea, en las ventanas de la derecha se mostrarán el Request y el Response HTTP para la llamada correspondiente. Mirando el header del Request se puede verificar que la URL base y la extensión que se están generando sean correctas. El body (lo que esta después de la línea que comienza con Contentlenght) es el mensaje SOAP de la llamada, debe ser un XML bien formado. En la ventana inferior derecha se ve el Response del Web Service. Si se devolvió algún error HTTP, el mismo se puede visualizar en el header del mismo, y en el body se muestra alguna descripción. En el caso de que el servicio finalizó en forma exitosa, se devuelve un código 200, y en el body aparece el Response SOAP (a partir de la línea en blanco posterior al header). El mismo también deberá ser un XML bien formado (para verificar esto se puede copiar y pegar el contenido, salvarlo como un archivo con extensión XML, y abrirlo con un browser). WSDL Inspector Introducción El WSDL Inspector permite a partir del WSDL de un Web Service definir los tipos de datos necesarios en GeneXus para poder consumir el Web Service en forma transparente sin tener que preocuparse de los protocolos involucrados en el proceso y la definición del mismo. Descripción El WSDL de un Web Service es un archivo que describe al mismo; brinda toda la información necesaria para poder consumirlo. GeneXus brinda una herramienta llamada WSDL Inspector que permite a partir del WSDL de un Web Service definir en la base de conocimientos todo lo necesario para poder consumir los métodos del Web Service en forma transparente. Para acceder al WSDL Inspector hay que ejecutar la opción Tools / WSDL Inspector. La misma está solamente accesible desde Design. En “Web Service URL” se debe ingresar el camino hacia el WSDL. Puede ser referenciado por medio del protocolo http (por ej. http://api.google.com/GoogleSearch.wsdl ) o file (por ejemplo: file:C:\Servicios\AmazonWebServices.wsdl). Una vez ingresado el camino del WSDL se debe presionar el botón “Inspect”, con lo cual en caso de no existir ningún error se mostrará la información de los distintos métodos que brinda el Web Service, junto con los tipos de datos necesarios para poder consumirlos. Para poder “importar” la información necesaria dentro de la base de conocimiento que permita consumir el Web Service se debe presionar el botón “Add Reference”. En la imagen anterior se muestra la información de un Web Service simple, el cual cuenta con un solo método llamado BabelFish que recibe dos parámetros de entrada de tipo Character y retorna otro parámetro de tipo Character. El siguiente ejemplo muestra otro caso en el cual el Web Service cuenta con más de un método y se necesita definir nuevos tipos de datos (ArrayOfNewsCategoty, NewsCategoty, ArrayOfBusnessShortNews, BusnessShortNews): Add Reference Como se mencionó anteriormente al presionar el botón “Add Reference” se genera dentro de la base de conocimiento los tipos de datos necesarios para poder consumir el Web Service en forma transparente. O sea, se genera un tipo de datos que identifica el Web Service y en caso de que el mismo necesite nuevos tipos de datos se genera un tipo de datos estructurado para cada uno de ellos. De esta forma se puede definir una variable a la cual asignarle el tipo de datos definido para el Web Service y utilizando los métodos de la misma poder invocar a los distintos métodos que el Web Service provee. Si para consumir el método se necesitan tipos de datos estructurados hay que crear variables con los tipos de datos estructurados creados por el Inspector. Invocación de los métodos de un Web Service MÉTODO SIN TIPOS DE DATOS ESTRUCTURADO Volvamos entonces a la primera imagen para poder mostrar en un caso sencillo como poder consumir un Web Service. En este caso al presionar el botón “Add Referente” se agrega a los tipos de datos que maneja GeneXus, el tipo “net_xmethods_wwwsd_BabelFishService.BabelFishService”. (Notar que en el nombre asignado al tipo de datos está precedido por el namespace que identifica al Web Service, de esta forma GeneXus asegura que no van a existir dos tipos de datos con el mismo nombre para distintos Web Services). De esa forma se puede definir una variable a la cual asignarle ese tipo de datos; llamaremos a la misma “ws”. Luego podremos invocar utilizando la variable “ws” a cualquiera de los métodos que el Web Service provee (en este caso solo uno) de la siguiente forma: &result = &ws.BabelFish(&traslationmode, &source) Donde &result, &traslationmode y &source son variables de tipo character. Eso es todo!, de esta forma se puede invocar a un Web Service en forma sencilla sin tener que preocuparse de los protocolos involucrados en el proceso y la definición del mismo; solamente se tuvo que dar la ubicación de su WSDL y GeneXus se encargó de esconder la complejidad y definir un tipo de datos que represente al Web Service. MÉTODO CON TIPO DE DATOS ESTRUCTURADO Ahora vamos a consumir un Web Service que utiliza dos tipos de datos estructurados. Al importar el Web Service en GeneXus se crea lo siguiente:  Un nuevo tipo de datos correspondiente al Web Service (com_swanandmokashi.Horoscope)  Un tipo de dato estructurado llamado ZodiacSigns con la siguiente definición: ZodiacSign Character(9999) DailyForecast Character(9999)  Un tipo de dato estructurado llamado ArrayOfZodiacSigns con la siguiente definición: ArrayOfZodicSigns collection of ZodiacSigns Para consumir el Web Service se tiene el siguiente código: &array = &ws.GetHoroscope() For &item in &array &SodiacSign = &item.ZodiacSign &ForeDailiy = &item.DailyForecast load endfor Donde: &ws es de tipo com_swanandmokashi.Horoscope &array es de tipo ArrayOfZodicSigns &item es de tipo ZodiacSigns De esta forma se consume un Web Service que usa tipos de datos estructurados. Nota: En el caso de tipos de datos booleanos, se debe utilizar el tipo de datos numérico N(1). El valor 1 se corresponde con el True, y el 0 con el False. Uso de Locations en el consumo de Web Services De la misma forma que con el llamado de los procedimientos SOAP, es posible modificar diferentes parámetros de la invocación de Web Services utilizando los locations. El nombre del location (indicado en el tag <GXLocation name=> del archivo location.xml, que debe utilizarse es el nombre que GeneXus le asigna al tipo de datos creado por el WSDL Inspector para el servicio, sustituyendo el último punto (.) por un underscore (_). Por ejemplo, en el caso del Web Service de Horóscopo anterior, en GeneXus el tipo de datos para el servicio muestra: com_swanandmokashi.Horoscope El location que se debe utilizar en este caso es: com_swanandmokashi_Horoscope El archivo location.xml debe de estar en el directorio corriente y sólo se toma en cuenta en tiempo de ejecución. Por ejemplo si se quiere redireccionar el Web Service a localhost:88 se tiene que tener un location.xml de la siguiente forma: <GXLocations> <GXLocation name="com_swanandmokashi_Horoscope"> <Common> <Host>localhost</Host> <Port>88</Port> </Common> <HTTP> <BaseURL>/HomePage/WebServices/</BaseURL> </HTTP> </GXLocation> </GXLocations> Ejemplo En GXOpen se encuentra una base de conocimiento de ejemplo en la cual se consumen tres Web Services; GXChart (servidor de gráficas), Babelfish (traductor de textos) y GetJoke (provee chistes agrupados por categorías). El mismo puede ser obtenido en http://www.gxopen.com/main/hproject.aspx?176 Consideraciones Para consolidar objetos que tengan variables de tipos de datos asociados a Web Services, es necesario previamente agregar la referencia con el WSDL Inspector en la base de conocimiento destino. Otra opción es copiar los archivos asociados al Web Service desde el directorio <dir.KB>\kbdata\usrtypes de la base de conocimiento origen a la destino (se generan dos archivos con extensiones .ari y .xml por cada Web Service agregado, que contienen las definiciones del mismo). Además, luego de consolidarlo, es necesario en el objeto borrar y volver a definir la/s variable/s de ese tipo, de lo contrario se producirá un error de especificación: spc0056, Internal error. Variable <variable> definition is incorrect or not available. Data:<tipo>. Cuando se compila un objeto main se compilan todos los tipos de datos definidos en lugar de compilar solamente los usados por ese main. Locations Introducción Se busca permitir configurar las invocaciones a objetos main GeneXus en forma remota, cuando se utilizan diferentes protocolos, por ej. llamadas vía SOAP. Dichas configuraciones se pueden hacer tanto usando el tipo de datos Location de GeneXus como el archivo location.xml. Alcance Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos. Para los siguientes generadores: .NET, Java, Visual Basic y Visual FoxPro. Descripción Cada programa main de GeneXus tiene asignado un location. Éste es un nombre lógico al que se le hace corresponder una ubicación válida para el caso de que el objeto sea invocado, según el protocolo que se utilice. Necesitamos entonces describir las características de este location, para lo que se utiliza el siguiente esquema: En primer lugar, se asigna al objeto a ser invocado un nombre lógico, configurando el mismo en la propiedad Location de dicho objeto. Será necesario entonces poder configurar los locations, según los diferentes protocolos que se utilicen para la invocación del objeto. Existen tres instancias posibles para realizar esto: 1) En tiempo de generación. Mediante el archivo location.xml, ubicado en el directorio raíz de la base de conocimiento y cuya estructura es descripta más abajo. Este archivo debe ser creado por el usuario GeneXus. 2) En tiempo de ejecución, mediante un archivo. Mediante el archivo location.xml, ubicado en el directorio corriente durante la ejecución del programa que invoca al main, cuya estructura coincide con el archivo del mismo nombre descripto en la instancia anterior. Este archivo debe ser creado o editado por el usuario GeneXus. 3) En tiempo de ejecución, mediante código. Mediante variables de tipo Location, cuya estructura es descripta más abajo. Es decir que las propiedades especificadas en tiempo de ejecución mediante código tendrán preferencia sobre las especificadas en tiempo de ejecución mediante un archivo y éstas a su vez tendrán preferencia sobre las especificadas en tiempo de generación para permitir mayor dinamismo en la configuración de los locations. Propiedades Se describen a continuación las propiedades disponibles para describir el location en el archivo XML: Propiedad Elemento XML Subelemento XML Tipo Protocolo Host Port BaseURL Secure Host Port BaseURL Secure Character Numeric Character Numeric (0|1) Numeric Numeric (0|1) Method Realm User Password Numeric Character Character Character HTTP HTTP HTTP HTTP Timeout Authentication Timeout Authentication HTTP HTTP AuthenticationMethod AuthenticationRealm AuthenticationUser AuthenticationPassword Authentication Authentication Authentication Authentication HTTP HTTP HTTP HTTP HOST Especifica la dirección del servidor correspondiente al location. El valor por defecto es “localhost”. Ejemplo por código &Location.Host = “www.soaplocation.com” Ejemplo en XML <Host>www.soaplocation.com</Host> PORT Especifica el puerto en el servidor correspondiente al location. El valor por defecto es 80. Ejemplo por código &Location.Port = 8080 Ejemplo en XML <Port>8080</Port> BASEURL Especifica la URL base del location, en caso de utilizar el protocolo HTTP. La URL final tiene la forma http://Host:Port/BaseUrl/pgmname. Si se necesitan varias BaseUrls sobre el mismo servidor se deberá definir un location para cada una. El valor por defecto es “/”. Ejemplo por código &Location.BaseURL = “/mydirectory/soap/” Ejemplo en XML <BaseURL>/mydirectory/soap/</BaseURL> SECURE Especifica si los llamados al location se harán mediante un protocolo seguro o no, en caso de utilizar el protocolo HTTP. Si esta propiedad tiene el valor 1 se utilizará el procolo HTTPS. El valor por defecto es 0. Ejemplo por código &Location.Secure = 1 Ejemplo en XML <Secure>1</Secure> TIMEOUT Especifica el tiempo, en segundos, a esperar por una respuesta del servidor. Si el valor es 0, la espera es indefinida. El valor por defecto es 0. Ejemplo por código &Location.Timeout = 1 Ejemplo en XML <Timeout>1</Timeout> AUTHENTICATION Especifica si se utilizará autentificación con el servidor o no. El valor por defecto es 0. En XML se especifican las propiedades de la autentificación dentro del elemento <Authentication> y por lo tanto no se especifica valor para este elemento. La simple mención del elemento <Authentication> indica que esta propiedad tendrá valor 1. Ejemplo por código &Location.Authentication = 1 Ejemplo en XML <Authentication/> AUTHENTICATIONMETHOD Especifica el método de autentificación con el servidor, en caso de utilizarla. Los posibles valores son los mismos que en el objeto HTTPClient. El valor por defecto es 0. Ejemplo por código &Location.AuthenticationMethod = 1 Ejemplo en XML <Authentication> <Method>1</Method> </Authentication> AUTHENTICATIONREALM Especifica el realm para la autentificación con el servidor, en caso de utilizarla. El valor por defecto es “”. Ejemplo por código &Location.AuthenticationRealm = “MyRealm” Ejemplo en XML <Authentication> <Realm>MyRealm</Realm> </Authentication> AUTHENTICATIONUSER Especifica el nombre de usuario para la autentificación con el servidor, en caso de utilizarla. El valor por defecto es “”. Ejemplo por código &Location.AuthenticationUser = “Name” Ejemplo en XML <Authentication> <User>Name</User> </Authentication> AUTHENTICATIONPASSWORD Especifica la contraseña para la autentificación con el servidor, en caso de utilizarla. El valor por defecto es “”. Ejemplo por código &Location.AuthenticationPassword = “MyPassword” Ejemplo en XML <Authentication> <Password>MyPassword</Password> </Authentication> Formato del archivo XML El archivo location.xml utilizado para describir los locations empleados en la base de conocimiento debe tener el siguiente formato: <GXLocations> <GXLocation name=”NombreDelLocation”> <Common> Propiedades </Common> <Protocolo> Propiedades </Protocolo> <Protocolo> Propiedades </Protocolo> . . . <Protocolo> Propiedades </Protocolo> </GXLocation> </GXLocations> Las propiedades en el elemento Common aplican a todos los protocolos. Las propiedades especificadas en un protocolo en particular tendrán prioridad sobre estas. En esta versión, el único protocolo soportado es HTTP. Obtención de locations en tiempo de ejecución Para poder modificar las propiedades de un location en tiempo de ejecución es necesario definir una variable de tipo Location y asignarle alguna de las locations existentes. Esto se puede hacer con la función getLocation( LocationName) que toma como parámetro una cadena con el nombre de algún location existente y devuelve un tipo Location. Por ejemplo si definimos la variable &Loc de tipo Location y tenemos algún procedmiento con la propiedad location en “MyLocation”, podemos ejecutar &Loc = getLocation( “MyLocation”) y luego modificar sus propiedades. Las modificaciones así realizadas son globales. En cualquier momento posterior en que se haga un llamado a un procedimiento en dicho location se tendrán en cuenta las últimas propiedades asignadas. Ejemplo de archivo location.xml <GXLocations> <GXLocation name=”Location1”> <Common> <Host>www.soapserver1.com</Host> <BaseURL>/soap/services/</BaseURL> <Timeout>30</Timeout> </Common> </GXLocation> <GXLocation name=”Location2”> <Common> <Host>www.soapserver2.com</Host> <Port>80</Port> </Common> <HTTP> <BaseURL>/webservices/</BaseURL> <Port>8080</Port> <Secure>1</Secure> <Authentication> <User>UserName</User> <Password>Password</Password> </Authentication> </HTTP> </GXLocation> </GXLocations> Con este archivo location.xml (usado tanto en tiempo de generación como en tiempo de ejecución), los locations Location1 y Location2 tendrán las siguientes propiedades: Propiedad Host Port BaseURL Secure Location1 www.soapserver1.com 80 /soap/services/ 0 Location2 www.soapserver2.com 8080 /webservices/ 1 Timeout Authentication AuthenticationMethod AuthenticationRealm AuthenticationUser AuthenticationPassword 30 0 0 (vacío) (vacío) (vacío) 0 1 0 (vacío) UserName Password Tipo de Datos XMLWriter Introducción El objetivo del tipo de datos XMLWriter es proveer la posibilidad de grabar archivos XML de un modo más sencillo que las funciones incluidas en versiones anteriores. El documento XML contiene una introducción a dicho lenguaje. Se recomienda leer también el documento XMLReader. Alcance Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos. Para los generadores: .NET, Java, Visual Basic y Visual FoxPro. Descripción Para poder crear un archivo XML desde un objeto GeneXus, se debe definir una variable de un nuevo tipo de datos denominado XmlWriter (xmlwrt) y luego invocar a los métodos necesarios para crear los nodos que lo componen. Métodos MÉTODOS BÁSICOS Open([FileName]) Permite crear un documento XML. File Name es el nombre de archivo con el cual se va a crear el documento, si se omite, el mismo se genera por “standard output”. En caso de ser un objeto Web se genera en el response. (Funciona con CGI, ISAPI WebClasses y Servlets). FileName – Character OpenToString() Permite crear un documento XML a un buffer inerno en lugar de a un archivo. El contenido del buffer puede ser consultado por medio de la propiedad ResultingString. WriteStartElement(<ElementName>) Comienza un elemento compuesto. Este elemento puede tener subelementos, por lo que es valido anidar llamadas a WriteStarElement/WriteElement. <ElementName> - Character WriteElement(<ValueName>, <ElementValue>) Almacena un valor dentro del tag de nombre ValueName. En el caso de que ElementValue sea de tipo Character, se sustituyen los caracteres especiales por secuencias de caracteres (el '<' se sustituye por '&lt;', el '>' por '&gt;', etc.). A diferencia del caso anterior este elemento no contiene subelementos. <ValueName>- Character <ElementValue>- Character WriteText(<Value>) Genera character data con el string <Value>. Se sustituyen los caracteres especiales por secuencias de caracteres (el '<' se sustituye por '&lt;', el '>' por '&gt;', etc.). <Value> - Character WriteRawText(<Value>) Genera cualquier texto sin sustituir los caracteres especiales por secuencias de caracteres. <Value> - Character WriteAttribute(<AttriName>, <AttriValue>) Asigna un atributo al último elemento. Es decir, al elemento que se creó con la última invocación a WriteStartElement(<ElementName>) o WriteElement(<ValueName>, <ElementValue>). <AttriName> - Character <AttriValue> - Character WriteEndElement() Cierra el último elemento abierto. Close() Cierra el documento. OTROS MÉTODOS WriteComment(<Comment>) Escribe el comentario indicado en <Comment>. Ejemplo: WriteComment(‘Comentario’) genera lo siguiente: <!— Comentario --> <Comment> - Character WriteEntityReference(<Entity>) Escribe una referencia a la entidad <Entity>. Ejemplo: WriteEntityReference(‘Entidad’) genera lo siguiente: &Entidad; <Entity> - Character WriteCData(<DataValue>) Escribe una sección Cdata con el valor <DataValue>. Si el contenido especificado para la sección Cdata contiene la secuencia de caracteres ]]>, el mismo es fraccionado y se generan tantas secciones Cdata como sean necesarias para obtener un documento XML bien formado. Ejemplo: WriteCData(‘Value’) genera lo siguiente: <![CDATA[value]]> <DataValue> - Character WriteProcessingInstruction(<Action>, <Value>) Escribe el registro del tipo processing instruction indicado por <Action> y <Value>. Ejemplo: WriteProcessingInstruction(‘play’, ‘sound = “Hello.wav”’) genera lo siguiente: <? Play sound=”Hello.wav” ?> <Action> - Character <Value > - Character WriteStartDocument([Encoding, [StandAlone]]) Escribe la declaración de XML usando la versión 1.0 y codificación ISO-8859-1. Opcionalmente se puede indicar un entero (0/1) como valor booleano para usar en la declaración standalone y un encoding. Este método debe ser llamado al comienzo de la generación del documento (luego del open() y antes de cualquier otro método). Ejemplo: WriteStartDocument() genera lo siguiente: <?xml version=”1.0” enconding=”ISO-8859-1” ?> Enconding - Character StandAlone – Integer (0/1) WriteDocType(<DocName> [,SubSet]) Escribe la declaración DOCTYPE del documento XML. Si se incluye un SubSet se ingresa entre corchetes al final de la declaración. Ejemplo: WriteDocType(‘<book>’, ‘<!ENTITY ge “entity”>’) genera lo siguiente: <!DOCTYPE <book> [<!ENTITY ge “entity”>]> <DocName> - Character SubSet – Character WriteDocTypeSystem(<DocName>,<uri> [,SunSet]) Escribe la declaración DOCTYPE del documento XML con una declaración de tipo SYSTEM. Si se incluye un SubSet se ingresa entre corchetes al final de la declaración. Ejemplo: WriteDocTypeSystem(‘<book>’, ‘file.dtd’) genera lo siguiente: <book> SYSTEM “file.dtd”> <!DOCTYPE <DocName> - Character <uri> - Character SubSet – Character WriteDocTypePublic (<DocName>,<PubId>, <uri> [,SunSet]) Escribe la declaración DOCTYPE del documento XML con una declaración de tipo PUBLIC. Si se incluye un SubSet se ingresa entre corchetes al final de la declaración. Ejemplo: WriteDocTypePublic(‘<book>’,‘Id’, ‘http://www.ser.com/dtd’) genera lo siguiente: <!DOCTYPE <book> PUBLIC “Id” “http://www.ser.com/dtd”> <DocName> - Character <PubId> - Character <uri> - Character Subset - Character PROPIEDADES Indentation Define cuantos caracteres se utilizan para indentar el código generado. Por defecto es 2. IndentChar Define el carácter que se utiliza para indentar el código generado. Por defecto se utiliza un espacio en blanco. ErrCode Retorna un valor mayor que cero en caso de haber ocurrido un error durante la generación del documento XML. ErrDescription Contiene la descripción del error ocurrido cuando ErrCode tiene un valor distinto de cero. ResultingString Permite consultar el valor del documento XML que se encuentra en un buffer interno cuando el documento se creó a partir del método OpenToString(). El documento retornado puede ser incompleto si se invoca a la propiedad antes de la ejecución del método close(). Soporte para Namespaces En esta sección se describen las funcionalidades disponibles para generar documentos XML que utilizan namespaces. MÉTODOS WriteNSStartElement(<LocalName> [,Prefix, NameSpaceURI]) Este método es análogo al WriteStartElement. Si se indica un NameSpaceURI que no está en el ámbito de definición del elemento, o este tiene un prefijo diferente del parámetro Prefrix, se crea automáticamente el atributo xmlns:prefix=URI <LocalName> - Character Prefix - Character NameSpaceURI - Character WriteNSElement(<LocalName> [,NameSpaceURI [,Value]]) Este método es análogo al WriteElement. El prefijo se determina automáticamente en base a los prefijos definidos en el ámbito del elemento. Si ningún prefijo estuviera asociado al URI especificado, se define junto con el elemento un namespace por defecto. Ejemplo: WriteNSElement(‘Precio’, ’20.5’, ‘http://www.genexus.com’) genera lo siguiente: <prefijo:Precio>20.5</prefijo:Precio> o <Precio xmlns=” http://www.genexus.com”>20.5</Precio> <LocalName> - Character NameSpaceURI - Character <Value > - Character WriteAttribute(<LocalName>, <Value>) Cuando se trabaja con documentos con name sapace, el método WriteAttribute tiene un comportamiento especial para algunos atributos. Si el nombre del atributo es “xmlns” o comienza con “xmlns:” se registra la definición del atributo como la definición de un namespace. De esta forma, en futuras invocaciones de un método WriteNSStartElement o WriteNSElement puede determinarse el prefijo correspondiente a una determinada URI. EJEMPLO DE SOPORTE DE NAMESPACES El siguiente procedimiento genera el archivo ejemplo.xml &writer.Open(‘ejemplo.xml’) &writer.WriteNSStartElement(‘a’) &writer.WriteAttribute(‘xmlns:p1’, ’http://www.artech.com’) &writer.WriteAttribute(‘xmlns’, ‘http://defecto.com’) &writer.WriteAttribute(‘att’, ‘a1’) &writer.WriteNSElement(‘b’, ’http://www.artech.com’) &writer.WriteAttribute(‘att’, ‘a1’) &writer.WriteAttribute(‘p1:att2’, ‘a2’) &writer.WriteNSElement(‘b’, ’http://www.genexus.com’) &writer.WriteAttribute(‘xmlns:p1’,’http://www.genexus.com’) &writer.WriteAttribute(‘xmlns:p2’,’http://www.artech.com/segundo’) &writer.WriteAttribute(‘p2:att1’, ‘a1’) &writer.WriteEndElement() &writer.Close() El archivo ejemplo.xml queda de la siguiente forma: <a xmlns:p1="http://www.artech.com" xmlns="http://defecto.com" att="a1"> <p1:b att1="a1" p1:att2="a2" /> <p1:b xmlns:p1="http://www.genexus.com" xmlns:p2="http://www.artech.com/segundo" p2:att1="a1" /> </a> Ejemplo El siguiente procedimiento genera un archivo llamado Reunion.xml que contiene datos de una reunión, indicando que integrantes participaron de la misma, y cuales son las tareas de cada uno. &filexml.open('Reunion.xml') &filexml.WriteStartDocument() &filexml.WriteStartElement('REUNION') &filexml.WriteAttribute('Fecha', dtoc(ReuFch) ) &filexml.WriteElement('FECHA', dtoc(ReuFch) ) &filexml.WriteComment('Descrpción de la reunión') &filexml.WriteCData(ReuDsc ) &filexml.WriteStartElement('INTEGRANTES') for each &filexml.WriteElement('INTEGRANTE', ReuPerNom ) endfor &filexml.WriteEndElement() &filexml.WriteStartElement('TAREAS') for each &filexml.WriteStartElement('TAREA') &filexml.WriteElement('RESPONSABLE', ReuTarPerNom) &filexml.WriteCData(ReuTarDsc ) &filexml.WriteEndElement() endfor &filexml.WriteEndElement() &filexml.WriteEndElement() &filexml.Close() El archivo reunion.xml contiene: <?xml version="1.0" encoding="ISO-8859-1" ?> <REUNION Fecha="06/03/01"> <FECHA>06/03/01</FECHA> <!-- Descrpción de la reunión--> <![CDATA[ Reunion del equipo de desarrollo de la aplicación. <INTEGRANTES> La reunión fue realizada el Viernes a las 9:30 horas.]]> <INTEGRANTE>Juan Pedro</INTEGRANTE> <INTEGRANTE>Laura</INTEGRANTE> <INTEGRANTE>Diego</INTEGRANTE> <INTEGRANTE>Florinda</INTEGRANTE> </INTEGRANTES> <TAREAS> <TAREA> <RESPONSABLE>Juan Pedro</RESPONSABLE> <![CDATA[ Realizar la documentción de la aplicación]]> </TAREA> <TAREA> <RESPONSABLE>Florinda</RESPONSABLE> <![CDATA[ Reunion con los clientes.]]> </TAREA> <TAREA> <RESPONSABLE>Laura</RESPONSABLE> <![CDATA[ Realizar el maunal de usuario]]> </TAREA> <TAREA> <RESPONSABLE>Diego</RESPONSABLE> <![CDATA[ Documentar las especificaciones.]]> </TAREA> </TAREAS> </REUNION> Tipo de Datos XMLReader Introducción El objetivo del tipo de datos XMLReader es proveer la posibilidad de leer el contenido de los archivos XML. El documento XML contiene una introducción a dicho lenguaje. Se recomienda leer también el documento XMLWriter. Alcance Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos. Y para los siguientes generadores: .NET, Java, Visual Basic y Visual FoxPro. Descripción Para poder leer el contenido de un archivo XML desde un objeto GeneXus, se debe definir una variable de un nuevo tipo de datos denominado XmlReader y luego invocar a los métodos y propiedades necesarios para obtener la información de los nodos que lo componen. La idea básica del funcionamiento es la siguiente: existe un método Read() que se comporta a manera de cursor avanzando al siguiente nodo del archivo, luego utilizando ciertas propiedades como por ejemplo Name y Value se puede obtener los datos del nodo, en este caso el nombre y el valor del mismo. De esta forma utilizando el método Read() se “navega” a lo largo del documento en forma secuencial obteniendo los distintos nodos del mismo. Métodos MÉTODOS BÁSICOS Open(<FileName>) Permite abrir un documento XML. File Name es el nombre de un archivo XML o una URL con un archivo XML. Puede usarse la propiedad ErrCode para consultar el éxito de la operación. <FileName> – Character OpenFromString(<DocXML>) Permite abrir un documento XML contenido en un string. <DocXML > – Character Read() Este método se utiliza para ir obteniendo en forma secuencial los distintos nodos del archivo abierto. Invocando al mismo se avanza al siguiente nodo y retorna un valor entero mayor que cero si se leyó un nodo y cero en caso contrario. ReadType(<NodeTypeConstraint> [,NameConstraint]) Al igual que el método Read(), este método avanza al siguiente nodo pero que cumpla con las restricciones indicadas y retorna un valor entero mayor que cero si se leyó un nodo y cero en caso contrario. La restricción <NodeTypeConstraint> especifica cuales son los tipos de nodos que quiero leer. Se especifica indicando las constantes del tipo de nodo concatenadas por medio del carácter “+” Por ejmplo: <NodeTypeConstraint> = 1 + 4 (especifica el tipo Element y Text) Si NameConstraint tiene un valor no nulo, especifica que valor debe de tener el nombre del nodo que quiero leer, siempre y cuando el nodo sea de tipo Element o EndTag. <NodeTypeConstraint> – Character NameConstraint – Character GetAttributeByIndex(<Index>) Retorna el valor del atributo en la posición <Index> del nodo actual obtenido por el método Read o ReadType. Solo es válido para nodos de tipo Element. Las posiciones se numeran desde 1. <Index> – Integer GetAttributeByName(<Name>) Retorna el valor del atributo de nombre <Name >del nodo actual obtenido por el método Read o ReadType. Solo es válido para nodos de tipo Element. <Name> – Character ExistsAttribute(<Name>) Retorna 1 si el atributo de nombre <Name> del nodo actual obtenido por el método Read o ReadType existe y 0 en caso contrario. Sólo es válido para nodos de tipo Element. <Name> – Character Close() Cierra el documento. OTROS MÉTODOS SetDocEncoding (<Encoding>) Permite establecer explícitamente la codificación de caracteres utilizada en el documento. El valor indicado tiene precedencia sobre la propiedad encoding de la declaración <?xml?> del documento. Los valores posibles de <Enconding> son: ANSI US-ASCII UTF-8 UTF-16 ISO-8859-1 <Enconding> - Character SetNodeEncoding(<Encoding>) Permite establecer la codificación de caracteres utilizada para los valores retornados por el objeto XMLReader al programa GeneXus. Los valores posibles de <Enconding> son: ANSI UTF-8 El valor por defecto es ANSI. <Enconding> - Character Skip() Permite saltear un elemento completo con todos sus hijos. Solo es válido para nodos de tipo Element. ReadRawXML() Permite obtener texto XML plano a partir del inicio de un elemento. Solo es válido para nodos de tipo Element. AddSchema(<URI>, [Namespace])(Solo .NET) Indica que se va a utilizar el “schema” de la <URI> para validar el XML del [Namespace] indicado. Si no se indica [Namespace], se toma el del atributo targetNamespace del esquema. Lo indicado en este método tiene prioridad sobre el atributo schemaLocation del documento XML (en caso de que exista). Para utilizar este método hay que indicar en la propiedad ValidationType que se realice validación por esquema o automática. <URI> – Character Namespace – Character Propiedades PROPIEDADES BÁSICAS Nodetype Retorna el tipo de nodo actual obtenido por el método Read o ReadType. Los valores posibles son: 1 - Element 2 - EndTag 4 - Text 8 - Comment 16 - WhiteSpace 32 - Cdata 64 - ProcessingInstruction 128 DocumentType ElementType EndTagType TextType CommentType WhiteSpaceType CDataType ProcessingInstructionType DoctypeType Estas propiedades contienen valores constantes que pueden utilizarse para comparar el resultado de la propiedad NodeType o con el método ReadType. Name Retorna el nombre del nodo actual obtenido por el método Read o ReadType. Solo es válido para nodos de tipo Element y EndTag. Value Retorna el valor del nodo actual obtenido por el método Read o ReadType. Solo es válido para los nodos de tipo Text, Comment, ProcessingInstruction, DocumentType y Element IsSimple Indica si el nodo actual obtenido por el método Read o ReadType responde a una estructura del tipo <Elemento>Valor</Elemento> AttributeCount Retorna la cantidad de atributos que posee el nodo actual obtenido por el método Read o ReadType. Solo es válido para nodos de tipo Element. EOF Retorna si se alcanzo el final del docuemnto. ErrCode Retorna un valor mayor que cero en caso de haber ocurrido un error durante el procesamiento de un documento XML. ErrLineNumber; ErrLinePos Retornan el numero de linea y posición dentro de la misma respectivamente en caso de que ErrCode sea distinto de cero. ErrDescription Retorna la descripción del error en caso de que ErrCode sea distinto de cero. OTRAS PROPIEDADES ReadExternalEntities Esta propiedad booleana(1/0) indica si deben leerse las entidades externas parseadas que forman parte del documento XML que se esté procesando (esto incluye el subconjunto externo del DTD). Si la lectura está habilitada, el objeto XMLReader leerá y procesará en forma transparente para el usuario toda referencia a archivos o URLs externas que sean incluidas por el documento. En caso contrario, las referencias a entidades externas son ignoradas. RemoveWhiteSpaces Esta propiedad booleana(1/0) indica si deben eliminarse los espacios en blanco, tabuladores y finales de línea del inicio y fin del valor de un nodo de tipo TEXT o ELEMENT. El valor por defecto es TRUE(1). RemoveWhiteNodes Esta propiedad booleana(1/0) indica si deben pasarse por alto los nodos de tipo WhiteSpace al procesar un documento. El valor por defecto es TRUE(1). SimpleElements Esta propiedad determina si los elementos con una estructura simple como la siguiente: <elemento>valor</elemento> o <elemento/> son procesados como un único nodo de tipo Element. El valor por defecto es TRUE(1). ValidationType(.NET y Java) Esta propiedad determina como se va a validar el XML leído. Los valores posibles son: 0 – No se realiza validación 1 – Validación automática 2 – Validación por medio de DTD 3 – Validación por medio de un “Schema” 4 – Validación por medio de XDR (Solo .NET) StopOnInvalid(Solo .NET) Esta propiedad booleana(1/0) indica si el parser tiene que parar cuando detecta un error de validación, pero el xml está bien formado. Si el valor es 0 el método Read() retornará 1 aunque haya habido un error de validación y la forma de detectar el error es controlando el valor de la propiedadErrCode. El valor por defecto es TRUE(1). Soporte para Namespaces En esta sección se describen las funcionalidades disponibles para procesar documentos XML que utilizan namespaces. MÉTODOS Los siguientes métodos retornan los distintos componentes del nombre de un atributo indicado por <Index>. Sólo son válidos para nodos de tipo Element. Las posiciones se numeran desde 1. GetAttributeName(<Index>) GetAttributePrefix(<Index>) GetAttributeLocalName(<Index>) GetAttributeURI(<Index>) <Index> - Integer PROPIEDADES Las siguientes propiedades sólo son válidas para nodos de tipo Element y EndTag. Name Retorna el nombre completo prefijo:nombrelocal. Prefix Retorna el prefijo que representa al namespace del nombre. LocalName Retorna el nombre sin el prefijo que representa al namespace. NameSpaceURI Retorna el URI usado para identificar al namespace. Cuando un elemento no está calificado con un namespace, las propiedades Name y LocalName coinciden. Entity references Por defecto, tanto las entidades internas como externas son procesadas automáticamente reemplazando las referencias por sus valores. El procesamiento de las externas sin embargo puede ser desactivado usando la propiedad ReadExternalEntities. Se dispone además de las siguientes funcionalidades: MÉTODOS Los siguientes métodos permiten acceder a la notación y entidad referenciadas por un atributo de tipo ENTITY. El atributo puede especificarse por medio de su posición en el texto o por su nombre y no se verifica que sea de tipo ENTITY. Si ninguna declaración fue hecha en el DTD del documento para el valor atributo se devuelve una cadena vacía. Sólo son válidos para nodos de tipo Element. Las posiciones se numeran desde 1. GetAttEntityValueByIndex(<Index>) GetAttEntityValueByName(<Name>) GetAttEntityNotationByIndex(<Index>) GetAttEntityNotationByName(<Name>) <Index> <Name> Integer Character Ejemplo Se tiene el siguiente documento XML, llamado Reunion.xml <?xml version="1.0" encoding="ISO-8859-1" ?> <REUNION Fecha="06/03/01"> <FECHA>06/03/01</FECHA> <!-- Descrpción de la reunión--> <![CDATA[ Reunion del equipo de desarrollo de la aplicación. <INTEGRANTES> La reunión fue realizada el Viernes a las 9:30 horas.]]> <INTEGRANTE>Juan Pedro</INTEGRANTE> <INTEGRANTE>Laura</INTEGRANTE> <INTEGRANTE>Diego</INTEGRANTE> <INTEGRANTE>Florinda</INTEGRANTE> </INTEGRANTES> <TAREAS> <TAREA> <RESPONSABLE>Juan Pedro</RESPONSABLE> <![CDATA[ Realizar la documentción de la aplicación]]> </TAREA> <TAREA> <RESPONSABLE>Florinda</RESPONSABLE> <![CDATA[ Reunion con los clientes.]]> </TAREA> <TAREA> <RESPONSABLE>Laura</RESPONSABLE> <![CDATA[ Realizar el maunal de usuario]]> </TAREA> <TAREA> <RESPONSABLE>Diego</RESPONSABLE> <![CDATA[ Documentar las especificaciones.]]> </TAREA> </TAREAS> </REUNION> Este procedimiento GeneXus lee el archivo y obtiene los integrantes de la reunión. &readfile.open(‘Reunion.xml’ ) &readfile.ReadType(1, 'INTEGRANTES') &readfile.read() do while &readfile.name <> 'INTEGRANTES' &Integrante = &readfile.value &readfile.read() enddo &readfile.close() Este procedimiento GeneXus lee el archivo y obtiene las tareas de un integrante de la reunión. &readfile.open(‘Reunion.xml’) &exito = &readfile.ReadType(1, 'RESPONSABLE') do while &readfile.value <> &Integrante &exito= &readfile.ReadType(1, 'RESPONSABLE') If &exito = 0 Exit Endif enddo If &exito <> 0 &readfile.read() &tareas = &readfile.value else &tareas = Nullvalue(&tareas) Endif &readfile.close() Consideraciones generales   Para el generador Java sólo se implementó la validación por medio de DTD El método AddSchema solo está implementado para el generador .NET Glosario Las siguientes definiciones fueron extraídas de “Extensible Markup Language (XML) 1.0 (Second Edition)”; por más información referirse a http://www.w3.org/TR/2000/REC-xml-20001006; y para el caso de los Namespaces referirse a http://www.w3.org/TR/1999/REC-xml-names-19990114/  Character data: Markup takes the form of start-tags, end-tags, empty-element tags, entity references, character references, comments, CDATA section delimiters, document type declarations, processing instructions, XML declarations, text declarations, and any white space that is at the top level of the document entity (that is, outside the document element and not inside any other markup). All text that is not markup constitutes the character data of the document.  Entities: An XML document may consist of one or many storage units. These are called entities; they all have content and are all (except for the document entity and the external DTD subset) identified by entity name. Entities may be either parsed or unparsed. A parsed entity's contents are referred to as its replacement text; this text is considered an integral part of the document. An unparsed entity is a resource whose contents may or may not be text, and if text, may be other than XML. Each unparsed entity has an associated notation, identified by name. Beyond a requirement that an XML processor make the identifiers for the entity and notation available to the application, XML places no constraints on the contents of unparsed entities. Parsed entities are invoked by name using entity references; unparsed entities by name, given in the value of ENTITY or ENTITIES attributes.  Entity reference: Refers to the content of a named entity.  CDATA sections may occur anywhere character data may occur; they are used to escape blocks of text containing characters which would otherwise be recognized as markup. CDATA sections begin with the string "<![CDATA[" and end with the string "]]>".  Processing instructions (PIs) allow documents to contain instructions for applications.  Standalone document declaration: Markup declarations can affect the content of the document, as passed from an XML processor to an application; examples are attribute defaults and entity declarations. The standalone document declaration, which may appear as a component of the XML declaration, signals whether or not there are such declarations which appear external to the document entity or in parameter entities.  Document type declaration: XML provides a mechanism, the document type declaration, to define constraints on the logical structure and to support the use of predefined storage units. An XML document is valid if it has an associated document type declaration and if the document complies with the constraints expressed in it. The XML document type declaration contains or points to markup declarations that provide a grammar for a class of documents. This grammar is known as a document type definition, or DTD. The document type declaration can point to an external subset (a special kind of external entity) containing markup declarations, or can contain the markup declarations directly in an internal subset, or can do both. The DTD for a document consists of both subsets taken together.  XML namespaces provide a simple method for qualifying element and attribute names used in Extensible Markup Language documents by associating them with namespaces identified by URI references. Tipo de Datos WebWrapper Introducción WebWrapper es un tipo de datos de GeneXus que permite encapsular la ejecución de los objetos Web (el código HTML generado). En particular permite enviar el contenido de un Web Panel por mail. Aplica a los siguientes objetos: Transacciones, Web Panels y Procedimientos, tanto para el generador Java como .NET. Descripción Para poder enviar el contenido de un Web Panel vía mail desde un objeto GeneXus es necesario definir una variable de tipo WebWrapper, para luego aplicar los métodos y propiedades necesarios. La idea es capturar el contenido de un Web Panel en su código HTML, y enviar éste vía mail, por lo tanto hay que tener en cuenta que el cliente de correo que reciba el mail debe tener la capacidad de interpretar lenguaje HTML, en caso contrario verá el código del Web Panel. PROPIEDADES BaseURL: Es la dirección Base del Web Panel. La dirección base determina el servidor y directorio virtual al que apuntarán los links y a donde se irá a buscar el Web Panel en caso de que se presione algún botón. La dirección base es agregada al código HTML que devuelve el método GetResponse. Object: Objeto Web a encapsular en la variable de tipo WebWrapper. A la propiedad Object debe asignársele siempre el resultado de la función Create: Create(Objeto, Parámetros) MÉTODOS GetResponse: Retorna el código HTML que devolvería el objeto Web especificado en la propiedad Object con los parámetros allí indicados. Ejemplo El siguiente ejemplo es un procedimiento que ilustra como enviar por mail, mediante Outlook, el Web Panel Hnotify para cada registro de la tabla USERS. Dicha tabla tiene clave primaria UserId, el cual se pasará como parámetros al Web Panel Hnotify. También tiene entre sus atributos secundarios a UserName, con el nombre del usuario, y UserMail, con la dirección de correo el electrónico del usuario. Variables Definidas: &Wrap del tipo WebWrapper &MailMsg del tipo MailMessage &Outlook del tipo OutlookSession &Wrap.BaseURL = “http://myserver/mysystem/” For each UserId &Wrap.Object = Create(Hnotify, UserId) &MailMsg.To.New(UserName, UserMail) &MailMsg.HTMLText = &Wrap.GetResponse() &Oulook.Send(&MailMsg) EndFor Consideraciones Generales Los objetos Web Panel de GeneXus, no son estáticos, por este motivo al enviarlos vía mail, en realidad se está enviando una imagen estática. Por lo tanto cualquier evento que se produzca en el Web Panel que realice un post al servidor (por ejemplo hacer clic en un botón, disparar un procedimiento, etc.) producirá que se abra el Web Panel en el browser, en la dirección especificada en la propiedad BaseURL. Si se desea hacer un WebWrapper de un Web Panel que incluya imágenes, se puede hacer de dos maneras:  Poner en el Web Panel las imágenes en forma absoluta, el inconveniente de esto es que el usuario debe estar conectado en el momento de leer el mail.  Poner en el Web Panel las imágenes relativas y mandarlas como archivos adjuntos en el mail. En este caso la ruta de la imagen no debe incluir directorios (por ej.: /imágenes/logo.jpg) si no hacer referencia directamente a la misma (por ej.: logo.jpg). Si se utiliza un objeto WebWrapper para mandar un Web Panel mediante mail, y dicho Web Panel tiene un botón o evento clic, el comportamiento al apretar dicho botón (o control con evento clic) en Outlook XP difiere del de Outlook 2000 y Outlook Express. En Outlook 2000 y Outlook Express el comportamiento es el esperado: se abre un browser, se hace el post al servidor Web, y en el browser se muestra la respuesta (incluso puede haber una redirección, call o link, en el evento). En Outlook XP el comportamiento es el siguiente: el post lo hace el propio Outlook (no se abre un browser para hacer el post). Luego se abre un browser haciendo un get de la página para mostrarla. Pero dicho get se hace solamente si no había una redirección en el evento que ejecutó el post. (De todas formas, el evento se ejecuta siempre). Por ejemplo, si se tiene un evento asociado a un botón que graba algo en la base de datos y asigna cierto valor a una variable que está en el form. En Outlook 2000 y Outlook Express, al apretar dicho botón en el mensaje se ejecutará el evento, por lo que se hará el cambio a la base de datos, y se abrirá un browser donde se verá en el form la variable con el valor que se le asignó en el evento. En Outlook XP se ejecutará el evento, haciendo el cambio en la base de datos, pero el form de respuesta nunca se mostrará. Luego se abrirá un browser donde se desplegará el form sin modificar la variable. Otro ejemplo: el evento asociado al botón modifica la base de datos y hace un call a otro Web Panel. En Outlook 2000 y Outlook XP, al apretar el botón se hace la modificación a la base de datos y se abre un browser donde se muestra el Web Panel llamado. En Outlook XP se hace la modificación a la base de datos pero no se muestra nada, ni siquiera se abre el browser. Hay dos formas en las cuales podemos cambiar nuestra programación para asegurarnos de que el comportamiento sea el mismo en los 3 clientes de mail: 1) No usar eventos. Siempre se pueden usar links. 2) Usar un Web Component. Es decir, el Web Panel que se manda por email está compuesto solamente por un Web Component. Dicho Web Panel tendría el evento Refresh similar al siguiente: Event Refresh if base de datos fue modificada webcomponent.object = create(HGracias, pars...) else webcomponent.object = create(HMailForm, pars...) endif End Event En el evento de usuario de HMailForm se haría la modificación a la base de datos por la cual se chequea en la condición. HGracias es el Web Panel al cual se quería hacer la redirección al procesar el evento. INTRODUCCIÓN Los objetos GeneXus pueden comunicarse entre ellos o con otros programas externos. Un objeto GeneXus puede llamar a, o ser llamado por, otro objeto pudiendo intercambiar información a través de parámetros. En el siguiente cuadro se muestran las invocaciones válidas entre los distintos objetos Web. C:\Documents and Settings\jiriarte\Desk top\cursointernet90\C ursoInternet90\C urso_no_presencial_'Desarrollo_de_aplicaciones_para_Internet_con_GeneXus'\14_ComunicacionentreObjetos\01_Introduccion_files\image001.g if Nota: Es importante tener en cuenta que no todas las combinaciones siempre son válidas. Verificar las combinaciones válidas en el documento Invocación desde un objeto a otro. Invocación desde un objeto a otro Para invocar desde un objeto Web GeneXus a otro objeto GeneXus o programa externo, contamos con el comando/regla CALL, el comando/función LINK y la función UDP:  CALL – Es una regla o comando (ya que dependiendo del objeto GeneXus en el que se vaya a usar, se podrá escribir en la sección de reglas, eventos, u otra parte del objeto) para llamar a un objeto GeneXus o a un programa externo, siendo posible pasarle parámetros. UDP – (User Defined Procedure) Es una función que permite llamar a un objeto GeneXus o programa externo al cual se le podrán pasar parámetros, y retornará al menos un valor como resultado de su ejecución.   LINK - El comando o función link es equivalente al comando CALL para llamar a páginas estáticas o redireccionar a una URL. Este comando puede ser utilizado dentro de cualquier evento de un objeto Web con excepción del evento Load. El resultado de la utilización de este comando es el redireccionamiento en forma automática a la URL especificada dentro del mismo. Tanto al utilizar CALL como UDP para invocar desde un objeto GeneXus, a otro objeto GeneXus o programa externo, cuando se ejecute la invocación, se pasará el control al programa llamado, y al finalizar éste su ejecución, devolverá el control al llamador en el caso en que el objeto llamado no tenga form, retornándole parámetros si los hay. Si el objeto al cual se invoca tiene salida en pantalla, este último pasa a tener el control total, por lo tanto si tenía código por ejecutar el llamador luego de esta invocación, no se ejecutará. Es importante tener en cuenta que los objetos Web ejecutan en el servidor y por consiguiente no pueden realizar llamadas a programas externos que tengan salida en pantalla, ya que la ejecución de dicha llamada cancelaría por time-out. En resumen, desde un objeto Web, se puede llamar a otro objeto Web o a un Procedimiento o Reporte que no tengan salida en pantalla. Utilizando CALL, se puede invocar a un objeto GeneXus o programa externo, tanto sin pasarle parámetros, como pasándole. Y utilizando UDP, es posible invocar a un objeto GeneXus o programa externo, con la particularidad de que el programa llamado retornará necesariamente al menos un valor al programa que lo invocó. El comando LINK permite llamar a páginas estáticas o redireccionar a una URL y en el caso que corresponda permite pasarle parámetros. Sintaxis Link( usr-pgm | ’url’ [{parm1, parmn}…] ) Donde: usr-pgm: es el nombre del objeto Web al que se va a redireccionar. <URL> : es el nombre de la URL a la que se va a redireccionar. <parm1>...<parmn>: son los parámetros que recibe la URL. El pasaje de parámetros es opcional. Por ejemplo: Event ENTER Link(‘http://www.ARTech.com.uy’) Endevent Consideraciones Los Procedimientos pueden invocar Web Panels y Transacciones Web. Si el Procedimiento ha sido invocado desde un Web Panel o una Transacción Web o vía HTTP (por ej.: con la propiedad “Call Protocol” en “HTTP”), podrá también invocar con un CALL o LINK a una URL HTTP (por ej.: llamar a un Web Panel o a una Transacción Web). Se debe considerar que dicha invocación no será ejecutada sincrónicamente. Será ejecutada como un redireccionamiento al objeto invocado al final de la ejecución Web. Un procedimiento llamado desde la línea de comando, por ejemplo, no puede invocar a un Web Panel. Pero sí se puede utilizar la función opendocument() para abrir una URL en el browser. Ejemplo En este ejemplo se muestra como se realiza la ejecución de distintos objetos cuando desde un procedimiento se invocan Web Panels o Transacciones Web. Procedimiento prc01: call(hwbp01) for each A=B endfor Procedimiento pproc02: call(hwbp01) .. call(hwbp02) Event 'one' pprc01.call() EndEvent Resultado: El Web Panel hwbp01 será ejecutado antes del "endevent", después del for each. Event 'two' pprc02.call() EndEvent Resultado: El Web Panel hwbp02 será ejecutado antes del "endevent". Event 'three' pprc02.call() hwbp03.call() EndEvent Resultado: El Web Panel hwbp03 será ejecutado antes del "endevent". ¿Por qué funciona de esta forma? Internamente, en cada sentencia call se setea una variable interna con el nombre del objeto al cuál, al final de la ejecución en el servidor, la redirección irá. INTRODUCCIÓN En este capítulo veremos los requerimientos necesarios para los generadores .NET y Java. Tanto para el desarrollo de aplicaciones Web como para la puesta en producción. También profundizaremos en las propiedades necesarias para una aplicación Web, ya sean propiedades propias de cada generador como también propiedades independientes del generador. Requerimientos .NET Además de los requerimientos básicos de GeneXus 9.0 (espacio en disco, cantidad de memoria, etc.) para cada equipo de desarrollo, se debe contar con el software mencionado a continuación. Plataforma .NET Para el desarrollo de aplicaciones es necesario instalar: Release del Framework Redistributable 1.1 y J# Version 1.1 Redistributable Package o Release del Framework Redistributable 2.0 y J# Version 2.0 Redistributable Package El Visual J# es requerimiento para los reportes PDF de las aplicaciones Web. Manejador de base de datos SQL Server ADO.NET utiliza el Data Provider de Microsoft para SQL Server (el cual se instala con el Framework). No se requiere el cliente SQL Server. Oracle Se debe tener el Cliente de Oracle versión 8.1.7.5 o superior, de esta forma se instala el Data Provider correspondiente. El valor “Server Name” de las DBMS option hace referencia al Service Name definido en la instancia del Oracle. La implementación utiliza el Data provider de Microsoft para Oracle (System.Data.OracleClient), el cual requiere el cliente. DB2 UDB for iSeries Se necesita la V5R3 del iSeries Client Access con un service level igual o superior a SI20055. La menor versión testeada del server es la V5 R1. Se puede obtener desde:http://www-03.ibm.com/servers/eserver/iseries/access/casp.html Al crear un modelo se debe copiar la dll IBM.Data.DB2.iSeries.dll al directorio gxnet/bin. DB2 Universal Database Se necesita tener instalada la versión 8.1.3 o superior. La dll es IBM.Data.DB2.dll, se debe copiar a los directorios gxnet/bin. MySQL MySQL soporta diferentes motores, GeneXus utiliza el InnoDB (http://dev.mysql.com/doc/mysql/en/InnoDB.html). La menor versión soportada del server es 3.23.58. El driver cliente para .NET se puede obtener desde: http://sourceforge.net/projects/mysqldrivercs. Luego de instalado se debe tener los archivos:   Informix No tiene acceso ADO.NET, se debe acceder con ODBC. La versión del DBMS puede ser 7.0 o Informix Foundation 2000. En el cliente debe estar instalado el cliente con la versión correspondiente. Se recomiendan los drivers de Intersolv o Informix. mysql.dll – Biblioteca .NET de acceso a MySQL. MySQLDriverCS.dll se debe copiar bajo el directorio gxnet/bin. PostgreSQL No tiene acceso ADO.NET, se debe acceder con ODBC. Servidor Web Se deberá contar con el servidor Web Internet Information Server 5.0 o superior. IMPORTANTE: El mismo debe ser instalado antes del .NET Framework. INTRODUCCIÓN Existe una API especificada por Sun Microsystems que se llama “Java Servlet API”. Esta API define la forma de ejecutar lo equivalente a los objetos Web de GeneXus, por lo tanto, el generador Java, por cada objeto Web de GeneXus, genera lo que se llama un Servlet. Los Servlets proveen una gran cantidad de ventajas que el generador Java aprovecha, como por ejemplo, la utilización de un pool de conexiones a la base de datos y la multiplataforma. A su vez, el generador Java provee una funcionalidad adicional que consiste en que los objetos Web pueden enviar la página HTML comprimida, para que sea descomprimida en tiempo real por el browser. La compresión se realiza sólo si el browser indica que es capaz de descomprimirlo. Esta opción puede deshabilitarse con la propiedad “Auto Compress HTTP Traffic”, para contemplar el hecho de que algunos browsers no reporten correctamente su capacidad para descomprimir las páginas, y no las puedan desplegar correctamente. En las pruebas que hemos realizado, esta funcionalidad se ha comportado de forma correcta con todos los browsers. Requerimientos Java Además de los requerimientos básicos de GeneXus 9.0 (espacio en disco, cantidad de memoria, etc.) para cada equipo de desarrollo, es necesario contar con cierto software de desarrollo Java para la compilación y ejecución de las aplicaciones generadas y el software necesario para el acceso a la base de datos (drivers JDBC). JDK/JRE (Java Development Kits Compiladores y Máquinas Virtuales) Para la compilación y ejecución de los programas es necesario contar con alguno de los Development Kits del mercado. Los principales son los de Sun, Microsoft e IBM. Si bien no es requisito tener todos los Development Kits, es recomendable. JDK DE SUN Para instalar el JDK de Sun, se debe bajar del Web site de Sun la última versión del JDK para Win32, ejecutar el EXE descargado, y seguir las instrucciones. SDK DE MICROSOFT El SDK de Microsoft no está disponible en internet ni se comercializa más. En ese caso se podrá usar el compilador del JDK de Sun (javac.exe), que es gratuito. Para determinar si el intérprete está instalado, puede ejecutarse lo siguiente: C:\WINDOWS\system32>jview Se mostrará la versión disponible del compilador y de la máquina virtual, respectivamente, por ejemplo: Cargador de línea de comandos de Microsoft (R) para Java Versión 5.00.3810 Copyright (C) Microsoft Corp 1996-2000. Todos los derechos reservados. Uso: JView [opciones] <classname> [argumentos] Opciones: /? /cp <ruta de clase> /cp:p <ruta> de clase muestra texto de uso establece la ruta de clase antepone la ruta a la ruta /cp:a <ruta> clase /n <nombre del espacio> ejecutar /p ocurre un error /v /d:<nombre>=<valor> sistema /a agrega ruta a la ruta de nombre del espacio en el que pausa antes de finalizar si comprueba todas las clases define las propiedades del ejecuta AppletViewer Nombre de clase: Archivo .CLASS a ejecutar. Argumentos: Argumentos de la línea de comandos para pasar al archivo de clase Generalmente el intérprete de Microsoft ( jview.exe ) es parte de la instalación de todas las plataformas Windows, aunque no esté instalado el SDK de Microsoft. Si no está disponible o está desactualizado (esto es, con una versión anterior al 5.00.3805), entonces se puede obtener con Windows Update. La otra alternativa es usar el intérprete de Sun, java.exe, que forma parte del SDK de Sun. Por razones de performance, se recomienda fuertemente utilizar el compilador de Sun ( javac.exe ) conjuntamente con el intérprete de Microsoft ( jview.exe ). COMPILADOR JIKES DE IBM IBM provee sólo el compilador Java, en forma open-source. Para instalarlo, se debe bajar la versión para windows, que es un archivo zip. Para la instalación simplemente se debe descomprimir el zip hacia una carpeta, y mover ésta hacia donde quiera hacerse la instalación. El directorio de instalación contendrá dos subdirectorios: bin, que tiene el compilador (jikes.exe) y doc, que contiene instrucciones de uso y licencia. Para poder utilizar este compilador es necesario que esté instalada alguna versión del JDK de Sun, dado que requiere de sus bibliotecas de clases. En cuanto a las versiones de este software se recomienda utilizar las últimas liberadas de cada uno de ellos, pero no versiones beta. Driver JDBC Los drivers JDBC (equivalentes a ODBC) permiten efectuar conexiones con bases de datos. Existen cuatro tipos de driver JDBC que se detallan a continuación. Dependiendo del DBMS y del tipo de acceso a la base de datos que se utilice, puede ser necesario obtener uno u otro tipo de driver JDBC. Generalmente se utilizan los drivers de tipo 4, que se presentan a continuación junto con otros tipos de driver. Los números de tipos de driver corresponden a una numeración que fijó SUN. Tipo 1: Java -> ODBC Esta arquitectura, tiene como ventaja importante que permite la utilización de drivers ODBC existentes, pero la desventaja de que hay que instalarlos en cada máquina, así como el cliente de DBMS. De esta forma, en el cliente se requiere:    DRIVERS JDBC DRIVERS ODBC (se crea un Data Source con la información de conexión) CLIENTE DBMS La aplicación GeneXus-Java se comunica con los DRIVERS JDBC. A los DRIVERS JDBC se les configura un parámetro para indicar que la conexión es a cierto Data Source. Y finalmente con la información definida en el Data Source, se establece la conexión del cliente con el Servidor Manejador de Base de Datos (DBMS). Las implementaciones actuales de estos drivers no son muy fiables, por lo que no se recomienda su utilización en ambientes de producción. Sin embargo, existe un caso por el cual utilizar el driver tipo 1: algunas versiones de AS/400 no soportan los dirvers JDBC, de modo que la única forma de implementar una aplicación Java en 2 capas, en esos casos, sería mediante este tipo de driver llamado también Bridge JDBC-ODBC. Tipo 2: Java -> Protocolo DBMS Con esta implementación, en el cliente se tienen los DRIVERS JDBC que se comunican directamente (en forma nativa) con el CLIENTE Oracle, Sybase, Informix, DB2, o cualquier otro DBMS. De esta forma, entonces, al igual que el driver de tipo 1, este también requiere que se instale en cada máquina cliente, los DRIVERS JDBC y CLIENTE DBMS. En general los drivers tipo 2, también llamados Native-API Partly-Java, se comunican muy rápido con la base de datos, siendo en teoría, los más performantes. Salvo por ésto, este tipo de driver no presenta demasiadas ventajas con respecto a las otras alternativas. Tipo 3: Java -> Servidor JDBC Esta clase de driver traduce llamadas JDBC en un protocolo de red independiente del DBMS y luego, a un protocolo de DBMS. Un Servidor JDBC, realiza la tarea de middleware, siendo capaz de conectar un cliente Java a diferentes bases de datos. La implementación del Servidor JDBC se realiza mediante la instalación de un software que sabe “escuchar” los requerimientos del CLIENTE JDBC y traducirlos a llamadas nativas para los DBMSs. Una ventaja que posee el driver tipo 3, también conocido como net-protocol all-Java, es que no requiere instalación en los clientes, según el DBMS. Como contrapartida, este driver requiere la instalación del Servidor JDBC. Merant DataDirect SequeLink Java Edition es un driver de tipo 3 que se ha probado para SQL Server y Oracle. Nota: Para ejecutar Applets, en 2 capas, si se utiliza el driver tipo 3, el Servidor JDBC deberá encontrarse en el mismo host que el Servidor Web, por ser el Servidor JDBC el que resolvería la conexión. En este caso, sería posible efectuar conexión con un DBMS que no se encuentre en el mismo host que el Servidor Web. Tipo 4: Java -> DBMS El driver tipo 4 convierte llamadas JDBC directamente en el protocolo de red usado por el DBMS. Esto permite llamadas directas desde la máquina del cliente al servidor del DBMS y es una solución práctica para el acceso a Intranets. Requieren más código, por lo que si se usa en 2 capas hay que bajar más código al cliente, y la performance suele ser algo menor que la de los otros drivers (esto puede depender mucho del driver, de la cantidad de conexiones simultaneas, etc). De todas formas, este es el tipo de driver más común, y el que se usa más en general. Dado que muchos de estos protocolos son propietarios, los proveedores de bases de datos son la principal fuente de este tipo de driver. Algunos ejemplos son:     I-net Software WebLogic jDriver AsToolBox Merant El driver tipo 4, también denominado native-protocol all-Java, no requiere instalación en los clientes, según el DBMS. Nota: Para ejecutar Applets, en 2 capas, si se utiliza el driver tipo 4, el DBMS deberá encontrarse en el mismo host que el Servidor Web pues no se permite a un Applet establecer una conexión con otra máquina que no sea el servidor de donde provino. Browser Para utilizar el generador Java, no es necesario tener ningún un browser instalado, sin embargo, se recomienda tener tanto Internet Explorer como Netscape para probar el correcto funcionamiento de las aplicaciones. Dependiendo de la versión del Java Development Kit que se utilice, el browser puede requerir el Java Plug-In, por lo que sería necesario disponer de este software también. Visualización de Reportes Para poder visualizar reportes PDF desde el browser, debe tenerse instalado Adobe Acrobat Reader. Para poder ejecutar Servlets, es necesario contar con:    Un Servidor Web Un Motor de Servlets JavaServer Web Development Kit El Servidor Web y Motor de Servlets, son dos servicios que se requieren (en un mismo servidor físico, o no) para poder ejecutar Servlets. En teoría, las aplicaciones GeneXus pueden ejecutarse con cualquier Motor de Servlets que sea compatible con la especificación de Servlets 2.1 o posterior. Algunos de los motores que se han utilizado exitosamente son:      IBM WebSphere en Windows, RS/6000, Unix OS/390, Linux y AS/400 JRun en Windows Jakarta Tomcat en Windows y Linux Resin en Windows y Linux Apache Jserv en Windows y Linux Por su parte, el JavaServer Web Development Kit, se instala automáticamente con la instalación del Motor de Servlets, y permite que el desarrollador pueda compilar los Servlets (objetos Web de GeneXus). A continuación explicaremos los pasos en orden, que se deben seguir para configurar y utilizar estos requerimientos. Explicaremos en forma conceptual y genérica cada punto, y tomaremos a modo de ejemplo, la opción de utilizar el Motor de Servlets RESIN para Windows, en forma local, con el fin de mostrar un ejemplo práctico concreto. Configuración de un Motor de Servlets Para ejecutar una aplicación Web Java, se debe configurar un motor de servlets; para ello se deben realizar algunos pasos, que si bien varían un poco según el motor de servlets que se vaya a utilizar, básicamente los pasos a seguir, son similares. Primeramente, vamos a introducir el concepto de “Webapp”, relacionado a los motores de servlets. Qué es una Webapp? Cada motor de servlets crea y maneja una “Webapp”. El nombre Webapp resulta de la abreviación de "Web application" y consiste en un directorio base, que contiene a su vez una estructura de subdirectorios determinada, en la cual se deben distribuir los archivos que sean necesarios para la ejecución de una aplicación Web. Los tipos de archivos involucrados en la ejecución de una aplicación Web, pueden ser los servlets (archivos .class), contenido estático y librerías adicionales (archivos .JAR). Pasos a seguir Una vez visto este concepto, pasemos a detallar entonces los pasos a seguir para configurar un motor de servlets: 1) Instalar el motor de servlets. 2) Definir una Webapp o bien identificar cuál es la Webapp por defecto para utilizarla. 3) Copiar drivers JDBC y clases standard de GeneXus (gxclassr.zip) al directorio “lib” de la Webapp. 4) Levantar el motor de servlets. 5) Tests: a. Ejecutar el servlet de ejemplo del motor de servlets, para comprobar que la instalación haya sido correcta, así como comprobar que el motor haya levantado bien. b. Ejecutar el servlet: com.genexus.Webpanels.gxver, que devuelve la versión de las clases standard de GeneXus. Mediante la ejecución de este servlet se puede comprobar primeramente que se están encontrando las clases standard de GeneXus y luego, que se trata de la misma versión con las que se generaron los servlets. A modo de ejemplo, si se utiliza RESIN en Windows, en forma local, se deben seguir los siguientes pasos: 1) Instalar el motor de servlets: para ello, simplemente se debe descomprimir un archivo de instalación .ZIP en algún directorio del equipo servidor (por ejemplo en c:\resin). La Webapp por defecto en este caso, es: C:\resin\doc\ 2) 3) Copiar las clases standard de GeneXus (gxclassr.zip) y las clases del driver JDBC al directorio C:\resin\doc\WEB-INF\lib Para levantar el motor de servlets, se debe ejecutar c:\resin\bin\httpd.exe. Tests: a. Para verificar que el RESIN haya levantado bien, se debe ejecutar el servlet que viene de ejemplo accediendo de la siguiente forma: http://localhost:8080/examples/basic/servlet/HelloServlet b. Para verificar que se estén tomando las clases standard de GeneXus y cuál versión, se debe ejecutar: http://localhost:8080/servlet/com.genexus.Webpanels.gxver 4) 5) Propiedades de ejecución .NET A continuación se detalla el significado de cada una de las opciones que figuran en el diálogo de configuración de la opción del menú Build / Run (F5). Compiler Path: Determina el path del compilador (csc.exe), este se encuentra bajo el directorio de instalación del Framework en: C:\WINNT\Microsoft.NET\Framework\v1.1.4322 Virtual Directory: Determina la URL base de ejecución, esta contiene el directorio virtual a ser creado (si no existe) por GeneXus en el Internet Information Service (IIS) local. El momento de la creación es luego de la compilación y reorganización. Propiedades de ejecución Java Para la ejecución de aplicaciones Web con Java, se debe configurar las siguientes propiedades: Platform Se debe seleccionar el ambiente de compilación y ejecución, es decir cuál Java Development Kit se utilizará. Las posibilidades son:    Microsoft SDK Sun JDK IBM’s Jikes Compiler Classpath En classpath se referencian las clases necesarias para compilar los servlets (clases correspondientes al JavaServer Web Development Kit). El archivo puede llamarse servlet.jar o jsdk.jar o jsdk22.jar (dependiendo del Motor de Servlets que se utilice) y por lo general se encuentra en el subdirectorio Lib del Motor de Servlets. Estas clases se deben referenciar en el classpath, además, del resto de los archivos de clase que se requieran referenciar en dicha variable de entorno. Compiler Path En el Compiler path se especifica la ubicación del compilador Java a utilizar. El compilador del Development Kit de Sun se llama javac.exe, mientras que el compilador del Development Kit de Microsoft se llama jvc.exe. Ambos compiladores se encuentran en el subdirectorio BIN del JDK / SDK. El compilador del Development Kit de IBM, por su parte, se llama jikes.exe. Make Path Aquí se debe especificar la ubicación del programa de make que se desea utilizar. La función del programa de make es procesar los archivos .mak, que indican las precedencias entre archivos para compilar. Microsoft provee un programa de make (sin costo) llamado nmake.exe, que es el que se recomienda usar. Sun no provee un programa de make, por lo que para compilar con el JDK de Sun se puede utilizar el programa de make de otros proveedores, como el de Microsoft. Si se opta por compilar con Jikes de IBM se sugiere utilizar el programa de make que provee Microsoft. Interpreter path El intérprete de Sun se llama java.exe mientras que el de Microsoft se llama jview.exe. Ambos intérpretes se encuentran en el subdirectorio BIN del JDK / SDK. El intérprete de Microsoft es uno los programas básicos provistos junto con el sistema operativo. Es decir, normalmente Windows incluye jview, en el directorio C:\WINDOWS\system32, independientemente de si el JDK está instalado o no. JIKES de IBM, por su parte, incluye solamente compilador. Si la ejecución es en Windows, se suele elegir el intérprete de Microsoft, de lo contrario el de Sun. Normalmente se recomienda utilizar plataforma y compilador de Sun, pero con el intérprete jview y el programa nmake, ambos de Microsoft. Web application base URL Este campo es para especificar la URL que el browser utilizará como base para la ejecución de los objetos Web. Propiedades avanzadas WEB BROWSER SETTINGS Esta sección aplica solamente a la ejecución de Applets. Si se marca la opción “Use Default Browser”, se ejecutarán los Applets utilizando el browser que se tenga por defecto en el sistema. Si no se marca dicha opción, se puede ingresar el path del browser a utilizar. Adicionalmente, los JDK/SDK’s incluyen un programa llamado appletviewer que permite ejecutar Applets. COMPILES OPTIONS Permite especificar parámetros que se desee pasar al compilador elegido cada vez que GeneXus lo llame. El compilador especificado en “Compiler Path” debe poder reconocer estos parámetros. Por defecto, está dado el parámetro “–O”, que permite generar código optimizado para la ejecución, sin información para el programador. Si se dispone del SDK de Sun y se desea ver las opciones posibles para el compilador, puede invocarse desde línea de comandos como: javac -help En la configuración más recomendada (plataforma y compilador de Sun, más intérprete y nmake de Microsoft), las opciones a pasar al compilador deben ser las siguientes: -O 1.1 -target INTERPRETER OPTIONS Análogo al anterior, permite especificar parámetros opcionales que quieran pasarse al intérprete. Con SDK de Sun, las opciones disponibles pueden verse con: java –help MAKE OPTIONS Permite especificar opciones para el comando make especificado en “Make Path”. Por ejemplo, si se utiliza el nmake de Windows, para ver las opciones disponibles, ejecutar desde una consola de DOS: nmake -help Propiedades a considerar en el desarrollo de objetos Web En los modelos GeneXus, existen propiedades que aplican exclusivamente a los objetos Web. Algunas a nivel del modelo de diseño por lo que aplican a toda la base de conocimiento y otras se encuentran a nivel de los generadores (por lo que aplican al modelo de prototipo o producción que lo utilice). Propiedades generales Estas propiedades se definen a nivel del modelo de Diseño. Se setean mediante la opción File / Edit Model / Properties teniendo abierto el modelo de diseño. Las relacionadas con objetos Web son:  Base Image Path Propiedades a nivel del Generador A nivel de cada modelo, existen algunas propiedades (en la sección Web Information) que aplican exclusivamente a los objetos Web. FOCUS CONTROL Esta propiedad permite determinar si los objetos Web, al mostrar su página, intentan posicionar el foco en el primer control de entrada (no read-only) o dejan librado al browser la posición del foco. Los valores posibles son:   First input att/var on the page Browser dependent Existe también la propiedad a nivel de objeto con los mismos valores que la propiedad del modelo y también el valor “Use model's property value”. PROTOCOL SPECIFICATION Esta propiedad permite especificar el protocolo a utilizar en la URL generada para invocar a los objetos Web. Tiene tres valores posibles:    Unsecure (HTTP) Secure (HTTPS) Do not specify El valor por defecto es “Unsecure (HTTP)”, que fuerza a generar HTTP como protocolo en la llamada al Web Panel e indica que el protocolo a utilizar es el Hypertext Transfer Protocol. El valor “Secure HTTPS”: fuerza a generar HTTPS como protocolo e indica que el protocolo a utilizar es el Secure Hypertext Transfer Protocol. Para utilizar este protocolo es necesario disponer de un servidor seguro. El valor “Do not specify” indica que no se especificará un protocolo particular, sino que se utiliza el mismo protocolo empleado para acceder al Web Panel actual. En el caso de tener aplicaciones con un esquema mixto: algunas páginas seguras y otras no, la propiedad del modelo deberá configurarse con el valor “Do not specify” y para cambiar el protocolo deberá hacerse un link al objeto indicando expresamente el protocolo a utilizar. ENCRYPT URL PARAMETERS Esta propiedad permite especificar si se desea encriptar los parámetros que se envían entre objetos y que son visibles en la URL del browser. Por más información referirse a la documentación: Encriptación de parámetros. ON REQUEST SSP SERVER DIRECTORY La propiedad “On request SSP server directory” es requerida cuando se generan SSP (Smart Static Pages) en forma dinámica. Por más información referirse a la documentación de Smart Static Panels. ON REQUEST SSP CLIENT URL La propiedad “On request SSP client URL” es requerida cuando se generan SSP (Smart Static Pages) en forma dinámica. Por más información referirse a la documentación de Smart Static Panels. BEFORE CONNECT La propiedad “Before Connect” ha sido implementada para cambiar las propiedades de la conexión en forma dinámica en tiempo de ejecución. Para utilizar esta característica, se requiere un Procedimiento GeneXus. Este Procedimiento debería establecer las propiedades de conexión en tiempo de ejecución; será ejecutado inmediatamente antes que el pedido de cualquier conexión sea ejecutado por la aplicación para interactuar con la base de datos. TEMP MEDIA DIRECTORY Esta propiedad se utiliza para configurar el path en el servidor Web en donde se salvarán temporalmente los archivos cuando se carguen en la base de datos. Esto ocurre, cuando un Blob es agregado o modificado, temporalmente se guarda en dicho directorio. Este directorio debe ser accesible desde el directorio virtual. AFTER CONNECT Esta propiedad permite llamar a un procedimiento GeneXus, inmediatamente después de ser asignada la conexión en una aplicación. Esta implementación permite apoyarse en los mecanismos de auditoría. EXPOSED NAMESPACE Por medio de esta propiedad se puede indicar el valor del namespace del SOAPAction del Web Service. Aplica a procedimientos con la propiedad “Call protocol” en “SOAP”. El valor por defecto es el nombre de la base de conocimiento pero es conveniente cambiarlo a un namespace que identifique a la empresa al momento de poner en producción el Web Service. Propiedades de .NET Estas propiedades se definen a nivel del modelo .NET y se setean mediante la opción File / Edit Model / Properties teniendo abierto dicho modelo. .NET aplication Namespace Determina el namespace de la aplicación. Los programas generados por GeneXus y compilados con .NET se encuentran disponibles bajo el namespace indicado por esta propiedad. El default es GeneXus.Programs. Sirve para los usuarios avanzados que quieren hacer algún tipo de deployment en el GAC (Global Assembly Cache). Valor por defecto: GeneXus.Program. Generate developer menu makefile Indica si se generaran los archivos necesarios para compilar el developer menú. El valor en “No” es útil para evitar el armado del makefile del developer menú, este es muy costoso ya que debe generar todos los response file (*.rsp) cada vez que se compila un objeto. Valor por defecto : “Yes”. Generate strong named assemblies Determina que los objetos main y/o dlls (assemblies) generados tengan un nombre único o no. Esto permite acceder a un conjunto de ventajas importantes que provee el .NET Framework, como deployment en el GAC o configuración de seguridad para el assembly. Valores: Yes: El programa generado tiene un “Strong Name”. No: El programa generado no tiene un “Strong Name”. Valor por defecto: “No” . Para generar el “Key” que identifica al objeto, el generador al momento de compilar busca un key.snk en el directorio dataxxx, si no hay: genera uno. (se requiere el SDK en el ambiente de desarrollo para ejecutar el sn.exe y generar el archivo con la Key). Además se debe configurar en la variable de ambiente “path” el camino a sn.exe para que la encuentre el compilador ("C:\PROGRAM FILES\MICROSOFT.NET\SDK\V1.1\bin"), de lo contrario da el error "Before compile error: The system cannot find the file specified" Los programas estándar provistos por el generador tienen strong names independiente del valor de la propiedad. Assemblie versión number Determina el número de versión a asignar a los assemblies que tienen strong name. La propiedad sólo aplica cuando la propiedad “Generate strong named Assemblies” está en “Yes”. Valor por defecto: 1.0.0.0 Compiler Flag La información de esta propiedad se incluirá en el .rsp que se usa para compilar los assemblies. Es útil por ejemplo, para generar información de debug (incluyendo el string “/debug”) o para incluir una dll dentro del namespace (/r:xxx.dll ). Config HttpHandlers Section La información de esta propiedad determina cómo se mapean los assemblies en ejecución. Valores: HttpHandler for each object: Una entrada en el web.config por cada assembly. Aquí se mapea el request del aspx con el assembly GeneXus.Programs.object (bin\object.dll). HttpHandlerFactory: Hay una sola entrada para todos los objetos en el web.config, en donde se indica un objeto al que pedirle el mapeo. ASHX: No hay mapeos en el web.config, se genera un archivo ashx por cada objeto que realiza el mapeo con el assembly GeneXus.Programs.object El valor HttpHandler for each object es más rápido en ejecución pero más lento en la carga inicial. Además permite tener objetos (*.aspx) no generados con GeneXus, con HttpHandlerFactory esto no es así. HttpHandlerFactory es más rápido para prototipar pero más lento en cada llamada porque el mapeo se resuelve en cada requerimiento. Esta opción puede enviar mensajes de error poco descriptivos, lo que dificulta la prototipación. El valor ASHX, es similar a Handler Factory, crea un archivo físico con el nombre del objeto y extensión ashx, el cual es invocado en ejecución. Valor por defecto: HttpHandler for each object Access Method Determina qué tipo de acceso se va a utilizar para acceder a la base de datos. El método de acceso especificado será utilizado para acceder a cada uno de los data stores. Valores: ODBC: Acceso vía ODBC ADO.NET: Acceso vía ADO.NET Valor por defecto: Depende del DBMS asociado al data store Default. Propiedad Enable Caching Esta propiedad permite definir si se habilita el “cache” de sentencias. Valores: Yes: Hablita el caching No: Deshabilita el caching Valor por defecto: “No”. Caching Section Las siguientes tres propiedades aplican cuando la propiedad “Enabled Caching” está en “Yes”. PROPIEDAD HARDLY EVER TTL (MINS) Cuando se lee una tabla que tiene en la “Propiedad Change frequency” el valor “Hardly Ever”, se mantiene en el “cache” durante el tiempo en minutos definido en esta propiedad. Valor por defecto: 600 PROPIEDAD TIME TO TIME TTL (MINS) Cuando se lee una tabla que tiene en la “Propiedad Change frequency” el valor “Time to Time”, se mantiene en el “cache” durante el tiempo en minutos definido en esta propiedad. Valor por defecto: 60 La diferencia entre la propiedad “Time to Time” y la propiedad “Hardly Ever”, es permitir definir distintos puntos de persistencia en las tablas del modelo. PROPIEDAD CHANGE FREQUENCY Si bien el “cache” se realiza a nivel de sentencia, es a nivel de tabla que se configura, permitiendo seleccionar el tiempo en que los datos van a persistir en memoria antes de ir a buscarlos nuevamente a la base de datos. Para poder configurar este tiempo se utiliza esta propiedad, que se configura a nivel de tablas, en modo de diseño. Valores: Almost Never: Se mantienen los datos en “cache” indefinidamente. Pretty Often: No se realiza “cache”. Hardly Ever: Valor que se define a nivel de modelo prototipo/producción. Time to Time: Valor que se define a nivel de modelo prototipo/producción. Valor por defecto: Pretty Often Log Level Esta propiedad permite configurar el nivel de trace de acceso a la base de datos con conexión ADO.NET. Valores: 0. Off 1. Fatal 2. Error 3. Warn 4. Info 5. Debug 6. All Valor por defecto: Off Esta propiedad escribe el tag <log4net threshold=...> del archivo web.config y client.exe.config (para modelos Web y Gui respectivamente). En el caso de modelos web también se escribe el tag <trace enabled=true />. Propiedad Maximum Cached cursors per connection Uno de los costos más importantes en las operaciones ODBC/ ADO.NET es el de preparar las sentencias SQL. La preparación incluye la compilación y validación de la sintaxis de dicha sentencia por parte del servidor. Los programas generados en .NET realizan un manejo inteligente de los cursores abiertos, de modo que no haya que volver a preparar cursores que ya fueron preparados. Para eso se mantiene un pool de cursores preparados, cuyo tamaño por defecto es de 100 cursores. Si se desea cambiar este número, se puede cambiar el valor de esta propiedad. Valor por defecto: 100 Propiedades del modelo Java A continuación se explican las propiedades que deben configurarse para la generación de aplicaciones Web con el generador Java.      Servlet Directory Static content base URL Static directory seen from client Auto compress web pages Generation Mode Propiedad Servlet Directory Para ejecutar los Servlets, una vez compilados, deben estar en un directorio específico de la estructura obtenida al instalar el Motor de Servlets. La misma varía en cada caso, dependiendo del Motor de Servlets que se utilice. Propósito Permite especificar el directorio donde se transferirán los Servlets generados. En tiempo de compilación de cada objeto Web, el generador los copiará al directorio especificado. Notas:  Es necesario especificar este valor antes de generar, ya que se utiliza para la generación del archivo de make.  El path debe ser relativo al cliente, es decir un path visto desde el PC en el que se está trabajando con GeneXus.  Se copiarán además de los archivos .class, los archivos .cfg, los cuales contienen la información de las propiedades ingresadas; por lo tanto, si se modifica algún valor de las propiedades del modelo, es necesario volver a generar y compilar algún objeto Web. Además, para que se tome en cuenta este cambio al ejecutar, es necesario reiniciar el servidor de servlets. Ejemplos de valores  H:\servlets - Si el motor de servlets está instalado en una máquina mapeada con el “drive” H y servlets es el nombre del directorio donde deben residir los servlets. C:\resin\doc\Web_inf\classes – Si el motor de servlets es el RESIN y esta instalado localmente en el directorio C:\resin.  Propiedad Static Content base URL Propósito Indica el directorio donde los servlets buscarán el contenido estático (imágenes, javascritps y styles.css) utilizado en los objetos Web correspondientes. Los servlets siempre ejecutan en el servidor, por lo que este directorio debe especificarse relativo al directorio correspondiente a la “base URL” de la webapp. Nota: Cambiar el valor de esta propiedad no implica regenerar la aplicación, sino solo un objeto Web. Si está en producción, sólo basta con modificar el archivo client.cfg. Ejemplo de valores Si se crea un directorio llamado “images” bajo el directorio raíz del webapp donde se instalaron los servlets, y a él se copian todas las imágenes necesarias, y en diseño sólo se especifica el nombre de la imagen, entonces en esta propiedad habría que poner /images. Propiedad Static Content directory seen from client Propósito Permite especificar el directorio donde se transferirán los JavaScripts (archivos *.js) que se generan para los menubars de objetos Web y Web Panels generados como estáticos. En tiempo de compilación, el generador los copiará al directorio especificado. Notas:  En este mismo directorio también habrán archivos de imágenes que se utilicen en los objetos Web. Los mismos se deben copiar manualmente a este directorio, y en los programas generados se referenciarán utilizando el valor de la propiedad “Static Content Base URL” concatenada con el nombre de cada imágen.  El path especificado debe ser relativo al cliente, es decir un path visto desde el PC en el que se está trabajando con GeneXus. Ejemplos de valores  X:\images - Si el servidor Web está instalado en una máquina, mapeada con el “drive” X y es el directorio “images” el utilizado para dejar el contenido estático. C:\resin\doc\images – Si el motor de servlets es el RESIN, está instalado localmente en el directorio C:\resin y se le creó el directorio images donde se copiaron las imágenes.  Propiedad Auto Compress HTTP Traffic Propósito Los objetos Web, en Java, pueden enviar la página HTML comprimida, de modo que sea descomprimida en tiempo real por el browser. La compresión se realiza solamente si el browser indica que es capaz de descomprimirlo. Valores Yes: envían la página comprimida. No: no envían la página comprimida. Es posible que algunos navegadores no reporten correctamente su capacidad para descomprimir las páginas, y no puedan desplegarlas correctamente. Default Value = “Yes”. Generation Mode Esta propiedad permite especificar si los objetos Web del modelo se generarán como objetos dinámicos (acceden a la base de datos) o como páginas HTML inteligentes (Smart Static Panels). También existe la posibilidad de generar Smart Static Panels a pedido mediante el valor “Create Static panels on request” de esta propiedad. Si se elige este valor, cuando se ejecuta un Web Panel, chequea si existe un .html que corresponda a sí mismo, con los parámetros que se le pasaron. Si existe, se redirecciona la llamada a dicho html. Si no existe, se crea el .html y luego se redirecciona. Por más información referirse a la documentación de Smart Static Panels Existe también la propiedad a nivel de objeto con los mismos valores que la propiedad del modelo y también el valor “Use model's property value”. Puesta en Producción Generador .NET Requerimientos Los requerimientos son similares al ambiente de desarrollo.  Servidor Web    Internet Information Server 5.0 o superior .NET Framework Redistributable 1.1 o 2.0 (Recomendable: Realizar la instalación del mismo a partir del Windows component update provisto por el setup de Visual Studio .NET) Manejador de Base de datos  Servidor de Base de Datos Instalación en el servidor En una aplicación Web es necesario copiar al servidor:  El directorio bin del modelo (donde se encuentran las dlls de cada objeto)     Los java script ( *.js) Las imágenes, htmls, *.css y cualquier contenido estático deseado El archivo Web.config Si se usan tipos de datos de Office, es necesario registrar la gxoffice2.dll Instalación en el Cliente Cliente Web, solamente alcanza con un browser. Para el caso de Internet Explorer la mínima versión soportada es I.E. 6.0. Para poder visualizar los Resportes PDF debe tener instalado el Adobe Acrobat Reader. Puesta en Producción Generador Java (War Deployment) Introducción Los servlets pueden ser ejecutados por motores de servlets (Tomcat, Resin, Jrun, etc.), o por servidores J2EE (WebSphere, BEA Weblogic, etc.). Configurar en forma adecuada los distintos motores de servlets o servidores J2EE, para ejecutar las aplicaciones Web Java, tiene cierta complejidad; se necesita conocer en cual directorio deben ir los servlets, en cual directorio deben ir los archivos adicionales (driver JDBC, classes adicionales, etc.) y dónde colocar el contenido estático. Además, una vez que se hace funcionar todo en un ambiente de prototipo hay que llevarlo a producción, es decir, configurar todo esto en el cliente. Entonces, el generador Java provee el War Deployment, que es un “output processor” del Deployment Wizard, que permite empaquetar en un sólo archivo, todo lo necesario, para la instalación y ejecución de una aplicación Web Java, en los distintos motores de servlets, o servidores J2EE, de forma sencilla. El War Deployment genera archivos con extensión .WAR (Web Archive Resource), los cuales son básicamente archivos .JAR a los cuales se les cambia la extensión a .WAR. Estos archivos empaquetan servlets, contenido estático, librerías adicionales y un archivo con formato XML, al cual se le llama descriptor, que contiene cierta información de la aplicación Web como por ejemplo el nombre de la aplicación, nombre de los servlets, mapeos, etc.). Configuración Para distribuir una aplicación Web, se debe ejecutar el Deployment Wizard, a través del Win Developer Menu. Este, permitirá seleccionar los objetos Web main para los que se desee armar el deployment, y luego automáticamente se abrirá el WAR Deployment para el armado del .WAR. Dentro del .WAR se incluirá todo lo necesario para ejecutar el objeto Web main y todos los llamados por él, más todos los archivos que se encuentren en el directorio indicado en la propiedad “Static content directory seen form client”. El WAR Deployment presenta estas opciones: Location Aquí se debe seleccionar el Location para el cual se quiera armar el .WAR. En caso de tratarse de un .WAR para una aplicación Web se debe seleccionar el Location <Client>; el resto de los locations son para el caso de querer distribuir las clases necesarias para ejecutar el servidor de aplicaciones en un aplicación en 3 capas con protocolo HTTP. Sirve para confirmar que se desea armar un .WAR para la Location actualmente seleccionado. Aquí se debe seleccionar el motor de servlets que se va a utilizar y en función de ello se arma el descriptor correspondiente (se profundiza más adelante). Este es el nombre que identifica a la aplicación Web. Para algunos motores de servlets va a ser utilizado luego en la URL para invocar los servlets. Deploy this Location Descriptor Type Web Application Name Additional Libraries Aquí se deben agregar todos las librerías adicionales para ejecutar la aplicación; el caso más común es el de los drivers JDBC. Esta es una estructura de directorios (que por defecto es vacía) en la cual se puede agregar todo el contenido estático que se necesite para ejecutar la aplicación. Permite agregar un directorio a la estructura de directorios de Additional Files. Permite borrar un directorio a la estructura de directorios de Additional Files. Permite agregar un contenido estático a los Additional Files en el directorio seleccionado. Permite borrar un contenido estático antes agregado en los Additional Files. Additional Files Add Directory Remove Directory Add Files Remove Files TAB Deployment Descriptor En el tab “Deployment Descriptor” se edita el descriptor del .WAR a generarse, en formato XML. Use Custom Descriptor Get Default Validate Deployment Al chequear esta opción se permite modificar el descriptor por defecto Vuelve a obtener el descriptor por defecto Valida el XML del descriptor en caso de haberlo modificado. ANEXO: CONCEPTOS DE INTERNET El propósito de este anexo es explicar una serie de conceptos sobre cómo funciona el Web. Para esto es necesario conocer el significado de ciertos conceptos que vamos a usar frecuentemente a lo largo del curso. Como la intención de este capítulo es establecer el lenguaje común que utilizaremos a lo largo del curso en lo que a Internet se refiere, trataremos de dar una visión intuitiva de los temas para no aburrir al lector con detalles innecesarios. Definiremos los siguientes conceptos:        Internet WWW Página Web URL Protocolo HTTP HTML Aplicación Web Tecnologías de las aplicaciones Web o o   Servlets Asp.net Javascript Intranet Comencemos entonces con definiciones básicas. Internet Internet es el nombre genérico que recibe la unión de todas las redes de comunicación a nivel mundial. Se podría definir como una red global en la que se unen todas las redes que utilizan protocolos TCP/IP y que son compatibles entre sí. Al contrario de lo que se piensa comúnmente, Internet no es sinónimo de WWW. Web o WWW El World Wide Web (Web o WWW) es uno de los muchos servicios ofrecidos en la red Internet. Es un sistema de información con interfaz gráfica, fácil de usar, que emplea la red Internet como medio de transmisión y permite navegar para buscar documentos en Internet. Estos documentos, como también los links que existen entre ellos forman un "Web" de información. El Web permite saltar o "hyperlink" de una página Web (o Web page) a otras. Puede pensarse en el Web como una gran biblioteca. Los sitios Web (Web sites) son como los libros (libros electrónicos) y las páginas Web son como las páginas específicas de estos libros. Estas páginas pueden contener noticias, imágenes, sonidos, 3D, etc. Además pueden estar ubicadas en computadoras de cualquier parte del mundo. Los libros electrónicos mantienen el concepto básico del libro, y además, brindan la oportunidad de disponer de una estructura no lineal, la que permitirá, entre otras cosas, decidir el orden en el que se desea recibir la información. Algunos de los servicios disponibles en Internet aparte de la Web son el acceso remoto a otras máquinas (SSH y telnet), transferencia de archivos (FTP), correo electrónico (SMTP), boletines electrónicos (news o grupos de noticias), conversaciones en línea (IRC y chats), mensajería instantánea (MSN Messenger, ICQ), transmisión de archivos, etcétera. Página Web Una página Web es un documento de la World Wide Web normalmente en formato HTML . Una página Web típicamente, incluye texto, imágenes y enlaces hacia otros documentos de la red, pudiendo además contener animaciones, sonidos, programas en Java, y cualquier otro tipo de documento, por medio de plugins y otras tecnologías. Actualmente las páginas Web ya no están únicamente enfocadas para ser visualizadas, sino que cada vez son más dinámicas permitiendo que el visitante participe en ellas mediante menúes interactivos, encuestas, votaciones, etc. En el Web se distinguen básicamente dos tipos de páginas. Las páginas estáticas y las páginas dinámicas. Las páginas estáticas son las más sencillas, se crean usando un editor de páginas Web o bien escribiendo directamente el código HTML. Mientras que se ajustan muy bien a los requerimientos iniciales de hacer promoción y obtener alguna venta ocasional, o bien la venta masiva de muy pocos productos, no se adecuan a la mayor parte de las necesidades de la venta. La desventaja que presentan es que el mantenimiento de las mismas implica un alto costo si se realizan cambios con frecuencia, ya que una persona debe realizar las modificaciones correspondientes. Algunos ejemplos de estas páginas son: Información general, Marketing, Información similar a la que se distribuye en folletos y documentos. Tienen la ventaja de brindar un acceso rápido y cómodo a información y brindar direcciones de correo electrónico para información y soporte. Las páginas dinámicas son creadas en el momento en que son referenciadas por el usuario. Si bien tienen un estilo base, la información desplegada en las mismas es dinámica. Son interactivas, ya que permiten que la página a visualizar pueda ser creada en base a la información ingresada por el usuario. Por ejemplo, una consulta de los pedidos pendientes de una orden de compra. Las páginas dinámicas permiten interactuar con una base de datos, por lo que son una poderosa herramienta para impulsar los negocios de la empresa. Al utilizar este tipo de páginas, la actualización se realiza en forma automática, pues al acceder a la página se accede a la base de datos con la información actualizada. Algunos ejemplos que se prestan para una aplicación que utilice páginas dinámicas:   Home Banking: operaciones varias sobre cuentas bancarias. Divulgación de información: acceso a información publicada por la empresa dependiendo del rol. Por ejemplo sin costo en el caso de que la información sea pública y con costo para aplicaciones en el que se exigen una validación de usuario. Comunicación con proveedores: para hacer órdenes de compra, verificar existencia de stock. Intranet: Aplicaciones internas de la empresa. No pueden ser accedidas desde fuera. Venta directa: Compra de artículos desde la casa, similar a la compra por catálogo.    Las aplicaciones Web desarrolladas con GeneXus generan normalmente páginas dinámicas (porque acceden a la base de datos). Intranet Una Intranet es una red de Área Local (LAN) privada empresarial o educativa que proporciona herramientas vía Internet, las cuales tienen como función principal proveer lógica de negocios para aplicaciones de captura, reportes, consultas, etc. con el fin de auxiliar la producción de dichos grupos de trabajo; es también un importante medio de difusión de información interna a nivel de grupo de trabajo. No necesariamente proporciona Internet a la organización; normalmente, tiene como base el protocolo TCP/IP de Internet y, por ser privada, puede emplear mecanismos de restricción de acceso a nivel de programación como lo son usuarios y contraseñas de acceso o incluso a nivel de hardware como un sistema firewall que pueda restringir el acceso a la red organizacional. Las aplicaciones GeneXus Web ejecutan tanto en Intranets como en Internet. Aplicación Web Una aplicación Web es aquella que los usuarios usan accediendo a un servidor Web a través de Internet o de una Intranet. Son populares debido a la practicidad del navegador Web como cliente “ligero”. Otra razón importante de su popularidad es la habilidad para actualizar y mantener aplicaciones Web sin distribuir e instalar software en miles de potenciales clientes. Tecnologías Para poder comprender mejor la tecnología escondida detrás de las aplicaciones desarrolladas para el Web, es necesario aclarar algunos conceptos adicionales. Los diferentes lenguajes utilizan diferentes tecnologías para generar las páginas dinámicas. Inicialmente surgió la tecnología CGI y luego las Web Classes las cuales fueron utilizadas en versiones anteriores de GeneXus por los generadores C/SQL y Visual Basic respectivamente para desarrollar aplicaciones Web. Actualmente, las tecnologías empleadas son los servlets y los asp.net por los generadores Java y .NET respectivamente. SERVLETS La palabra servlet deriva de otra anterior, applet, que se refería a pequeños programas escritos en Java que se ejecutan en el contexto de un navegador Web. Por contraposición, un servlet es un programa que se ejecuta en un servidor Web. El uso más común de los servlets es generar páginas Web de forma dinámica a partir de los parámetros de la petición que envíe el navegador Web. ASP.NET es otra alternativa de Microsoft para el desarrollo de aplicaciones Web. Esta tecnología se desarrolló para la nueva plataforma .NET y se trata de una evolución de las ASP o Active Server Pages. También en este caso se trata de aplicaciones que ejecutan en el servidor y envían el HTML resultante al cliente. Los programas en el servidor son .dll’s que se invocan con extensión .aspx. Las aplicaciones Web utilizan también código JavaScript para permitir mayores funcionalidades. JavaScript JavaScript es un lenguaje interpretado orientado a las páginas Web, con una sintaxis semejante a la del lenguaje Java. Se ha convertido en un verdadero lenguaje de programación que aporta la potencia de cálculo del navegador para aumentar la usabilidad de aplicaciones Web con técnicas avanzadas como Ajax. Ajax Ajax es una arquitectura y no una tecnología. Ajax stands for Asynchronous JavaScript XML. Incorpora:      Basado en estándares de presentación usando XHTML y CSS; Despliegue e interacción dinámica usando Document Object Model; Intercambio y manipulación de datos usando XML y XSLT; Recuperación asincrónica de datos usando XMLHttpRequest; y JavaScript atando todo junto. Ajax transforma la experiencia del usuario Web de una experiencia discontinua, donde los usuarios deben esperar por la respuesta del servidor luego de cada solicitud de una página, en una experiencia continua y unida, donde los usuarios interactúan con una interfase que rápidamente responde, sin importar las conexiones al servidor que pasana ser invisibles al usuario.. URL Básicamente una URL es una dirección Web. Cuando visualizamos una página Web con Netscape, Internet Explorer o cualquier otro navegador, los links (visualizados subrayados y generalmente en color azul), contienen información oculta que apunta a la ubicación del recurso al que se hace referencia. Se puede pensar una URL como un puntero estándar a un recurso Internet. El recurso podría ser un gráfico, un sonido o simplemente un archivo de texto. Las URL’s también pueden usarse para iniciar sesiones telnet, ftp y otros servicios. En muchos casos es conveniente conceptuar una URL como el equivalente de estándar DOS para nombre y path de un archivo. De hecho una URL puede apuntar a un archivo en la máquina local y también puede apuntar a un archivo específico de un directorio específico en una máquina remota. Sintaxis protocol://host/path/filename[?parm1,…,[parmn]] protocol: Especifica el protocolo de acceso. Ejemplos: file, ftp, http, telnet host: Nombre del host al cual deseamos conectarnos. Ejemplo: www.genexus.com path/filename: Ubicación y nombre del documento en el servidor. [parm1,...,[parmn]] Información opcional para consultas Las URLs pueden definirse de forma absoluta o relativa. Una URL absoluta empieza siempre por el protocolo, es seguido de dos puntos (":") y de una parte específica del esquema. Una URL relativa comprende sólo la parte específica del protocolo de una URL, o de algún componente de seguimiento de aquella parte. El protocolo y componentes principales se infieren del contexto en el cual aparece la referencia URL: es decir del documento que contiene la referencia. Protocolo HTTP El protocolo de transferencia de hipertexto es el protocolo usado en cada transacción de la Web (WWW). El hipertexto es el contenido de las páginas Web, y el protocolo de transferencia es el sistema mediante el cual se envían las solicitudes de acceder a una página Web (desde un Web browser), y la respuesta de esa Web (desde un programa http Server), remitiendo la información que se verá en pantalla. También sirve el protocolo para enviar información adicional en ambos sentidos, como formularios con mensajes y otros similares. El protocolo HTTP es un protocolo sin estado, es decir, que no guarda ninguna información sobre conexiones anteriores. Al finalizar la transacción todos los datos se pierden. Está basado en el modelo cliente-servidor: un cliente HTTP abre una conexión y realiza su solicitud al servidor, el cual responde generalmente el recurso solicitado y la conexión se cierra. Se establecen 4 pasos básicos en el protocolo HTTP: 1) Conexión: Durante la conexión, el Web browser intenta conectarse al servidor. Si el browser no logra la conexión en una determinada cantidad pre-configurada de tiempo, se desplegará un mensaje de error y la consulta del usuario cancelará. 2) Solicitud: Una vez que la conexión al servidor HTTP ha sido establecida, el browser envía una solicitud para el recurso deseado en el servidor. 3) Respuesta: Si el servidor encuentra el recurso, éste es enviado al browser y se pasa al último paso. De lo contrario, un mensaje de error es enviado y se pasa al último paso. 4) Se cierra la conexión: Si el servidor retornó el recurso solicitado, el browser realizará la carga del mismo y será desplegado al usuario. El formato tanto de la solicitud como de la respuesta es el siguiente: <Línea inicial> Header-1: value-1 ... Header-n: value-n <Cuerpo del mensaje (Opcional)> La línea inicial es diferente en las solicitudes y en las respuestas. En las solicitudes van tres campos separados por un espacio en blanco: "Método recurso VersiónDelProtocolo". Por ejemplo: "GET /path/to/file/index.html HTTP/1.0". La línea inicial de una respuesta tiene tres campos separados por un espacio: "versiónDelProtocolo códigoRespuesta Mensaje". Por ejemplo: "HTTP/1.0 200 OK" o bien "HTTP/1.0 404 Not Found". Los encabezados están normados en el protocolo, e incluyen, en el caso de una solicitud, información del navegador y eventualmente del usuario cliente; en el caso de una respuesta, información sobre el servidor y sobre el recurso. El cuerpo del mensaje contiene el recurso a transferir o el texto de un error en el caso de una respuesta. En el caso de una solicitud, puede contener parámetros de la llamada archivos enviados al servidor. Cabe señalar que los principales navegadores Web no muestran al usuario los encabezados HTTP del recurso. La característica de ser un protocolo sin estado, popularizó el uso de cookies, que son archivos que se almacenan en el computador que puede leer un sitio Web al establecer conexión con él, y de esta forma reconocer a un visitante que ya estuvo en ese sitio anteriormente. Gracias a esta identificación, el sitio Web puede almacenar gran número de información sobre cada visitante, ofreciéndole así un mejor servicio. (Más adelante profundizaremos en cookies.) Existe también una variante de este protocolo, que brinda comunicaciones seguras en Internet denominado https. También profundizaremos en este concepto más adelante en este curso. HTML Es el lenguaje en el cual están escritos los documentos del WWW. Es un subconjunto especializado del lenguaje más general SGML (Standard Generalized Markup Language). El lenguaje HTML está compuesto por una serie de códigos o tags ubicados dentro de un documento ASCII, que son traducidos por un Web browser como Netscape, Internet Explorer, etc., en instrucciones específicas para formatear el documento que se va a desplegar en la pantalla. Entre dichos tags están incluidos los tags de hyperlinks, que permiten especificar enlaces hacia otros recursos en el Web. Un documento HTML consiste en texto que compone el contenido del documento y tags, los cuales definen la estructura y apariencia del documento. La estructura de un documento HTML es simple. Cada documento tiene un cabezal (head) y un cuerpo (body), delimitados por los tags <head> y <body>. El cabezal es donde se indica un título al documento y donde se indican otros parámetros que el browser podría utilizar en el momento de desplegar el documento. El cuerpo es donde se coloca el contenido propiamente dicho del documento HTML. Esto incluye el texto a desplegar y otros controles que indican al browser cómo desplegar el texto. Los tags también referencian archivos de efectos especiales como imágenes y sonido e indican los hot spots que enlazan el documento a otros documentos. Un ejemplo de código HTML podría ser el siguiente: <HTML> <HEAD> <TITLE>This is my first page </TITLE> </HEAD> <BODY>shows in a very <I>simple</I> way,the basic structure of an HTML document. </BODY> </HTML> el cual se vería en un browser de la siguiente forma: Web Server Un servidor web es un programa que implementa el protocolo HTTP (hypertext transfer protocol), el cual está diseñado para transferir páginas web. Un servidor web se encarga de mantenerse a la espera de peticiones HTTP llevada a cabo por un cliente HTTP que solemos conocer como navegador. El navegador realiza una petición al servidor y éste le responde con el contenido que el cliente solicita. A modo de ejemplo, al teclear www.genexus.com en nuestro navegador, éste realiza una petición HTTP al servidor de dicha dirección. El servidor responde al cliente enviando el código HTML de la página; el cliente, una vez recibido el código, lo interpreta y lo muestra en pantalla. Como vemos con este ejemplo, el cliente es el encargado de interpretar el código HTML, es decir, de mostrar las fuentes, los colores y la disposición de los textos y objetos de la página; el servidor tan sólo se limita a transferir el código de la página sin llevar a cabo ninguna interpretación de la misma. Sobre el servicio web clásico podemos disponer de aplicaciones web. Éstas son fragmentos de código que se ejecutan cuando se realizan ciertas peticiones o respuestas HTTP. Hay que distinguir entre: Aplicaciones en el lado del cliente: el cliente web es el encargado de ejecutarlas en la máquina del usuario. Son las aplicaciones tipo Java o Javascript: el servidor proporciona el código de las aplicaciones al cliente y éste, mediante el navegador, las ejecuta. Es necesario, por tanto, que el cliente disponga de un navegador con capacidad para ejecutar aplicaciones (también llamadas scripts). Normalmente, los navegadores permiten ejecutar aplicaciones escritas en lenguaje javascript y java, aunque pueden añadirse más lenguajes mediante el uso de plugins. Aplicaciones en el lado del servidor: el servidor web ejecuta la aplicación; ésta, una vez ejecutada, genera cierto código HTML; el servidor toma este código recién creado y lo envía al cliente por medio del protocolo HTTP. Las aplicaciones de servidor suelen ser la opción por la que se opta en la mayoría de las ocasiones para realizar aplicaciones web. La razón es que, al ejecutarse ésta en el servidor y no en la máquina del cliente, éste no necesita ninguna capacidad adicional, como sí ocurre en el caso de querer ejecutar aplicaciones javascript o java. Así pues, cualquier cliente dotado de un navegador web básico puede utilizar este tipo de aplicaciones. Ejemplos de servidores web son Apache, IIS, Websphere. Web Browser Un navegador web o web browser es una aplicación que permite al usuario recuperar y visualizar documentos de hipertexto, comúnmente descritos en HTML, desde servidores web de todo el mundo a través de Internet. Los navegadores actuales permiten mostrar o ejecutar: gráficos, secuencias de vídeo, sonido, animaciones y programas diversos además del texto y los hipervínculos o enlaces. El seguimiento de enlaces de una página a otra, ubicada en cualquier computadora conectada a la Internet, se llama navegación; que es de donde se origina el nombre de navegador. Otra denominación es explorador web inspirada en uno de los navegadores más populares el Internet Explorer producido por Microsoft. Ejemplos de otros navegadores utilizados son Nestcape Navigator, Firefox, Mozilla, etc.. Thin Client Un Cliente Liviano (Thin client) es una computadora (cliente) en una arquitectura de red cliente-servidor que tiene muy poca o ninguna lógica del programa, por lo tanto depende principalmente del servidor central para las tareas de procesamiento. La palabra liviano se refiere a lo pequeña que es la imagen de arranque, quizás no más grande que la requerida para conectar a la red y arrancar un navegador web.
Copyright © 2024 DOKUMEN.SITE Inc.