Aplicaciones gráficas y Web con RPG (Con la ayuda de RpgForWeb) por Guillermo Andrades H elp400 lleva un cierto tiempo publicando artículos sobre la capacidad del System i (también del iSeries y los AS/ 400, claro) para desarrollar y manejar aplicaciones Web, incluyendo algunos referentes al lenguaje RPG. Ahora nos llega una invitación para que publiquemos algo sobre cómo abordamos esta tarea en CPI Software. “A ver cómo lo hacéis…” ▲ ▲ ▲ Cuando hablé con Alberto sobre el posible contenido me dijo algo así cómo que esperaba que no lo hiciéramos sobre una demo chiquitina y ajada que tuviéramos en nuestro sistema sino sobre un programa “de verdad”, sugiriéndome como ejemplo un programa de consulta sobre su base de datos –que el buen hombre la tiene en Access– de Revistas, Artículos y Autores, no sé si esperando que le dijéramos que no para ahorrarse las paginillas o que le dijéramos que sí para tener un sistema de consultas gratuito... :-)) El caso es que tomamos sus ficheros Access, los convertimos buenamente al 400 y hemos diseñado una página Web, creada y alojada en un System i 520 y controlada por programas RPG IV. Con RpgForWeb se puede enfocar de diferente forma la solución para un programa o aplicación, más cercana o menos a la forma tradicional de programar en 400. En este caso hemos preferido usar funciones menos “tradicionales” de forma que podamos apreciar la capacidad de congeniar con toda clase de fanfarria más al estilo Web, la capacidad de interactuar con cualquier tendencia actual y futura. Para un modelo de programación más cercano al tradicional, RpgForWeb tiene funciones que asemejan el modo de uso tipo pantalla, incluyendo la función ExFmt para presentar una “pantalla” y esperar el envío/intro del usuario final. Dejaremos para otra ocasión una demo de ese estilo. En directo Cómo lo hemos hecho 20 Por una parte intentamos que se vea claramente que “es una aplicación RPG”, por otra también queremos que ésto (el que sea RPG) deje claro que no supone renunciar a ninguna virguería de las que puedan implementarse en aplicaciones Web, por lo que usamos técnicas de HTML, JavaScript y CSS (hojas de estilo), incluso funciones DHTML, DOM y AJAX para conseguir efectos de interactividad poco usuales en aplicaciones de gestión. ServerNEWS ENERO 2007 De forma que aquí tenemos una de las características principales de RpgForWeb. Como vemos en el gráfico de la Figura 1, la función a realizar –el programa– se divide en dos capas: la capa de presentación (también llamada de cliente, con la que el usuario final trabaja, lo que anda en un navegador) y la capa de aplicación (también llamada de lógica de negocio). Esta separación en capas permite que cada una se desarrolle independientemente, incluso por personas diferentes, y que sea más fácil su desarrollo y mantenimiento, ya que ciertos cambios pueden requerir editar sólo algún componente sin tener que tocar el conjunto. Por supuesto, además, cada capa puede consistir en diferentes elementos, la capa de aplicación se puede hacer con varios programas RPG, SQL, CL o Cobol, al igual que la capa de presentación puede montarse básicamente sólo con HTML pero también completarlo con bloques de JavaScript y CSS, bien dentro del propio fichero HTML o en N ficheros .js y .css diferentes relacionados, facilitando aún más la atomización y la especialización, la programación modular. Cómo funciona El objetivo es que la aplicación Web no requiera instalar nada en la parte de cliente, esto es: que funcione en casi cualquier aparato (un PC, una PDA, incluso un teléfono móvil) que incluya un navegador de Internet. Esto se logra con el servidor HTTP Apache incluido en i5/OS (y en OS/400), que es el que sirve todos los ficheros de la parte de cliente a cualquier navegador compatible. En nuestro caso, esos ficheros residen en el propio IFS del 400, bien guardaditos en la caja mágica. Para muestra un botón En la dirección http://RpgForWeb.com/help400 puede verse la demo real trabajando en un AS/400 (Figura 2) y que os invito a probar antes de proseguir con el artículo. De hecho, la funcionalidad del programa es muy sencilla; tenemos tres posibilidades de selección: a. Un número de revista directo (por ejemplo, 166) b. Un argumento de búsqueda (por ejemplo, IFS) c. Elegir artículos por autor (por ejemplo, Carlos) En la opción b se teclea un argumento, aparece una lista de artículos que tienen ese argumento en su título y al pinchar en uno, se visualiza el artículo correspondiente. En la opción c se puede elegir un autor (como argumento de búsqueda), salen sus artículos y al pinchar en uno, se visualiza el artículo (Figura 3). www.help400.es FIGURA 1 Modelo de aplicación en dos capas FIGURA 4 Ejemplo de los resultados de una búsqueda FIGURA 2 Demostración real en http://RpgForWeb.com/help400 Nota: hay algunos artículos, sobre todo antiguos, que no están accesibles, por lo que señalamos con los signos + o – esta propiedad. teclearse RPG IV normal encolumnado y con tantos Moves o Gotos como cada uno quiera. En el fichero HTML tenemos los campos de entrada (<input name=xxxx>): FIGURA 3 Ejemplo de búsqueda por el nombre parcial de un autor • txNum para teclear el número de revista • txBus para el argumento de búsqueda • txAut para seleccionar Autor • Ya que usamos Ajax, nos permite también enviar “campos” con nombres diferentes, y que no tienen porqué estar en etiquetas <input>, pero que sí tienen que estar en el repositorio DDS del programa 400 para el emparejamiento. Y en el 400 hemos preparado un “repositorio” pareja, una simple DDS, que se usa para emparejar los datos, de forma que los campos en HTML se pongan a disposición del programa RPG en un formato normal para su uso. En primer lugar, indicar que en el ejemplo se ha utilizado código en rpg-free principalmente, pero por supuesto puede www.help400.es 5 20 9 9 9 1 20 0 0 0 Cuando se teclea en el navegador la URL de comienzo (llamamos a esto un EntryPoint o punto de entrada) RpgForWeb identifica el EntryPoint (“Help400” en este caso) como parte de una cierta aplicación, establece las variables necesarias para comenzar una transacción Web y llama a un programa RPG asociado al EntryPoint. Ese programa inicial tiene solamente: ENERO 2007 ServerNEWS ▲ ▲ ▲ ¿Vemos algo de código? TXTNUM TXTBUS IDAUTOR IDTEMA NUM OPCION BUSAUT En directo Para conseguir una mayor interacción y un modo de uso más moderno, sin los molestos refrescos de página, toda la información posible está en el mismo HTML base, ocultando y visualizando partes necesarias y usando Ajax (httpRequest) para la comunicación con los programas RPG (Figura 4). A A A A A A A 21 ■ APLICACIONES GRÁFICAS Y WEB CON RPG //lee file-html con la pagina de respuesta cwFile = ‘artic’; cwPage = cwGetPage(cwpDirA:cwFile); //Cambiar campos en la pagina CallP cwAddFldT(‘TxAut’:’Carlos’); CallP cwAddFldT(‘TxBus’:’RPG’); FIGURA 5 Código RPG que trata la opción de búsqueda A //Enviar la pagina al browser CallP cwWrite(cwPage); //pasar control al navegador *INLR = *ON; • La operación GetPage toma del IFS el fichero artic.html. La variable cwpDirA es una variable global de RpgForWeb que contiene el directorio IFS asociado a la aplicación a la que pertenece el EntryPoint usado para comenzar la transacción. • La operación AddFldT se usa para enviar valores a campos o variables en el html, en este caso la usamos para poner valores por omisión a los campos de Autor y argumento de búsqueda. • cwWrite envía la página al navegador. Cuando el usuario final interactúa con la página web (que le fué enviada con GetPage y cwWrite) y envía los datos, éstos se procesan con un programa RPG. En el programa se tratan los ficheros con las funciones normales de RPG; aquí estamos usando dos ficheros físicos y un lógico de uno de ellos: no es más que RPG: FHLPAUT FHLPART FHLPARTKA IF IF IF E E E K DISK K DISK K DISK USROPN USROPN rename…. Cuando el navegador ejerce una función, tal cómo enviar un requerimiento, el programa RPG recibe los “campos” de entrada (visibles y ocultos) del HTML. Esto se logra con una sola línea RPG: cwDS = cwCvtDB(cwpInput:’REPOHLP’:’LIBHLP400'); En directo ▲ ▲ ▲ 24 Esta línea es prácticamente igual en todos los programas, sólo cambia el nombre del “repositorio” a usar (REP0HLP) y la biblioteca donde reside (LIBHLP400). De esta forma pueden tenerse diferentes repositorios dependiendo de las necesidades de las aplicaciones. Estas DDS repositorio hacen casi la misma función que los campos dds que se colocan en las pantallas verdes tradicionales: ser un buffer donde se almacenan temporalmente los campos de pantalla que van y vienen del programa. Si se pide un argumento de búsqueda se ejecuta el código RPG de la Figura 5a. En el caso de que la búsqueda de artículos sea por Autor, el código es el de la Figura 5b. ServerNEWS ENERO 2007 B when opcion=’B’; //busqueda NUM=0; Open HLPART; Read HLPART; DoW NOT %EOF(HLPART); if %Scan(%xLate(LOW:UP:%trim(txtBus)): %xLate(LOW:UP:arTitul))>0; Exsr Tabla; endif; Read HLPART; EndDo; Close HLPART; when opcion=’A’; //autor Open HLPARTKA; Setll idAutor hlpArtKa; ReadE IdAutor hlpArtKa; NUM=0; DoW NOT %EOF(hlpArtKa); Exsr Tabla; ReadE IdAutor hlpArtKa; EndDo; Close hlpArtKa; Como podemos ver, es código RPG normalito, nada que ver con que estemos trabajando en una página Web; cada cual será capaz de mejorarlo, escribirlo de otra forma, pero se trata de puro RPG. Aquí tenemos la principal maravilla de RpgForWeb: usamos RPG para leer y enviar campos a “pantalla”, leer y actualizar bases de datos, llamar a otros programas…. No hay límite a lo que un buen programa RPG puede hacer. En la sentencia Exsr Tabla se construye la tabla (Query o Grid) que contendrá, en el navegador, la lista de artículos de la revista. Este es un modo avanzado de uso de tablas tipo Query, RpgForWeb permite también tablas tradicionales HTML. En este caso (Figura 6) el código para llenar la tabla no parece tampoco muy del otro jueves: • El código (en 2) es para poner en el Query el nombre completo del autor del artículo, que no está en el fichero que se lee (articulos) sino en el de Autores. • El código (3) es para señalar en el Query los registros (es decir, los artículos de la revista) que no tienen contenido asociado web. • El código (4) va concatenando los campos que van al Query, véase cómo cada campo lleva los atributos o edición deseados en simple RPG. • Para separar cada fila o línea en el Query se usa el código (1), marcando con # el fin de cada fila. Podría hacerse de otra forma, pero siempre en RPG, una forma u otra dependerá de cada cual, pero es poco más o menos el código que sabemos. www.help400.es 1 2 3 4 BegSr Tabla; If NUM>0; CWPAGE = %TRIM(CWPAGE)+ ‘#’; EndIf; NUM = NUM + 1; Chain ARAUTOR HLPAUT; if ARWEB = ‘’; Artic = ‘-’; else; Artic = ‘’; EndIf; CwPage=%Trim(cwPage)+%EditC(NUM:’Z’)+ ‘|’+%EditC(arNumer:’Z’)+ ‘|’+%EditC(arPagin:’Z’)+’|’+%Trim(arTitul)+ ‘|’+%TRIM(Autor)+ ‘|’+%TRIM(arDescr)+’|’+%Trim(arWeb)+ ‘|’+%Trim(Artic); EndSr; Como ya hemos comentado antes, el envío de la tabla al navegador se hace simplemente con: CallP cwWrite(cwPage); *INLR = *ON; Después de este código, el navegador recibe la respuesta (en formato Ajax, ya que así fué solicitada, aunque al 400 le importa poco si la transacción es Ajax o normal, eso es cuestión de la forma de proceso en la parte cliente). Código en cliente www.help400.es <!— (html) area para visualizar la web de Help400 —> <div id=”webhelp400" style=”display:none;”> <iframe id=”if400" style=”border:1px solid black” align=”center” width=”99%” height=”600"> </iframe> </div> function goNum(num){ if (isNaN(num)) { alert(“Debe introducir un numero.”); return false; } ifr = document.getElementById(‘if400’); ifr.src=”http://www.help400.es/asp/scripts/ nwsum.asp?Num=” + num; ver=document.getElementById(‘webhelp400’); ver.style.display=’block’; } Otra ventaja del desarrollo es que no se necesita ningún entorno concreto ni complejo ni caro, existen múltiples editores sin coste que son suficientes, y que pueden correr en cualquier PC con pocos requerimientos. Como referencia puede verse http://RpgForWeb.com/r4wuw.htm. Fin RpgForWeb tiene otras funciones para manejo de tablas diferentes, así cómo funciones integradas para enviar variables y campos en otros formatos, procesar formularios (“pantallas”) con un modo compatible con ExFmt, Diseñador y Convertidor de pantallas, establecer transacciones con Login independiente de los perfiles de usuario, soportar aplicaciones con diferentes lenguajes, etc, ya que RpgForWeb es un entorno que ayuda tanto en la parte de desarrollo como en la de ejecución de aplicaciones Gráficas. Por último, si alguien quiere comentar la demo puede hacerlo desde la propia página. ■ Guillermo Andrades, con muchos años de experiencia en el entorno AS/400, es fundador de CPI Software y padre asociado de RpgForWeb.com. ENERO 2007 ServerNEWS En directo En la parte de cliente, la capa de presentación de este programa, hay funciones JavaScript que quizá no tengan suficiente sitio aquí para explicarlas, ya que el objetivo fundamental del artículo es afirmar la capacidad de control por parte del RPG/400. RpgForWeb incluye un montón de funciones JavaScript probadas, así que con eso, un poco de cabezonería y otro poco del típico prueba y error es como se consiguen los objetivos. A un programador que sólo sepa RPG puede serle difícil entender –no digamos escribir– código JavaScript, pero para programas sin gran complejidad es suficiente con las funciones incorporadas. El “copia y pega, vaya que no me sale, probemos otra vez”. La combinación de HTML, JavaScript y CSS quizá pueda asustar un poco, pero en realidad no es necesario más que conocer unos rudimentos para comenzar, ya que RpgForWeb también incluye plantillas con html y CSS. En equipos con varias personas se puede incluso separar las funciones según la experiencia de cada uno. Si uno anda un poco bajo de conocimientos, tanto los cursos como los manuales o las referencias existentes en Internet de esos temas son innumerables, ya que html, JavaScript y css son el fundamento de la Web, y aprendiendo estas técnicas no perdemos sino ganamos el tiempo y ponemos en nuestras manos la modernización de las aplicaciones. Con JavaScript el primer horror que se encuentra uno es el montón de paréntesis y brackets que se usan para separar bloques de código, pero es lo que hay, si uno quiere parecer moderno tiene que usar este tipo de escritura, así que más vale acostumbrarse porque ése es el estilo también en C y Java. Aparte de esto, el código no es difícil de comprender. Por ejemplo, el código para procesar el acceso a una revista por su número: ▲ ▲ ▲ FIGURA 6 Subrutina de carga de la tabla de resultados 25