Sei sulla pagina 1di 58

Precio: 6 (Espaa) (IVA incluido) AO XI. 2. POCA N 127 UNA PUBLICACIN DE: REVISTAS PROFESIONALES S.L.

G
R
A
T
I
S
C
D

I
N
C
L
U
I
D
O
LA PRIMERA REVISTA DE PROGRAMACIN EN CASTELLANO
Noticias, javaHispano y Opinin, Libros, Preguntas y Respuestas
8 413042 303299
00127
ACTUALIDAD
Presente y futuro de IPv6
Java Expo 2005
Inteligencia Ambiental:
la presencia invisible
MIDDLEWARE
Tipos Generics en .NET 2.0 para C# y VB
Struts, la referencia en desarrollos J2EE
REDES
Programacin web gil
con ColdFusion MX 7
DISEO
Generacin de cdigo a partir de
modelos con EMF
ALGORITMOS
Programacin Win32 avanzada
CANAL PANDA
La seguridad IT, tambin para los
empleados
Nmero 127
Edita: REVISTAS PROFESIONALES S.L.
solop@revistasprofesionales.com
C/ Valentin Beato 42, 3. 28037 - Madrid.
http://www.revistasprofesionales.com
http://digital.revistasprofesionales.com
Editor
Agustn Buelta

Coordinacin Tcnica-Redaccin
Carlos Laparra

Maquetacin
Alfonso Sabn Mejas

Asesora de Publicidad
Felipe Ribagorda
Tel.: 91 304 87 64
Delegacin en Barcelona
C/ Rocafort, 241/243, 5 1
Mariano Snchez
Tel.: 93 322 12 38

Suscripciones
Tel: 91 304 87 64
Fax: 91 327 13 03

Impresin
Ideas de Impresin

Distribucin
Motorpress Ibrica
DISTRIBUCION EN MEXICO
DIMSA - C/ Mariano Escobedo, 218
Col. Anhuac. 11320 Mxico, D.F.
DISTRIBUCION EN ARGENTINA
Capital Federal: Distrimachisa
Interior: York Agencysa - Tlf: (5411) 433 150 51
REPRESENTANTE EN MEXICO
Angel Bosch - angelbosch@infosel.net.mx
Distribucin, nmeros atrasados y suscripciones
C/ Renacimiento, 180. Col. San Juan Tlihuaca.
Azcapotzalco. 02400 Mxico D.F.

La revista Slo Programadores no tiene por qu


estar de acuerdo con las opiniones escritas por
sus colaboradores en los artculos firmados.
El editor prohibe expresamente la reproduccin
total o parcial de los contenidos de la revista
sin su autorizacin escrita.
Depsito legal: M-26827-1994
PRINTED IN SPAIN
COPYRIGHT 30-06-2005
P.V.P. 6,00 Euros
Precio en Canarias, Ceuta y Melilla:
6,15 Euros
P2P, UN ENFOQUE DIFERENTE
Cuando se nos habla de las redes Peer to Peer (P2P) no podemos evitar pensar
en la descarga de vdeo o msica. Hay quien dice que dicha descarga constituye
un delito, aunque por otro lado hay quien defiende el derecho a compartir. Al
margen de esta discusin, lo que no genera ningn tipo de dudas es que la
tecnologa P2P alberga grandes posibilidades de comunicacin y por lo tanto de
negocio.
Microsoft, por ejemplo, ha apostado por esta tecnologa en el proyecto Farsite
(http://research.microsoft.com/sn/Farsite/). Farsite es un sistema de ficheros
distribuido que permite a un grupo de estaciones de trabajo acceder a un
sistema de ficheros nico y que reside en las propias estaciones de trabajo, de
modo que cada estacin desempea las labores de cliente y servidor, tal como
establece el concepto de P2P. Mediante un sofisticado sistema de replicacin,
los archivos del sistema de ficheros se van almacenando y replicando por las
estaciones de trabajo que tienen acceso a dicha infraestructura. Para el caso
de plataformas GNU/Linux, la empresa Radiant Data ha desarrollado PeerFS
(http://www.radiantdata.com), un sistema de ficheros igualmente distribuido y
replicado de forma transparente en los equipos conectados. Adems, PeerFS
tambin permite distribuir las bases de datos de MySQL, lo cual incorpora el
concepto P2P al mundo del almacenamiento masivo de datos.
Esto son slo dos ejemplos que demuestran que la tecnologa P2P va a centrar
gran parte de la innovacin en los prximos aos, lo que conduce a pensar que
la revolucin provocada por Napster en su momento, an no ha acabado
ACTUALIDAD
12 IPv6: Oportunidad para la innovacin, oportunidad para nuevos
negocios
14 Java Expo 2005
16 Inteligencia Ambiental: la presencia invisible
DISPOSITIVOS MVILES
20 Creacin de un sistema de distribucin de Midlets (I)
MIDDLEWARE
26 Novedades en los lenguajes de .NET 2.0 (y III)
32 Struts prctico (II)
REDES
42 Creacin de aplicaciones web con ColdFusion MX 7 (II)
DISEO
48 Generacin de cdigo a partir de modelos con EMF
ALGORITMOS
56 API Win32 y C: una programacin directa y eficaz (y III)
Y ADEMS. . .
04 Noticias
08 javaHispano: Harmony, ejecutar .NET en J2EE, juegos con Java y ms
10 Canal Panda: La seguridad IT, tambin para los empleados
62 Preguntas y respuestas
64 Contenido del CD-ROM
66 Libros: Grficos y BBDD
Asociacin Espaola de Editoriales
de Publicaciones Peridicas
E D I T O R I A L
S U M A R I O
NOTICIAS
MICROSOFT
La nueva versin de Microsoft Office, Office 12, incorporar
XML como formato para sus archivos
Microsoft ha anunciado recientemente que adop-
tar la tecnologa estndar de la industria
eXtensible Markup Language (XML) como formato
de archivo por defecto en la prxima versin de las
ediciones de Microsoft Office, actualmente conoci-
da con el nombre en clave de Office 12. Los nue-
vos formatos de archivo, llamados Microsoft Office
Open XML Formats, se convertirn en los formatos
por defecto para las versiones de Microsoft Word, Excel y PowerPoint de
Office 12, que espera ser lanzado al mercado en la segunda mitad de
2006.
Para que los desarrolladores, partners y profesionales de las nuevas tec-
nologas dispongan de las herramientas e informacin que necesitan
para desarrollar soluciones basadas en Office utilizando los nuevos for-
matos de archivo, Microsoft ir emitiendo la informacin necesaria, as
como conferencias y eventos relacionados con este tema (como por
ejemplo TechEd 2005).
Las ventajas que pueden derivarse de la incorporacin de la tecnologa
XML a los formatos de los archivos de Office 12 son:
Formatos de archivo compactos y robustos.
Mejor interoperabilidad de datos.
Formatos abiertos y sin royalties.
Compatibilidad y soporte para clientes y partners.
La gran aceptacin de XML
Microsoft ha dado soporte a este estndar de la industria en su tecno-
loga de productividad desde Office 2000, cuando la compaa introdu-
jo XML dentro de los formatos de
archivo HTML soportados por Word,
Excel y PowerPoint. Microsoft ha
ampliado ese soporte en Office XP y
Office 2003, adems de en Microsoft
Office InfoPath 2003.
Tambin los clientes y la industria de la
tecnologa en general han adoptado
rpidamente XML. Segn una investigacin de Microsoft, ms de un
milln de desarrolladores estn actualmente trabajando en soluciones
sobre Office 2003, y ms de un tercio de ellos estn utilizando XML en
estas soluciones.
En un estudio realizado por Gartner, se estima que la utilizacin de e-
forms habilitadas por XML al menos se duplicar durante el prximo
ao y que en el ao 2007, un 40% de trabajadores cualificados usarn
herramientas para la creacin de contenidos XML. Otro estudio des-
arrollado por Forrester Research prev que en 2008 XML se convertir
en uno de los formatos de documento dominantes para el archivo de
datos.
Las personas interesadas en los nuevos formatos de archivo de la pr-
xima versin de Office pueden obtener informacin adicional en la web
http://www.microsoft.com/office/preview.
BEA SYSTEMS
Gartner sita a BEA como proveedor lder de software de
infraestructura
BEA Systems ha dado a conocer recientemen-
te los resultados de un estudio de Gartner, del
que se desprende que la propia compaa se
sita como uno de los tres proveedores ms
importantes en tres diferentes mercados
durante 2004: servidores de aplicaciones, pro-
ductos de portales y suites de aplicaciones, as como en AIM (Aplicacin,
Integracin y Middleware) y en mercado de Portal. Para hacer tal afir-
macin, el estudio se ha basado en la cuota de mercado de ingresos por
licencias.
El informe de Gartner Market Share: AIM and Portal Software,
Worldwide, 2004, Preliminary muestra que BEA consigui en 2004 el
21,7% del mercado mundial de servidores de aplicaciones; el 11,6% del
mercado de suites de aplicaciones; el 8,9% de productos de portal y el
7,2% del mercado de integracin y middleware, mercado, ste ltimo,
cuyo valor asciende a ms de 6.700 millones de dlares. Gartner evala
a los proveedores teniendo en cuenta su visin y capacidad de ejecu-
cin. La firma de investigacin entiende por lderes aquellos fabrican-
tes que presentan un buen funcionamiento, tienen una clara visin de
las tendencias del mercado y son proactivos en la construccin de com-
petencias para mantener sus posiciones de liderazgo en el mercado.
http://digital.revistasprofesionales.com SOLO PROGRAMADORES n 127 4
BUSINESS OBJECTS
Crystal Reports XI y Crystal Reports Server XI,
disponibles en castellano
Business Objects, proveedor de soluciones de
business intelligence (BI), acaba de lanzar la nueva
versin en castellano de sus dos ltimos produc-
tos, Crystal Reports XI y Crystal Reports Server XI.
La experiencia adquirida y las impresiones favora-
bles que le han llegado con respecto al producto
en castellano de la anterior versin 10 han dado
lugar a este nuevo paso por parte de la compaa.
De hecho, la mayora de las ventas que la
compaa realiz de este producto eran de
ediciones en castellano, donde un 72% de las
unidades vendidas en 2004 eran referencias
en castellano, mientras que el 28% eran edi-
ciones en ingls que se distribuan tanto a
Espaa como para Portugal, no dejando
duda de que el mercado prefiere el producto
traducido.
Este ha sido el principal motivo que ha lleva-
do a Business Objects a lanzar la nueva ver-
sin de Crystal Reports XI y Crystal Reports
Server XI.
Slo Programadores
en Formato
Digital
Por menos dinero
Llegar antes a su ordenador que a los quioscos
Entra en http://digital.revistasprofesionales.com
Suscripcin anual a Slo Programadores por slo 27 euros
y a Slo Programadores y Mundo Linux por slo 40 euros
Regalo de un CD-ROM con el archivo de los 12 ejemplares
de la temporada 2003-04
NOTICIAS
http://digital.revistasprofesionales.com SOLO PROGRAMADORES n 127 6
PANDA SOFTWARE
La PYME espaola carece de proteccin frente a las nuevas
amenazas
Panda Software ha presentado recientemente su informe Niveles de
Proteccin en la PYME espaola 2005, en el marco de la Campaa de
Seguridad para la PYME, que, promovida por la Asociacin de
Internautas (AI) y con el apoyo de la Entidad Pblica Red.es, cuenta con
la colaboracin de Panda Software.
Dicho informe pone de manifiesto que si bien ha aumentado satisfac-
toriamente el nivel de proteccin antivirus, las PYMES no estn adecua-
damente protegidas contra las nuevas amenazas como el spyware y el
spam, que son, despus de los virus, las que ms preocupan a los peque-
os empresarios espaoles.
Segn los datos que se desprenden de este estudio, el 94,5% de las
PYMES asegura contar con un sistema de seguridad, siendo un antivi-
rus el 60,5% de los casos. Asimismo, de las empresas encuestadas que
tienen implantado un software antivirus, el 96% asegura tenerlo actua-
lizado. Estos datos suponen un gran avance en materia de seguridad en
cuanto a antivirus se refiere, pero hay ms.
Desproteccin frente a las nuevas amenazas
El informe 2005 presenta sin embargo un panorama bien distinto en
cuanto a las nuevas amenazas se refiere y la conclusin que de l se
extrae es que la PYME espaola cree que con disponer de un antivirus
es suficiente, ya que slo un 10% de las empresas entrevistadas dispo-
ne de un sistema de seguridad antispyware. Estos datos son preocu-
pantes si se tiene en cuenta que a nivel mundial
el 90% por ciento de las empresas tiene software
espa instalado segn un informe elaborado por
las empresas Webroot y Earthlink. Adems, la
media de spyware instalado en cada uno de los
equipos analizados es de 25 ejemplares. Segn los
datos recogidos por la solucin antivirus online y
gratuita de Panda Software, Panda ActiveScan
(cuya nueva versin detecta
spyware), el 84% del total de mal-
ware instalado en los ordenadores
es software espa.
El informe 2005 presentado por
Panda revela que, en el caso del
spam, la situacin de las PYMES
es an, de mayor desproteccin
que en el caso del spyware, ya que
solamente el 5,5% de las PYMES aseguran contar con un sistema de
seguridad especfico para combatirlo. Segn datos hechos pblicos
recientemente por la empresa TB-Security se calcula que el spam causa
prdidas de productividad que alcanzan el 3%. Lo cual puede dar una
idea del impacto que dicho tipo de malware puede producir en las
PYMES espaolas si se tienen en cuenta las estimaciones de la propia
TB-Security que pronostica un 30% en el crecimiento del spam para
2005.
Mayor nivel de informacin y concienciacin
Sin embargo, el informe de Panda Software tambin refleja algunos
aspectos positivos. Por ejemplo, es destacable que las PYMES espaolas
parecen ms y mejor informadas sobre las posibles amenazas y vulne-
rabilidades existentes, puesto que ms de la mitad de los usuarios busca
asesoramiento en empresas especializadas y proveedores de seguridad
informtica en caso de tener un problema.
Muestra del Informe
El informe ha sido realizado en el segundo trimestre de 2005 y se cen-
tra en una muestra de 1.253 PYMES, clasifi-
cada por tamao de la empresa (de 0 a 10
empleados, de 11 a 25 empleados, de 26 a 50
empleados, y ms de 50 empleados). Adems,
se ha elaborado un estudio detallado de
seguridad en las principales Comunidades
Autnomas (Andaluca, Catalua, Comunidad
Valenciana, Madrid y Pas Vasco).
SUN MICROSYSTEMS
Telefnica mviles despliega sus servicios con Java
Enterprise System
Sun Microsystems ha anunciado que Telefnica Mviles Espaa (TME)
ha seleccionado el software de infraestructura Java Enterprise System
(JES) tanto para ofrecer servicios existentes como para desplegar
aplicaciones y servicios de prxima generacin. La solucin Java
Enterprise System va a proporcionar a Telefnica un conjunto
completo de componentes abiertos y basados en estndares que
facilitan la rpida creacin y despliegue de nuevos servicios
de comunicaciones.
Los beneficios para TEM, segn fuentes de Sun, pueden
resumirse en un ahorro de costes por el innovador mode-
lo de licencia (precio fijo al ao por empleado), no penali-
zar econmicamente los servicios cuando crece el
nmero de clientes, derecho a un nmero ilimitado de
licencias de los productos que forman parte de JES,
etc.
Java Enterprise System
Java Enterprise System pretende ser una simplifica-
cin del software de importancia crtica para las empresas,
integrando los servicios corporativos de red ms habituales y que las
organizaciones necesitan para crear y desplegar con xito sus aplica-
ciones de negocio. Este completo sistema de software basado en
estndares se entrega como una nica entidad sobre infraestructura
preintegrada, con ciclos de actualizaciones predecibles y
un coste muy asequible (140 euros por usuario al ao).
Supuestamente, JES proporciona a los responsables de
sistemas la tranquilidad que necesitan para centrarse
nicamente en lo que mejor saben hacer: utilizar las
Tecnologas de la Informacin para lograr metas de
negocio. Los servicios en red compartidos de JES
proporcionan las siguientes funcionalidades y
capacidades:
Servicios de aplicaciones y Web
Servicios de identidad de red
Servicios de portal
Servicios de comunicacin y colaboracin
Servicios de disponibilidad
Servicios de seguridad de extremo a
extremo
El lector puede obtener ms informacin sobre
Java Enterprise System en www.sun.com/
software/javaenterprisesystem.
NOTICIAS
RED.ES y ARSYS
Disponible la gua sobre la nueva normativa para el
registro de dominios .es
La entidad pblica empresarial Red.es, ads-
crita al Ministerio de Industria, Turismo y
Comercio de Espaa, y arsys, empresa de
registro y alojamiento de dominios, han
editado conjuntamente la Gua de domi-
nios .es, un manual que recoge los aspec-
tos bsicos incluidos en el nuevo Plan
Nacional de Nombres de Dominio bajo el
cdigo correspondiente a Espaa.
El Boletn Oficial del Estado (BOE) del pasa-
do 31 de mayo public la Orden de 19 de
mayo por la que se aprueba este Plan, cuyo
objetivo es flexibilizar las normas exigibles
para la asignacin de nombres de dominio
bajo .es entre empresas, particulares e ins-
tituciones, y fomentar el desarrollo de la
Sociedad de la Informacin en Espaa.
La Gua de dominios .es explica las nuevas
condiciones de contratacin de los regis-
tros territoriales, as como toda la informa-
cin relativa a los requisitos necesarios para
el registro, los plazos de implantacin, el
periodo de pre-registro, etc. La Gua puede descargarse en formato PDF
desde la pgina web de arsys (www.arsys.es). Asimismo, la web del Esnic
(www.esnic.es), departamento
de Red.es que gestiona la asig-
nacin de nombres de dominio
bajo .es, incluye tambin un
apartado especfico sobre la
nueva normativa.
Crecimiento de la demanda
de dominios .es
SOLO PROGRAMADORES n 127 8 http://digital.revistasprofesionales.com
JAVAHISPANO
Actualidad Java
de la mano de javaHispano
Actualidad Java
de la mano de javaHispano
Apache Software Foundation est estudiando desarrollar una implementacin libre de J2SE,
cuyo nombre sera Harmony. La iniciativa cuenta con el apoyo de numerosas figuras desta-
cadas del Software Libre; entre ellas, miembros del equipo de desarrollo de IKVM, Kaffe, GCJ,
Classpath y otros proyectos que implementan alguna parte de J2SE bajo una licencia libre.
Varios representantes de Sun han manifestado su apoyo al proyecto, al cual es posible que
contribuyan de algn modo. No obstante, tambin han afirmado que no comprenden la
necesidad de esta implementacin, ya que para ellos las licencias bajo las que se distribuye
J2SE son suficientemente libres.
Hasta que Harmony o javal (http://www.javali.org.br), una iniciativa similar de origen brasi-
leo, se completen, aquellos que deseen emplear una plataforma Java libre pueden optar
por SNAP (http://www.snapplatform.org/), una solucin que empaqueta en un mismo pro-
ducto bien documentado y de fcil instalacin a Jikes como compilador, SableVM como
mquina virtual, GNU Classpath como libreras, Eclipse como IDE y Tomcat como servidor
web.
Apache podra desarrollar una implementacin libre de J2SE
Sun ha empezado a licenciar el JDK 5.0 bajo una nueva licencia: JIUL (Java Internal Use License). Esta licencia permitir modificar el cdigo fuente
del JDK para corregir rpidamente bugs, sin la necesidad de esperar por los parches oficiales. Al cdigo modificado no se le requerir pasar los tests
de compatibilidad de la plataforma.
Estos JDKs modificados debern utilizarse nica y exclusivamente para uso interno, esto es, para cualquier uso operacional o comercial dentro de
una organizacin o negocio. El acceso de clientes a la tecnologa Java modificada a travs de un cliente remoto (como un navegador web) se con-
sidera uso interno mientras el cdigo modificado se halle y se ejecute en un servidor situado en el interior de la empresa.
Esta es la tercera modalidad de licenciamiento del JDK de Sun, junto con la Sun Community Source License, orientada al mundo comercial, y Java
Research License, orientada a la investigacin y al mundo acadmico.
El JDK 5.0 se distribuye bajo una nueva licencia
Mainsoft ha lanzado un plugin para Visual
Studio.NET, Grasshopper, que permite des-
plegar aplicaciones de .NET en servidores de
aplicaciones Java. Para ello transforma,
mediante un compilador, el MSIL de .NET en
bytecode y, para proporcionar libreras como
ASP.NET y ADO.NET, incorpora las libreras del
proyecto Mono compiladas a bytecode.
Existe una versin gratuita de Grasshopper
que slo permite desplegar las aplicaciones
en Tomcat. Para emplear otros servidores
J2EE y acceder a la funcionalidad de depura-
cin del plugin es necesario ir a la versin
comercial.
Grasshopper: ejecutar aplicaciones .NET en servidores J2EE
SOLO PROGRAMADORES n 127 9
JAVAHISPANO
javaHispano
http://digital.revistasprofesionales.com
Struts, el primer framework web libre para Java, acaba de cumplir cinco
aos. Este framework ha sido el estndar de facto para desarrollo de apli-
caciones web con Java durante muchos aos y, en la actualidad, a pesar de
la dura competencia de otros como Spring, sigue siendo lder indiscutible
en cuanto a su uso.
Desde que Craig R. McClanahan construy la primera versin en su port-
til mientras se encontraba de vacaciones, Struts ha experimentado muchas
evoluciones. Pero la ms radical est por llegar con el nacimiento de Shale,
donde se romper el monoltico controlador en tres partes y se contempla-
r el uso de JSF como capa de presentacin.
Struts cumple cinco aos
Sobre el autor
Abraham Otero (abraham.otero@javahispano.org) es responsable de calidad y miembro de la junta de javaHispano.
La popularidad de las cmaras digitales ha creado la demanda de un soft-
ware que permita la descarga, visualizacin, clasificacin y bsqueda de
las fotos. Existen varias soluciones para desarrollar este tipo de programas
desde Java; las ms potentes son, probablemente, las desarrolladas por
Aprise (http://asprise.com). Para el mundo Windows ofrece JTwain, mien-
tras que para otros sistemas operativos debemos emplear JSANE, con
soporte para AIX, BSD, GNU/Linux, OS2, Solaris y otros sistemas Unix.
Otra solucin es Morena (http://www.gnome.sk) que tambin permite
interactuar con Twain y SANE desde Java. En el bando del Software Libre,
podemos encontrar una solucin para Windows, todava en desarrollo,
que comparte nombre con su homlogo de Aprise: JTwain (http://source-
forge.net/projects/jtwain/).
Soluciones para controlar cmaras digitales y escneres desde Java
OPININ
Java para
desarrollar juegos
Cuando omos Java y juegos en una
misma frase tendemos a llevarnos las
manos a la cabeza: que si el tiempo de
inicio de la mquina virtual, que si la
latencia del recolector de basura, que
si el uso excesivo de memoria, que si
es lento... La lista es casi interminable.
Pero Existen de verdad razones que excluyan a
Java como un lenguaje de desarrollo de videojuegos? En
el equipo de Arianne (http://arianne.sourceforge.net/)
pensamos que no.
Cuando comenzamos el desarrollo de Stendhal, pensa-
mos que Java sera la mejor opcin porque aporta un
entorno completo donde ejecutar nuestro videojuego
independientemente del sistema operativo. Hemos pro-
bado el desarrollo multiplataforma en otros lenguajes y
sin duda Java es el rey en este aspecto. El tiempo de ini-
cio de la mquina virtual esta rondando entre los 1 o 2
segundos lo cual si vas a hacer un juego que enganche
durante horas no es un problema. El consumo de memo-
ria de nuestra aplicacin es moderado, rondando los
30MB. Videojuegos similares a Stendhal desarrollados
por equipos similares rondan esta cantidad o incluso la
superan. No hemos experimentado problemas con el
recolector de basura a pesar de no estar optimizado
nuestro juego para evitar derrochar memoria, y aun as
no afecta al tiempo de respuesta. Adems, evitamos las
fugas de memoria y por tanto reducimos la cantidad de
memoria usada.
Pero sobre todo, lo ms importante para considerar la
experiencia un xito es la velocidad: velocidad de ejecu-
cin ya que sin ningn tipo de optimizacin hemos obte-
nido 120 FPS para una pantalla de 640x480x32 bits.
Inicialmente pensamos en un error en el clculo de los
FPS, pero no, eran correctos: Java estaba creando la esce-
na 120 veces por segundo.
Por ltimo la velocidad de desarrollo, que muchos pare-
cen olvidar, ha sido lo que ms nos ha sorprendido, escri-
bir cdigo Java nos ha resultado entre 2 y 3 veces ms
rpido que escribir cdigo en C++ y casi a la par que
escribir cdigo en Python, con lo cual hemos empleado
ese tiempo extra en desarrollar nuevas ideas y corregir
los fallos existentes.
Por tanto, a modo de conclusin, dira que la prxima vez
que pensis en desarrollar un videojuego, dadle una
oportunidad a Java; no os defraudar.
Miguel Angel Blanch (mblanch)
Desarrollador de Arianne
SOLO PROGRAMADORES n 127 10
CANAL PANDA
http://digital.revistasprofesionales.com
Las normativas sobre seguridad e higiene en el
trabajo tienen un fin muy claro: evitar acciden-
tes y enfermedades en los trabajadores. Y ade-
ms, cada normativa puede verse desde dos
puntos de vista muy distintos, desde el lado del
trabajador y desde el del empresario. Si un obre-
ro utiliza casco, est protegiendo su integridad
fsica, lo que sin duda es muy conveniente. Pero
si un empresario hace que el trabajador use el
casco, est protegiendo su fuerza de trabajo,
haciendo que la empresa no vea reducida su pro-
ductividad.
Ms all de estos puntos de vista, hay un tras-
fondo aadido a estas medidas de seguridad: en
una empresa segura, el ambiente de trabajo es
mejor. El mero hecho de tener, por ejemplo, fil-
tros anti-polen en el sistema de aire acondicio-
nado, hace que el aire dentro de una oficina sea
ms sano y se pueda trabajar mejor. O tener un
vigilante en la puerta del edificio que evite la
entrada a personas no deseadas tambin mejora
sustancialmente el confort en el trabajo diario.
Sin embargo, en muchas empresas todava no se
ha llegado a implementar un sistema de protec-
cin contra intrusiones informticas adecuado.
S es cierto que la proteccin contra cdigos
maliciosos es muy comn, ya que los empresa-
rios y responsables de sistemas se han dado
cuenta de que la probabilidad de perder infor-
macin por culpa de un cdigo malicioso es muy
alta si no de dispone de un sistema antivirus. De
esta manera, la base de datos de clientes, los
proyectos, las propuestas, en definitiva la base de
funcionamiento de la empresa, estar a salvo.
Pero hay un nivel que todava debemos alcanzar
en los sistemas de proteccin. Las amenazas no
se ciernen exclusivamente sobre los datos, sino
que en los ltimos tiempos se han lanzado en
picado sobre el dinero. Cada vez ms los cdigos
maliciosos se crean con el objetivo de obtener un
beneficio econmico, llegando al caso de cifrar
ficheros, exigiendo una cantidad econmica a
cambio de la clave de descifrado.
De todos es conocido tambin que el phishing
supone un claro peligro para los usuarios. Este
tipo de estafa consiste en mandar un correo
electrnico a una coleccin de direcciones de e-
mail (al ms puro estilo spam) en las que se
informa de un supuesto problema con los datos
de la cuenta bancaria por Internet del usuario.
Evidentemente, no existe ningn problema real
con la cuenta del usuario, pero aquel que pique
puede verse en un serio problema, al haber dado
el control de su cuenta bancaria a un estafador.
En todos estos casos, una empresa podra desen-
tenderse de estos problemas, ya que no son sino
errores en los que cae el usuario, sin que tenga
mayor repercusin para la marcha de la empre-
sa. Pero vendra a equivaler a la instalacin de un
filtro anti-polen como el que mencionbamos
antes.
Un problema alrgico en un empleado no es pro-
blema que deba resolver la empresa, pero sin
duda entra dentro de las obligaciones y respon-
sabilidades de los empresarios mantener un aire
lo ms puro posible para sus empleados.
Pues lo mismo ocurre en una instalacin infor-
mtica corporativa. Los empleados deben tener
una proteccin que vaya ms all del simple fil-
trado de cdigos maliciosos, ya que el malware
va mucho ms all de lo que son los clsicos
virus o troyanos.
En el mejor de los casos, alguna empresa puede
llegar a pensar que sus cuentas bancarias pue-
den estar amenazadas, pero el control interno
que siempre hay en los departamentos de admi-
nistracin de las empresas convierten los ata-
ques de phishing en prcticamente intiles a
nivel corporativo. No descartemos, sin embargo,
La seguridad IT, tambin para
los empleados
La seguridad IT, tambin para
los empleados
FERNANDO DE LA CUADRA
Un sistema de seguridad no ser
efectivo si no se tienen en cuenta
todas las posibles amenazas.
Analicemos dnde pueden estar los
puntos dbiles de los sistemas de
seguridad actualmente implantados.
Si no tenemos una
concepcin global
de la seguridad
podemos generar
huecos muy
difciles de taponar
SOLO PROGRAMADORES n 127 11
CANAL PANDA
La seguridad IT, tambin para los empleados
http://digital.revistasprofesionales.com
que en el futuro puedan verse involucradas
tambin las cuentas bancarias corporativas.
Hoy en da la definicin de malware no
solamente incluye cdigo ejecutable, como
se podra suponer al derivarse su nombre
de malicious software. Para que algo
cause dao en una instalacin informtica
no es necesario que sea software, puede ser
un simple mensaje de correo electrnico.
Nadie tiene la ms mnima duda de que el
spam es pernicioso, y sin embargo un e-
mail, por mucha Viagra que anuncie, no es
software: es un mensaje de correo electr-
nico que se podr leer de una manera u
otra, pero en principio, no va a llevar a cabo
una tarea dentro del sistema ms all de la
molestia que supone su recepcin y elimi-
nacin.
Lo mismo ocurre con el phishing, no es
cdigo ejecutable, pero el peligro que
entraa es elevadsimo y debe incluirse
algn tipo de filtro anti-phishing integrado
con los sistemas de proteccin corporativa.
El uso de herramientas distintas dentro de
los sistemas de seguridad para problemas
distintos hace que se pierda la visin inte-
grada de la proteccin, generando huecos
muy difciles de taponar.
A todas estas amenazas hay que sumar una
a la que no se le da la importancia suficien-
te en las empresas: el spyware. En muchsi-
mas ocasiones se piensa que el spyware es
un problema para los usuarios finales, para
los usuarios domsticos. Estos mismos
usuarios son los que estn delante de los
ordenadores en las empresas, y aunque la
informacin que intentan robar estos cdi-
gos espas suele ser referente a hbitos de
navegacin, no debemos olvidar que el
spyware suele incluir entre sus funciones la
de grabacin de pulsaciones de teclas
(keylogging). Un listado de las pulsacio-
nes de teclas en el ordenador de un traba-
jador quiz no consiga tarjetas de crdito,
pero s una ingente cantidad de datos que
harn las delicias de los competidores.
A pesar de las medidas clsicas de seguri-
dad contra espionaje industrial, las empre-
sas deben tener en cuenta que una terica-
mente inocua barra de navegacin instala-
da por un empleado (y no detectada ade-
cuadamente por el sistema antimalware)
puede dar a traste con un proyecto millo-
nario. O sin ser tan tremendistas, puede
simplemente servir de va de escape a
direcciones de correo para engrosar las lis-
tas de los spammers.
Si las empresas de hoy en da quieren esta-
blecer un sistema de seguridad efectivo,
deben vigilar que todos los riesgos
(ataquen directamente a la empresa o bien
a los empleados) estn vigilados y solucio-
nados.
La concepcin global de la seguridad infor-
mtica de hoy en da ofrece, y exige,
soluciones completas para la seguridad
completa.
Sobre el autor
Fernando de la Cuadra (Fdelacuadra@pandasoftware.com) es editor tcnico internacional de Panda Software (http://www.pandasoftware.com).
Panda Software ha lanzado recientemente
una nueva versin de su solucin antimalwa-
re con gestin remota va Internet, Panda
WebAdmin. La nueva versin de WebAdmin
proporciona seguridad a las empresas no
solamente frente a virus, gusanos y troyanos,
sino tambin frente a otras amenazas de
Internet como spyware, adware, dialers o hac-
king tools.
Panda WebAdmin consta de un cliente antivi-
rus instalado localmente en los equipos a pro-
teger, as como de un innovador sistema de
gestin centralizada alojado en los servidores
de Panda Software (http://webadmin.panda-
software.com), desde el cual el administrador
puede instalar, configurar y monitorizar la
seguridad de toda la empresa de forma
remota.
En Panda WebAdmin, el criterio fundamental
para poder gestionar la seguridad es que los
equipos estn conectados a Internet y no que
estn conectados a la red corporativa. Esto
permite al administrador controlar la seguri-
dad en equipos remotos que no formen parte
de la red corporativa, como son porttiles y
ordenadores de delegaciones remotas, as
como reducir los costes asociados al manteni-
miento de la seguridad informtica.
Panda WebAdmin Antivirus est disponible en
espaol, ingls y japons, e incluye los servi-
cios de la gama corporativa de Panda
Software: soporte telefnico o va e-mail para
la resolucin rpida de cualquier incidencia
que pueda surgir, actualizaciones diarias con-
tra nuevos virus, SOS Virus 24h/365d para el
envo de ficheros sospechosos e informacin
proactiva (sobre los nuevos virus que apare-
cen, del estado vrico mundial, etc.). Asimismo,
Panda Software ofrece a sus clientes, gratui-
tamente, todas las mejoras que vaya
incorporando a esta solucin. El lector intere-
sado puede ampliar esta informacin en:
ht t p: / / empr esas. pandasof t war e. es/
productos/webadmin/
Panda Software lanza una nueva versin de Panda WebAdmin, la solucin
antimalware para empresas que cuentan con mltiples porttiles y/o delegaciones
El men de administracin de
WebAdmin ofrece las funcionalidades
necesarias para establecer las polticas
de seguridad de la empresa.
Los clientes de WebAdmin pueden administrar
la seguridad de sus equipos remotamente desde
http://webadmin.pandasoftware.com
WebAdmin informa continuamente de
la actividad vrica.
SOLO PROGRAMADORES n 127 12
ACTUALIDAD
IPv6: Oportunidad para la innovacin,
oportunidad para nuevos negocios
IPv6: Oportunidad para la innovacin,
oportunidad para nuevos negocios
http://digital.revistasprofesionales.com
El Internet Global Congress
(IGC) celebr en Barcelona su
sptima edicin del 6 al 10
de junio de 2005 consolidn-
dose como el evento de refe-
rencia sobre tecnologa,
innovacin y sociedad digital
en Espaa. Entre los temas
tratados, destac por encima
de todos el presente y futuro
de IPv6. Por eso reproduci-
mos aqu el anlisis de Jordi
Palet Martnez, donde el
autor expone los problemas
de la Internet actual, y qu
posibilidades puede abrir
IPv6 en el futuro.
El IGC2005
da la bienvenida
a IPv6
Por supuesto que han aparecido mltiples
aplicaciones y servicios, pero en realidad me
atrevera a decir que no son tantos, si tene-
mos en cuenta que la mayora de stos, de
una manera o de otra, se basan en los dos
anteriores (o en los protocolos sobre los que
se soportan). Por lo tanto, estamos legitima-
dos para afirmar que la innovacin en
Internet prcticamente se ha detenido. Debido
a que hoy dependemos en gran medida de
Internet para cualquier tipo de aplicaciones y
servicios, ya sea en el lugar de trabajo o en el
hogar (servicios de ocio, informacin, etc.), y
dado que existe una evidente ausencia de
innovacin en Internet, en cierto modo pode-
mos afirmar que esto repercute negativamen-
te en el desarrollo de la sociedad de la infor-
macin y del conocimiento.
Hay un motivo fundamental para que se pro-
duzca esta falta de innovacin en Internet: la
dificultad de desarrollar aplicaciones que fun-
cionen extremo a extremo, en cualquier lugar
de la red, y que adems puedan ser seguras y
puedan funcionar en movimiento (la cual cosa
tiende a ser cada vez ms habitual en entor-
nos tanto de trabajo como de ocio).
Esta dificultad se debe al uso casi universal de
NAT. Hay centenares de aplicaciones y des-
arrollos que residen en los laboratorios por
falta de recursos de sus creadores, porque al
intentar ponerlos en el mercado, se encuen-
tran que los escenarios de redes son tan
diversos como las posibles combinaciones de
fabricantes y modelos de NAT.
La forma en la que se construye NAT no est
concretada en ningn estndar, lo cual impi-
de definir un mecanismo nico que permita
abrir un camino a travs de NAT cuando una
aplicacin as lo requiera. An definiendo
En estos ltimos aos, hemos sido
espectadores de un crecimiento
importante y continuado de Internet.
Sin embargo, este crecimiento ha
tenido nicamente dos golpes de
efecto destacables desde el punto
de vista del usuario final: el correo
electrnico y la web.
JORDI PALET MARTNEZ
(CEO/CTO, Consulintel. Presidente del Grupo de Trabajo
de Educacin, Promocin y Relaciones Pblicas de IPv6)
Jordi Palet Martnez es CEO/CTO de Consulintel
y fue ponente en el IGC2005.
SOLO PROGRAMADORES n 127 13
ACTUALIDAD
IPv6: Oportunidad para la innovacin, oportunidad para nuevos negocios
http://digital.revistasprofesionales.com
ahora este estndar, Cunto tiempo tar-
daramos en actualizar todos los NAT que
hay en la red, teniendo en cuenta que
hay millones de ellos? Qu coste ten-
dra?
Sin lugar a dudas, puedo asegurar que
tanto el coste como el tiempo seran muy
superiores y mucho menos eficaces que
la inversin requerida para hacer la tran-
sicin a IPv6, que por otra parte aporta
multitud de ventajas adicionales y, espe-
cialmente, la posibilidad de extensin de
todo aquello que pueda hacer falta en un
futuro, prcticamente sin lmites.
En estos momentos, el mercado ya ha
reconocido las ventajas de IPv6,
aunque para ser sinceros ha costado un
poco ms de lo que se esperaba en un
principio.
En los ltimos dos aos, aproximada-
mente, el inters por IPv6 ha sido expo-
nencialmente creciente, y su despliegue
est avanzando a pasos agigantados, con
noticias interesantes prcticamente cada
da des de hace ms de seis meses acer-
ca de nuevas implantaciones en redes,
semiconductores, dispositivos y, en
general, todo tipo de productos, aplica-
ciones y servicios.
Adems, este inters no ha sido exclusi-
vo por parte de proveedores de servicios
de Internet, sino que tambin ha llegado
a la industria en general y, especialmen-
te, a fabricantes de productos de consu-
mo donde, sin duda, pronto descubrire-
mos novedades impensables hasta ahora
(domtica, audio/vdeo/multimedia, ofi-
cina, televigilancia, etc.).
Veamos un ejemplo. Una de las aplica-
ciones que hoy en da est teniendo ms
xito es la voz sobre IP, y un caso concre-
to es el xito de Skype, una creacin
reciente de los diseadores de KaZaA.
Esta aplicacin ha requerido y requiere el
80% de la inversin de la compaa, des
de que sta empez a desarrollarse, con
el objetivo de asegurar que la aplicacin
funcionara en cualquier lugar de la red.
Evidentemente, los propietarios de Skype
se lo pueden permitir, ya que con la
venta de su desarrollo anterior, KaZaA,
consigui recursos financieros abundan-
tes. An as, sera interesante ver cunta
creatividad adicional podran desarrollar
sus ingenieros, ya sea en mejoras sobre
el mismo Skype, ya sea en otras aplica-
ciones, con este 80% de los recursos.
Pero, sin duda, este no es el caso de la
mayora de las pequeas y medianas
empresas, ni de la comunidad de
desarrolladores de cdigo abierto, ni de
desarrolladores independientes. stos no
suelen disponer de este 80% de recursos
para malgastar haciendo una herramien-
ta que solucione un problema que debe-
ra estar resuelto y garantizado por la
red.
Se puede afirmar categricamente que
desarrollar para redes IPv4 supone ms
costos, ms complejidad tcnica, y plazos
de desarrollo y mantenimiento muy
superiores, la cual cosa muchas veces
provoca el abandono de las ideas, e impi-
de la innovacin.
Me atrevera a predecir un nuevo boom
de Internet cuando haya una masa crti-
ca de desarrolladores que exploten el
potencial que les ofrece IPv6.
Dnde est el negocio, con IPv6, para
los ISPs? Por un lado, hay que tener en
cuenta que el servicio de acceso est
dejando de ser un negocio; competencia,
ms requisitos de ancho de banda y de
calidad de servicio, conllevan reduccio-
nes de mrgenes. Por otro lado, la
demanda de ms ancho de banda no est
compensada con la prestacin de nuevos
servicios, con el despliegue de nuevas
aplicaciones, y es aqu donde se produce
la oportunidad de negocio.
Los ISPs son el canal perfecto para llegar
a millones de clientes, con unos costos
de despliegue mnimos, para que cual-
quier emprendedor pequeo pueda
comercializar sus aplicaciones. IPv6 es la
oportunidad para que los ISPs se puedan
convertir en aglutinadores de servicios
e incrementen sus volmenes de factu-
racin, sus mrgenes y sus servicios a los
clientes, con una amplia oferta de aplica-
ciones.
Es equiparable al caso de los servicios de
televisin por cable o satlite. El cliente
paga una cuota bsica mensual para la
suscripcin al servicio (lo que equivaldra
a la cuota de conexin a la red de banda
ancha en nuestro caso). An as, el clien-
te generalmente contrata paquetes de
canales temticos adicionales como cine,
infantiles, documentales, etc., o hasta de
vez en cuando, servicios puntuales (pay
per view).
No es necesario que los ISPs desplieguen
soporte nativo de IPv6, no inicialmente,
sino que han de ser capaces de activar en
sus redes mecanismos de transicin que
aprovechen el potencial de transportar
IPv6 a las redes IPv4 existentes. Con esto
pueden reducirse prcticamente a cero
las inversiones iniciales.
De esta manera, el soporte nativo a IPv6,
y tambin la desaparicin de IPv4 en las
redes troncales y de acceso, sern cam-
bios progresivos, cuando se hayan conse-
guido volmenes de negocio que justifi-
quen este cambio.
Por otro lado, en el momento en el que
estn disponibles ms aplicaciones y ser-
vicios, los usuarios tendirn a requerir
ms ancho de banda, ms calidad de ser-
vicio, menos retrasos, etc. Servicios
que, lgicamente, generarn ingresos
adicionales.
Todo esto, sin tener en cuenta que no
aprovechar esta oportunidad es dar pie
para que la competencia se anticipe, con
el riesgo consiguiente de perder clientes.
El nuevo negocio de los ISPs es, por lo
tanto, sacar partido a las redes de banda
ancha con IPv4 para desplegar aplicacio-
nes y servicios que aprovechen las capaci-
dades extremos a extremo de IPv6. El
nuevo negocio empieza por regalar las
direcciones IPv6 a los clientes, y facilitar
as que exploten el desarrollo de estas
aplicaciones y servicios: la innovacin.
http://www.consulintel.es
SOLO PROGRAMADORES n 127 14
ACTUALIDAD
http://digital.revistasprofesionales.com
Un repaso a Java Expo
A lo largo de ms de 80 ponencias, esta edicin de
Java Expo ha servido para exponer puntos de
debate de mxima actualidad en mbitos como el
desarrollo de software en comunidad, los nuevos
modelos de servicios financieros, las ltimas pro-
puestas en el entorno de los servicios online de la
Administracin Pblica espaola, la productividad
de la distribucin y el impacto de la cadena de
valor, los nuevos servicios asociados a la evolucin
de las operadoras de telecomunicaciones o el futu-
ro tecnolgico del transporte inteligente en
Espaa.
Java Expo 2005 ha cobrado este ao un carcter
especial al coincidir con el 10 aniversario del naci-
miento de la tecnologa Java. Con este argumento,
y tambin para dar prestigio al evento, James
Gosling, vicepresidente de Sun Microsystems y
reconocido a nivel internacional como el padre de
Java, fue quien hizo la intervencin inaugural del
congreso. Durante dicha intervencin, hizo un
repaso de la evolucin de Java. Gosling, quien lide-
r el denominado Green Team, encargado de
desarrollar el lenguaje de programacin que en
1995 sera lanzado comercialmente con el nombre
de Java, manifest que: Estoy realmente orgulloso
de la dimensin que ha alcanzado el fenmeno
Java. En estos diez aos, esta tecnologa ha logrado
revolucionar reas que afectan a partes muy
importantes de nuestra vida, como puede ser el
cuidado de la salud. Y el futuro de Java estar en
cualquier lugar donde haya un dispositivo digital
conectado a la red al que se pueda aadir valor.
Demostraciones prcticas
Java Expo 2005 ha congregado a un amplio
espectro de profesionales con capacidad de deci-
sin de empresas de todos los tamaos, as como
a los profesionales tcnicos interesados en la
aplicacin de soluciones basadas en Java. A parte
de las sesiones plenarias, conferencias paralelas
y experiencias de xito basadas en Java, se habi-
lit una zona de exposicin en la que los asisten-
tes pudieron conocer, de primera mano, las solu-
ciones propuestas por Sun y su comunidad
iForce de partners tecnolgicos de valor aadido.
Entre otras muchas demostraciones, se presen-
ci una ilustracin prctica sobre Liberty, una
especificacin abierta que garantiza la identidad
en red y permite un inicio de sesin nico, segu-
ro y ubicuo para mltiples sitios web y mltiples
dispositivos conectados a Internet.
Conclusiones
La VIII edicin de Java Expo ha dejado patente
que en esta ltima dcada, gracias a su versatili-
dad, eficiencia, portabilidad y seguridad, Java se
ha convertido en una opcin muy importante
para el desarrollo y despliegue de aplicaciones y
servicios para la red, y ha generado a su alrede-
dor un ecosistema que crea cada vez mayores
oportunidades de negocio y valor aadido.
El pasado 1 de Junio tuvo lugar, en
Madrid, la VIII edicin de Java
Expo, un foro que cont con la
participacin de ms de 40 empresas
y con la asistencia de ms de 3000
profesionales.
CARLOS LAPARRA
Java Expo 2005
Java Expo 2005
Ms de 3000 profesionales se dieron cita en la VIII edicin de Java Expo.
SOLO PROGRAMADORES n 127 16
ACTUALIDAD
Inteligencia Ambiental:
la presencia invisible
Inteligencia Ambiental:
la presencia invisible
http://digital.revistasprofesionales.com
Introduccin
La Inteligencia Ambiental (AmI Ambient
Intelligence) es un modelo de interaccin en el
que las personas estamos rodeadas de un entor-
no digital consciente de nuestra presencia, sen-
sible al contexto, que responde de manera adap-
tativa a nuestras necesidades y hbitos, para
facilitarnos la vida diaria en el hogar, lugares de
ocio y trabajo.
Existe inteligencia en el ambiente, y es invisible.
Es una especie de ngel de la guarda, que nos
acompaa y nos ayuda, nos abre las puertas,
enciende las luces, nos indica que hay otro pro-
grama ms interesante en el televisor y paga
nuestro autobs.
Cunto tiempo invertimos al da en manipular
los elementos del entorno para configurarlos y
adaptarlos a nuestras necesidades en cada
momento? Se podran crear ambientes en los
que la interaccin activa del usuario sea mnima,
entornos que perciban las situaciones y respon-
dan de la manera adecuada?
El concepto de Inteligencia Ambiental dispone el
mundo al servicio de las personas. Como en un
cuento de hadas los objetos dejan de estar inani-
mados y reaccionan por iniciativa propia para
facilitarnos la vida: puertas de supermercado
que se abren a nuestro paso o grifos que propor-
cionan agua automticamente cuando nos
vamos a lavar las manos; estamos hablando de
un futuro que en cierta medida vive con nos-
otros desde hace algn tiempo y que cada vez
est ms presente.
Antes de seguir hay que sealar que en este
marco la palabra ambiente no debe interpretar-
se como medioambiente, sino como entorno,
y as, inteligencia ambiental se interpreta como
inteligencia en el entorno.
Componentes tecnolgicos
Desde un plano ms cientfico, vamos a analizar
las bases tecnolgicas que subyacen tras el con-
cepto de Inteligencia Ambiental. Los cuatro atri-
butos fundamentales que caracterizan un siste-
ma AmI son:
Computaci n, comuni caci n e i nfor-
maci n ubi cua: un usuario estar rodeado
de pequeas computadoras en su entorno,
que se comunican y gestionan la informacin
necesaria para adaptarse a las necesidades de
la persona. El televisor, el control de luces y de
calefaccin, el sistema de control de acceso
de la puerta o el salpicadero del vehculo son
algunos de los ejemplos de estos objetos
avanzados, representando una capacidad de
computacin y comunicacin por doquier,
vigilante, para reaccionar a la conducta del
usuario de manera inteligente.
Sensi bi l i dad al contexto: el entorno es
sensible a su circunstancia y a los elementos
que la determinan. Esta sensibilidad se imple-
menta mediante sensores, que permiten per-
cibir el entorno. No hay lmites para la natu-
raleza de dichos sensores, desde los ms pri-
mitivos como los sensores de temperatura, de
luz o de presencia, hasta los ms sofisticados
como microcmaras, o elementos software
reconocedores de patrones de conducta, que
correlacionan las entradas de los dems para
Cunto tiempo malgastamos
diariamente en hacer comprender
nuestras intenciones a los
dispositivos y servicios de alrededor
una y otra vez? Puede el sistema de
iluminacin de mi vivienda percibir
por s mismo si necesito luz o no
para leer o cocinar, y activarla si es
necesario? Si mi vecino siempre
sabe a qu piso voy, por qu no lo
sabe el ascensor que uso todos los
das? Existe un futuro donde todo
esto s es posible, y llega de la mano
de la Inteligencia Ambiental.
IAKI VZQUEZ y DIEGO LZ. DE IPIA GZ. DE ARTAZA
(Facultad de Ingeniera (ESIDE) - Universidad de Deusto)
La Inteligencia
Ambiental no se
siente, no se ve, no
se toca, pero acta
constantemente,
como una
presencia invisible
SOLO PROGRAMADORES n 127 17
ACTUALIDAD
http://digital.revistasprofesionales.com
identificar la situacin o tarea en la que
est inmerso el usuario. Incluso las tec-
nologas de comunicacin como Wi-Fi,
Bluetooth o RFID se pueden utilizar para
percibir la presencia de otra entidad,
como si de un sexto sentido se tratase.
I nt el i genci a: este entorno digital
dotado de capacidades de computacin
y percepcin es capaz de razonar sobre
los estmulos que detecta y reaccionar
de la manera que estima conveniente
para adaptarse a las necesidades del
usuario. El sistema de razonamiento
puede estar localizado en uno de los dis-
positivos, que coordina a los dems, o
ms bien, surgir de manera espontnea
por la aportacin individual y la coope-
racin entre stos. Por ejemplo, un pro-
fesor llega a su despacho, el sistema de
control de accesos de la puerta le iden-
tifica a travs del PDA y notifica de ello
al resto de dispositivos, provocando que
el ordenador realice un login automti-
co, y que la temperatura y luz se ajusten
automticamente a sus preferencias.
I nteracci n natural: el usuario no
tiene porqu ser un agente completa-
mente pasivo en este entorno, sino que
puede interactuar explcitamente
mediante mecanismos de comunicacin
similares a los que desarrolla de manera
natural, como la voz o los gestos. De
este modo, nuestro profesor podra
variar la temperatura del despacho, blo-
quear la puerta o apagar las luces solici-
tndolo al entorno.
En definitiva, estamos hablando de
ambientes con una cierta capacidad de
computacin y comunicacin, sensores,
procesamiento inteligente para la toma de
decisiones, que pueden interactuar con el
usuario de manera natural.
Como ya hemos comentado, la idea que se
esconde detrs de AmI es descargar a las
personas de la tarea de reconfigurar conti-
nuamente el entorno que nos rodea debido
al cambio de ciertas condiciones, la presen-
cia de nuevas entidades, el desarrollo de
otras actividades, etc. Es precisamente la
Inteligencia Ambiental presente en el
medio la que se encarga que ejecutar y
coordinar todas las acciones necesarias
para establecer el hbitat adecuado en el
que pueda desenvolverse nuestra conducta.
El paradigma de la Inteligencia Ambiental
se puede analizar en dos ejes diferentes,
propuestos por el ISTAG (Information
Society Technology Advisory Group, Grupo
de Asesoramiento en IST de la Comisin
Europea), y del que la figura 1 es una adap-
tacin.
Por una parte tenemos el eje horizontal,
que indica la proximidad de los conceptos o
componentes de una visin centrada en la
tecnologa a una visin centrada en la per-
sona. Por otra parte, el eje vertical seala la
naturaleza relacional del componente, su
aislamiento o capacidad de convergencia e
integracin con otros.
Los componentes tecnolgicos que pueden
ser aplicados en AmI se han dividido en tres
grandes bloques. El primero, Ambiente,
contiene los elementos particulares de
componente fundamentalmente tecnolgi-
ca que constituyen los bloques bsicos
sobre los que edificar un escenario de
Inteligencia Ambiental. El segundo bloque,
Inteligente, contiene los elementos parti-
culares ms prximos a prestar servicios a
la persona, que le proporcionan un mayor
valor aadido o interactan directamente
con ella.
El tercer bloque, en la parte superior del
grfico, es el verdadero desafo de AmI. Su
misin es aportar la integracin entre todos
estos elementos individuales para coordi-
Inteligencia Ambiental: la presencia invisible
Figura 1. Ejes de desarrollo de la Inteligencia Ambiental.
SOLO PROGRAMADORES n 127
nar su comportamiento, de tal manera que
constituye el sustrato del entorno inteli-
gente. Es aqu donde se ubican las arquitec-
turas tecnolgicas y los estndares que
permiten un entorno dinmico, de tipo Plug
and Play, donde emerge una percepcin
ambiental constante. Los dispositivos se
descubren unos a otros, se informan
mutuamente de las percepciones indivi-
duales, se toman decisiones coordinadas y
se ejecutan las adaptaciones individuales o
colectivas que sean necesarias.
El centro es la persona
Lo que diferencia el concepto europeo de
AmI respecto a otros similares como per-
vasive computing o sentient computing,
es su manifiesta orientacin, casi violen-
ta, a tomar a la persona como centro del
universo: que todos los ingenios, sistemas
y servicios giren alrededor de l para
extender y mejorar la propia experiencia
vital en cualquier mbito. Parafraseando
al ISTAG, la Inteligencia Ambiental debe
estar conducida desde una perspectiva
humanstica, no tecnolgica, y debe ser
controlable por gente corriente []. Debe
promover y facilitar la participacin
del individuo en la sociedad y en sus
diferentes comunidades, en todos los
aspectos de la vida, del entretenimiento al
gobierno.
As, finalmente, la Inteligencia Ambiental,
no slo consiste en un elevado desarrollo
tecnolgico en mltiples campos, que per-
mita facilitar la relacin de las personas con
su entorno de manera transparente, sino
que constituye una oportunidad para
mejorar y modernizar diversos aspectos del
modelo social.
El gap existente entre los desafos sociales
y la tecnologa se cubre mediante el con-
cepto de AmI Space: un escenario de apli-
cacin para un determinado tipo de situa-
ciones, donde la tecnologa est al servicio
de la sociedad para modelar un entorno
inteligente en el que puedan desenvolverse
las personas.
Hay diferentes AmI Spaces definidos para
mbitos paradigmticos: el hogar, el lugar
de trabajo, el vehculo, lugares de recreo,
etc. En cada uno de estos entornos las per-
sonas se comportan de modo diferente, las
tecnologas y la inteligencia invisible que
reside en el ambiente se enfocan de mane-
ras distintas.
Los desafos ms ambiciosos que propone
AmI no se espera que sean alcanzados
hasta el ao 2020, pero desde el da de hoy
y progresivamente ya se estn introducien-
do pequeas mejoras en nuestra vida dia-
ria, casi imperceptibles, que implementan el
verdadero concepto que subyace aqu. Ya
no nos sorprenden las puertas que se abren
ante nuestro paso, las luces que se encien-
den solas, o los sistemas de climatizacin
que se autoregulan segn la presencia o no
de personas en la sala.
Esta es la esencia de la Inteligencia
Ambiental: no se siente, no se ve, no se
toca, pero acta constantemente, como
una presencia invisible.
Un escenario, a modo de ejemplo
Para evaluar el impacto en nuestra vida
diaria derivado de la aplicacin de mecanis-
mos de Inteligencia Ambiental, propone-
mos un experimento. Vamos a narrar el
comportamiento y las acciones que lleva a
cabo una persona mientras se dirige de
casa al trabajo, y cmo algunas de dichas
acciones se podran automatizar con el
empleo progresivo de mecanismos de
Inteligencia Ambiental (vase el cuadro
adjunto).
El resultado es claro: sin AmI el usuario
debe realizar 14 acciones activas de mani-
pulacin del entorno, mientras que aplican-
do mecanismos de Inteligencia Ambiental,
se podran reducir a 5 acciones en las que
slo se requiere su confirmacin por moti-
vos de seguridad.
18
ACTUALIDAD
http://digital.revistasprofesionales.com
Figura 2. En AmI el concepto central es la persona, no la tecnologa que la sirve.
Figura 3. Los AmI Spaces son la aplicacin
de las tecnologas en mbitos concretos de
la vida.
SOLO PROGRAMADORES n 127
Conclusiones
Pero lo ms difcil an est por hacer. El
diseo de arquitecturas inteligentes que
permitan a los dispositivos encontrarse,
conocerse y negociar entre s a nivel
semntico, sistemas que perciban con un
mayor grado de certeza las intenciones de
un usuario para adaptar el entorno a las
tareas que desarrolla, interfaces naturales,
gestuales o vocales, que permitan que las
personas se comuniquen de manera no
artificial con los servicios a su alrededor y
que la interpretacin sea correcta, ... son
slo algunos ejemplos de las reas de tra-
bajo en las que se hallan inmersos muchos
equipos de investigacin internacionales.
Cuidado con los entusiasmos. El trabajo
bien hecho es firme, pero se desarrolla len-
tamente. Que la especulacin no nos con-
duzca a decepciones fcilmente evitables,
como ocurri con WAP o UMTS. Cada cosa
a su tiempo. Mantengamos las expectativas
de la Inteligencia Ambiental equilibradas
desde el principio, que avance firmemente,
cada vez con ms implantacin en nuestros
mbitos de vida: trabajo, vehculo, hogar...,
y as, sin que lo notemos, nuestro entorno
ser ms inteligente, ms receptivo, ms
reactivo y ms humano.
19
ACTUALIDAD
Inteligencia Ambiental: la presencia invisible
http://digital.revistasprofesionales.com
Referencias

IST Advisory Group. Ambient Intelligence: from
vision to reality. EU Publication. 2003.

IST Advisory Group. IST Research Content. EU
Publication. 2003.

IST Advisory Group. Scenarios for Ambient
Intelligence in 2010. EU Publication. 2001.

Lpez de Ipia, D. y Katsiri, E. An ECA Rule-
Matching Service for Simpler Development of
Reactive Applications. IEEE Distributed Systems
Online, vol. 2, number 7. 2001.

Vzquez Gmez, J.I. y Lpez de Ipia, D. An
Interaction Model for Passively Influencing the
Environment. Adjunct Proceedings of the 2nd
European Symposium on Ambient Intelligence.
Eindhoven, The Netherlands. November 2004.
Accin sin AmI Accin con Aml Posible mecanismo Aml aplicado
Al salir de casa, cierro la
puerta con llave...
Al salir de casa, la puerta se
bloquea automticamente
El sistema de control del hogar, al detectar que no queda nadie en
casa, decide bloquear la puerta. Puede solicitar confirmacin al usuario
...y llamo al ascensor
El ascensor acude a
recogerme
El sistema de presencia de la escalera, quiz consultando un registro
histrico, determina que el 98% de las veces que un usuario se
encuentra a esta hora en este piso, llama al ascensor
Me dirijo al garaje, pulso
el mando de apertura
para elevar la puerta
Me dirijo al garaje, cuya
puerta se abre ante mi
presencia
Mi PDA se valida en la entrada cuando me aproximo, lo que me
franquea el acceso. Puede solicitar confirmacin al usuario
Abro el vehculo y entro
El vehculo se abre de
manera automtica
Mi PDA sabe que hoy es da laboral (gestiona mi calendario) y por lo
tanto determina que voy al garaje a por el coche, e indica al vehculo
que se abra. Puede solicitar confirmacin al usuario
Inserto la llave y... ... me identifica...
El vehculo identifica al poseedor de la PDA (token de
identificacin) o mendiante otros mecanismos pasivos
(huella dactilar al tomar el volante, ...)
...lo pongo en
marcha
...ponindose en marcha... El vehculo se pone en marcha o la PDA se lo indica
Vuelvo a abrir la puerta
del garaje para salir
... y abriendo la puerta del
garaje a mi paso
El vehculo o la PDA abren la puerta del garaje
Sintonizo la emisora
de noticias mientras
conduzco al trabajo
El sistema de radio sintoniza la
emisora que suelo escuchar a
esa hora
El sistema de radio conoce mis preferencias y las activa, o bien mi PDA
se lo indica
Busco una plaza libre
durante cinco minutos y
aparco el vehculo
El vehculo me indica la ruta
ptima y cmo llegar a una
plaza libre
La PDA indica el destino al sistema de navegacin, que busca la ruta
ptima
Entro en mi edificio y me
valido con la tarjeta en la
entrada
El sistema de control de
accesos de edificio me
franquea la entrada
Mi PDA, tarjeta o tag verifican mi identidad por m
Indico mi piso en el
ascensor
El ascensor me recoge y me
lleva a mi planta
Esta identidad sirve para determinar mi destino en el ascensor, aunque
siempre puedo variarlo
Uso la llave de la puerta
del despacho para abrirlo
La puerta del despacho me
permite el paso
El mismo mecanismo de identificacin me valida en la puerta del
despacho. Puede solicitar confirmacin al usuario
Enciendo la luz del del
despacho
La luz se activa si es
necesario
El sistema de presencia del despacho determina que es necesario activar la
iluminacin
Enciendo mi ordenador
y me valido
El ordenador se inicia con mi
sesin, quiz previa confirmacin
El mismo mecanismo de identificacin me valida en la sesin del
ordenador. Puede solicitar confirmacin al usuario
: el usuario es el sujeto activo : el entorno es el sujeto activo : el entorno es el sujeto activo, solicitando confirmacin explcita del usuario
SOLO PROGRAMADORES n 127 20
DISPOSITIVOS MVILES
http://digital.revistasprofesionales.com
Introduccin
De todas las opciones para descargar aplicaciones
en un mvil, es la distribucin de aplicaciones Over
The Air, comnmente conocida como OTA, la que
nos abre mayores posibilidades.
Con este artculo iniciamos una serie en la que
veremos cmo implantar un sistema de distribu-
cin de Midlets basado en el Internet Information
Server, de aqu en adelante IIS. El desarrollo de un
sistema OTA nos va a permitir difundir nuestras
aplicaciones basadas en J2ME desde Internet. As
pues daremos las base tericas de la programacin
de una extensin IIS y se explicarn los conceptos
y elementos que estn detrs de OTA.
En una primera parte se har un repaso a los con-
ceptos de HTTP en los que se basa la distribucin
Over The Air, necesarios para entender el funciona-
miento de nuestro aplicativo. Se explicar cmo
crear una extensin para IIS y la diferencia con
otras tecnologas afines de Microsoft, as como las
APIs implicadas. Aunque se poda haber optado
por una solucin basada en Servlets o en mdulos
Apache, se han descartado ambas en favor de una
solucin basada en IIS por varios motivos.
En el caso de los Servlets se hubiera aportado
informacin que no resultara novedosa, dado que
la implementacin de un Servlet es realmente tri-
vial. En el caso de escribir un mdulo Apache an
no siendo obvia su creacin, se nos planteaba el
problema de decidir qu versin usar (1.x o 2.x) as
cmo explicar toda la temtica de la gestin de los
mdulos y filtros en Apache.
En todos los casos (Servlet, mdulos, extensiones)
nos basta con conocer poco ms de media docena
de funciones para implementar las funcionalida-
des bsicas necesarias.
Se ha optado por una implementacin en IIS por-
que an no teniendo una ventaja tcnica y de pro-
ductividad sobre las otras opciones, nos servir
para tratar otros temas al margen de OTA.
La aplicacin desarrollada podr ser ejecutada en
una variedad de sistemas operativos como
Windows 2000 Server, Windows 2003 Web Edition
(IIS 6.0) e incluso Windows XP Profesional (IIS 5.1).
Una cuestin a tener en cuenta es que la versin
de IIS que se entrega con Windows XP Profesional
no est pensada para un uso intensivo en web, de
hecho el nmero mximo de conexiones simult-
neas que puede mantener nunca debe exceder la
decena. Dadas las caractersticas de la propia apli-
cacin puede ser ms que suficiente en la mayora
de los casos, pero se recuerda que si se quiere
implantar en un entorno de explotacin con requi-
sitos que excedan lo personal se tendr que recu-
rrir a las licencias ms caras de las versiones
servidor.
Una observacin ms a tener en cuenta, es que
cuando desarrollemos extensiones deberemos
tener presentes las dependencias con otras DLL,
dado que pueden llevarnos a errores de funciona-
miento si stas no estn disponibles en el sistema
operativo destino.
Para verificar las dependencias podemos recurrir a
herramientas como tdump de Borland (con la
opcin em) o dumpbin de Microsoft (con la
opcin /IMPORTS).
Finalmente decir que la aplicacin se ha escrito en
C++ usando Visual Studio .NET 2003, aunque es
muy fcil portar el proyecto a otros compiladores
existentes.
Conceptos bsicos de HTTP
HTTP esta pensado para el tratamiento de infor-
macin distribuida cuyo mximo exponente es el
World Wide Web. Para localizar los recursos en la
web se usan las URL. A continuacin repasare-
mos cules son y cmo designaremos a los ele-
mentos que componen un Uniform Resource
Locator.
Una URL tiene la siguiente estructura:
[PROTOCOLO][HOST][PUERTO][VIA
DE ACCESO][CONSULTA]
Una vez se tiene desarrollada una suite
de Midlets la primera cuestin que nos
puede venir a la cabeza es Cmo
conseguir distribuirla de forma que
llegue al mximo nmero de
destinatarios?
JOS ANTONIO PREZ
Creacin de un sistema de
distribucin de Midlets (I)
Creacin de un sistema de
distribucin de Midlets (I)
En esta serie de
dos entregas
desarrollaremos
un servicio de
distribucin de
aplicaciones para
telfonos mviles
segn el modelo
OTA y basado
en IIS
SOLO PROGRAMADORES n 127 21
DISPOSITIVOS MVILES
http://digital.revistasprofesionales.com
En un recurso HTTP la URL tendra el
siguiente formato de forma ms especfica:
http://host[:puerto]
[va_de_acceso[?consulta]]
Slo los elementos protocolo y host son
obligatorios. La consulta o query nos per-
mite aadir parmetros a la peticin para
ayudar a producir contenidos de forma
dinmica.
A diferencia de otros protocolos como el
FTP en el que existe una sesin a nivel de
conexin entre el cliente y el servidor, el
HTTP es un protocolo sin estado (stateless).
En HTTP el cliente establece conexiones
puntuales con el servidor. Estas conexiones
finalizan con la respuesta del servidor, sin
pasar por estados como login, queries y
logout.
Las conexiones HTTP suele hacerse en el
puerto 80 (puerto por omisin). Otro puer-
to usado por convenio es el 8080.
Los datos que un cliente enva a un servidor
en una conexin HTTP y los datos que se
responden desde un servidor a un cliente se
dividen en dos partes: las cabeceras (HEA-
DER) y el cuerpo (ENTITY).
Las cabeceras estn formadas por una
sucesin de lneas de texto separadas por el
par de caracteres \r\n.
La primera lnea de las cabeceras que enva
un cliente a un servidor se usa para indicar
el mtodo de conexin y el recurso afecta-
do. El formato de esta lnea es:
<Mtodo de conexin><espacio><URI>
<espacio><Versin de HTTP><\r\n>
El <Mtodo de conexin> o verbo, es una
palabra reservada que indica el tipo de
conexin deseada por el cliente (GET,
POST...). El <URI> indica cmo identificar
el recurso o fuente a solicitar o interpelar
en el servidor. La <Versin de HTTP> indi-
ca la versin soportada por el cliente y es
nicamente el texto HTTP/ seguido del
nmero de versin y subversin separada
por un punto. Dos ejemplos de esta sintaxis
podran ser:
POST /midlets/midsvr.dll HTTP/1.1
GET /midlets/admin.htm HTTP/1.1
A continuacin de esta lnea obligatoria
para todas las peticiones HTTP aparecen
una sucesin de cabeceras que designare-
mos con el nombre de atributos, y sus valo-
res correspondientes. Cada atributo/valor
viene separado del siguiente por el par de
caracteres \r\n. Los atributos pueden ser
especificados en cualquier orden y no todos
los atributos son necesarios para una peti-
cin. El formato de las lneas que contienen
los atributos es:
<Nombre del atributo>
<el carcter:><espacio>
<valor del atributo><\r\n>
En el cuadro Campos de las cabeceras
HTTP ms usuales se describen los atribu-
tos ms corrientes. La lista de atributos
finaliza con una lnea vaca (nicamente
contiene el par de caracteres \r\n) vinien-
do a continuacin (s existe) el cuerpo de
mensaje o ENTITY. Las respuestas del servi-
dor tienen la misma estructura que una
peticin HTTP de cliente aunque difieren en
algunas cuestiones. La primera lnea del
rea de cabecera (lnea de estado) sirve
para retornar el cdigo de estado de la peti-
cin y tiene la siguiente estructura:
<Versin de HTTP> <Cdigo numrico
de estado> <espacio> <descripcin
del cdigo de la operacin> <\r\n>
Donde <Versin de HTTP> es nicamente
el texto HTTP/ seguido del nmero de ver-
sin y subversin separada por un punto. Los
cdigos de estado reportados por un servidor
HTTP estn categorizados en 5 grupos depen-
diendo del mbito de los mismos:
1xx: Cdigos informativos.
2xx: Cdigos de operacin finalizada
con xito.
3xx: Cdigos de redireccin.
4xx: Cdigos de error cuya causa est
en la peticin cliente.
5xx: Cdigos de error generados por el
servidor.
Los mtodos de conexin
El protocolo HTTP define 8 mtodos
de conexin. Veamos cada uno en
detalle:
OPTI ONS: representa una peticin
sobre las opciones de comunicacin.
Creacin de un sistema de distribucin de Midlets (I)
Campos de las cabeceras HTTP ms usuales
Nombre del campo
o atributo
Descripcin del campo Cliente Servidor
Accept
Indica los mime types de los
formatos de respuesta aceptados.
X
Accept-Encoding
Tipo de codificacin aceptada
(gzip, deflate, compress...).
X
Accpept-Language
Lenguaje preferencia para la
recepcin de la respuesta.
X
Cache-Control
Define el uso que hace de la
cache.
X
Connection Especifica el tipo de conexin. X X
Content-Encoding
Indica qu codificacin se aplica al
ENTITY.
X X
Content-Length Longitud total del ENTITY. X X
Content-Type
El tipo de contenido del ENTITY
(mime/type).
X X
Date
Fecha y hora en la que se
gener el mensaje.
X X
Host
Host y nmero de puerto del
recurso solicidado.
X
Location
Usado para redirigir el recipiente
a otra direccin.
X
Server
Contiene informacin acerca del
software del servidor.
X
User-Agent
Contiene informacin acerca del
agente que cre la peticin.
X
SOLO PROGRAMADORES n 127
GET: Se pide unos datos que se reciben
como parte de la respuesta del servidor.
Es el mtodo usado en las peticiones que
se realizan cuando se introduce una URL
en un navegador de Internet. La URI
contiene todos los parmetros que pue-
den ser necesarios para la peticin.
HEAD: es idntico al mtodo GET pero
el servidor no retorna el cuerpo de la
respuesta. Slo se envan las cabeceras.
POST: Se usa para pedir al servidor que
acepte las entities adjuntadas como
elementos de la peticin a realizar. Es el
mtodo usado tpicamente para enviar
formularios cuyos datos aparecen en el
cuerpo como parejas atributo-valores
separados por caracteres &. Caso
especial lo constituye el envo de varias
entidades en un mismo formulario para
enviar, por ejemplo, archivos al servidor,
(FORMS en los que se define el atribu-
to enctype=multipart/form-data). En
este caso se define un boundary para
separar los diferentes entities (vase
un ejemplo en la figura 1).
PUT: se pide que la entity adjunta se
guarde como la URI indicada.
DELETE: se pide al servidor que borre
un recurso identificado por la URI de la
peticin.
TRACE: permite al cliente ver qu es lo que
se est recibiendo al final de una peticin y
usar estos datos para test o diagnstico.
CONNECT: se usa para realizar conexiones
a un servidor a travs de un proxy.
Los mtodos de conexin ms frecuentes
usados por los navegadores son GET,
POST y CONNECT.
ASP, extensiones y filtros
El IIS permite que el desarrollador pueda ges-
tionar las peticiones web despreocupndose
de lo relativo a la conexin y centrndose en
la funcionalidad. Para ello proporciona tres
mecanismos: pginas ASP (ASP.NET), filtros y
extensiones. Las pginas ASP y ASP.NET com-
parten gran similitud en cuanto a la funcio-
nalidad y la finalidad de las pginas JSP, PHP,
o ColdFusion. Todas ellas son tecnologas que
permiten crear pginas dinmicas en el ser-
vidor. Las pginas ASP permiten usar objetos
COM de Windows para crear las pginas
HTML que se envan al lado cliente.
El cdigo de las pginas ASP puede incluir
tags HTML y cdigo escrito en VBScript o
JScript.
ASP.NET es el resultado de la evolucin de
las tecnologas de Microsoft orientado a la
creacin de contenidos dinmicos de la
web. ASP.NET hace posible que se use cual-
quier lenguaje de programacin con sopor-
te para .NET. Adems, al igual que ocurre en
otras tecnologas como los JSP, el cdigo se
compila la primera vez que se invoca una
pgina mejorando el rendimiento del servi-
dor. El interfaz de programacin de aplica-
ciones para el servidor de aplicaciones de
Internet (ISAPI) proporciona un conjunto
de interfaces para crear tanto extensiones
como filtros para el Internet Information
Server. Un filtro ISAPI es bsicamente una
DLL cargada por el IIS que examina y modi-
fica, si ello es necesario, los datos de entra-
da y/o salida del IIS. Los mbitos de aplica-
cin pueden afectar a seguridad-encripta-
cin, compresin, logs, autenticacin, etc.
Las extensiones amplan y mejoran las fun-
cionalidades del servidor (IIS), proporcio-
nando una funcionalidad semejante a la de
los CGI, permitiendo as crear contenidos
dinmicos. El servidor IIS delega en la
extensin la creacin de los datos solicita-
dos, pudiendo descargar la DLL transcurri-
do un tiempo sin actividad. La ventaja de
usar extensiones es que se puede trabajar a
nivel de cabeceras HTTP de forma fcil.
La estructura y ciclo de ejecucin
de una extensin IIS
Una extensin de IIS incluye normalmente
la definicin de tres funciones:
GetExtensi onVersi on es el punto de
entrada de una extensin ISAPI y se eje-
cuta siempre que se recarga la exten-
sin. Su signatura es:
BOOL WINAPI GetExtensionVersion
(HSE_VERSION_INFO *pVer);
El parmetro pVer es un puntero a una
estructura que podemos rellenar con
informacin acerca de la extensin
(nmero de versin y texto descriptivo).
Por ejemplo:
BOOL WINAPI GetExtensionVersion(OUT
HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = MAKE
LONG(HSE_VERSION_MINOR,
HSE_VERSION_MAJOR);
lstrcpyn(pVer->lpszExtensionDesc,
MidletServer for IIS,
HSE_MAX_EXT_DLL_NAME_LEN);
return TRUE;
}
Termi nateExtensi on es la funcin
que se llama cuando la extensin es des-
cargada por el servidor. Esta funcin,
aunque opcional, es interesante porque
nos permite finalizar y liberar recursos
que son usados durante la vida de la
extensin. Su signatura es:
BOOL WINAPI TerminateExtension
(DWORD dwFlags);
El nico parmetro, nos indica cundo la
extensin va a ser descargada. Si el valor es
HSE_TERM_ADVISORY_UNLOAD, pode-
22
DISPOSITIVOS MVILES
http://digital.revistasprofesionales.com
Figura 1. Una peticin HTTP puede servirnos
par enviar archivos binarios al servidor usando
como encoding el tipo multipart/form-data.
Figura 2. Para poder administrar la
extensin deberemos identificarnos en
primer lugar.
Figura 3. La aplicacin desarrollada
usar el mtodo POST para enviar las
peticiones del administrador.
SOLO PROGRAMADORES n 127
mos retornar FALSE para indicar al servidor
que no descargue la extensin. Si el valor es
HSE_TERM_MUST_UNLOAD, la descarga
de la extensin no se puede cancelar.
HttpExtensi onProc es invocada por
el servidor IIS cada vez que se recibe una
peticin. Su prototipo es:
DWORD WINAPI HttpExtensionProc
(EXTENSION_CONTROL_BLOCK *pEcb);
En sta funcin es el lugar donde el pro-
gramador debe incluir el tratamiento y res-
puesta a la peticin realizada. Para ello nos
proporciona un puntero a una estructura de
tipo EXTENSION_CONTROL_BLOCK que
como veremos es el elemento sobre el que
pivota todo el cdigo de una extensin IIS.
EXTENSION_CONTROL_BLOCK:
La estructura
Si hay un elemento fundamental en la pro-
gramacin de las extensiones IIS, ese es sin
duda alguna la estructura EXTENSION_
CONTROL_BLOCK. Todos los datos que
podemos obtener de una conexin y todas
las funciones que podemos ejecutar refe-
rente a una peticin vienen a travs de una
instancia de esta estructura. Los campos
que contienen son:
DWORD cbSi ze: Indica el tamao de la
propia estructura.
DWORD dwVersi on: Nmero de ver-
sin de la estructura. EL HIWORD con-
tiene el nmero mayor de la versin y el
LOWORD contiene el nmero de
versin menor.
HCONN ConnID: Es el handle asociado
a la conexin establecida entre el cliente
y el servidor. Nos permite poder leer
y escribir por los canales de lectura y
escritura. No se debe modificar su
valor.
DWORD dwHttpStatusCode: Es el
cdigo de estado de la transaccin
en curso cuando la peticin haya
finalizado.
CHAR lpszLogData[HSE_LOG_BUF-
FER_LEN]: Permite indicar una cadena
de caracteres acabada con terminador
nulo para que se escriba en el fichero de
logs del servidor IIS y que puede ser
usado con propsitos de anlisis por
parte del administrador.
LPSTR l pszMethod: Es un puntero a
una cadena con el mtodo de conexin
(GET, POST...)
LPSTR l pszQuer ySt r i ng: Es una
cadena de caracteres que contiene la
consulta o query de una peticin (recor-
dar el formato de una URL). Es equiva-
lente a usar la funcin Get
ServerVariable especificando como
nombre de variable QUERY_STRING.
LPSTR l pszPathI nfo: Es una cadena
de caracteres que contiene la va de
acceso proporcionada por el cliente. Es
equivalente a usar la funcin Get
ServerVariable especificando como
nombre de variable PATH_INFO.
LPSTR l pszPathTransl ated: Es equiva-
lente a usar la funcin GetServerVariable
especificando como nombre de variable
PATH_TRANSLATED.
LPSTR l pszContentType: Contiene el
valor de la cabecera HTTP Content-
Type.
LPBYTE l pbData: Es un puntero al
buffer que contiene los datos enviados
por el cliente. Aunque no tiene porque
contener todos los datos enviados.
DWORD cbTotal Bytes: Es el nmero
total de bytes recibidos desde el cliente
en el entity. Es el valor de la cabecera
HTTP Content-Length.
DWORD cbAvai l abl e: Nmero de
bytes disponibles en el buffer apuntado
lpbData. Si coincide con el valor de
cbTotalBytes, todos los datos estn en
el buffer. En caso contrario se debe
leer el resto usando la funcin
ReadClient.
Las APIs del IIS
Todas las APIs de IIS que se pueden ejecu-
tar en una extensin con respecto a una
conexin, las proporciona la instancia de la
estructura EXTENSION_CONTROL_BLOCK.
Esta estructura define cuatro punteros a
funciones:
GetServerVari abl e permite obtener el
valor de todas las variables de servidor
relacionadas con la peticin. Adems
nos permite acceder a los headers HTTP
de la peticin en curso. Su prototipo es:
BOOL (WINAPI *
GetServerVariable)(HCONN hConn,
LPSTR lpszVariableName, LPVOID
lpvBuffer, LPDWORD lpdwSize);
Donde hConn es el handle que indica el
canal de comunicacin en uso.
lpszVariableName hace referencia a la
variable de la que se quiere obtener el valor.
En el cuadro Variables del servidor pode-
mos ver algunas de las variables que pode-
mos consultar. Para acceder a las headers
HTTP, se debe especificar el nombre de la
cabecera en maysculas sustituyendo los
guiones por lnea de subrayado y con el
prefijo HTTP_. Por ejemplo, para conocer
el valor de la cabecera Content-Type ten-
dramos que especificar como nombre de la
variable HTTP_CONTENT_TYPE. En el cua-
dro Campos de las cabeceras HTTP ms
usuales podemos ver algunas de las varia-
bles. lpvBuffer es el buffer donde se
devuelve el valor de la funcin. lpdwSize
es un puntero a una variable que indica el
tamao mximo del buffer. Al finalizar la
peticin indica el nmero de bytes que
ocupa la respuesta:
std::string
GetVariable(EXTENSION_CONTROL_BLOCK
*pECB, const std::string & inName){
char szValue[512];
DWORD dwBuffSize = sizeof(szValue)
- 1;
/*HTTP_USER_AGENT ALL_HTTP
ALL_RAW... o cualquier otra*/
if(pECB->GetServerVariable(pECB-
>ConnID, (LPSTR)inName.c_str(),
szValue, &dwBuffSize))
return std::string(szValue);
return std::string();
}
Wri teCl i ent nos proporciona la forma
de escribir datos por el canal de respues-
ta. Su prototipo es:
BOOL (WINAPI * WriteClient)(HCONN
ConnID, LPVOID Buffer, LPDWORD
lpdwBytes, DWORD dwReserved);
23
Creacin de un sistema de distribucin de Midlets (I)
DISPOSITIVOS MVILES
http://digital.revistasprofesionales.com
Figura 4. La aplicacin desarrollada
cuenta con un interfaz con todos los
elementos necesarios para gestionar la
administracin de Midlets.
SOLO PROGRAMADORES n 127
El parmetro Buffer apunta a los datos
que se quieren enviar al cliente.
lpdwBytes es un puntero a una variable
que contiene el nmero de bytes a enviar
y que retorna el nmero de bytes envia-
dos. dwReserved sirve para indicar si la
escritura va a ser sncrona o asncrona. Los
valores que puede tomar son:
HSE_IO_SYNC
HSE_IO_ASYNC
En nuestra aplicacin usaremos el envo
de datos sncronos, aunque en aplica-
ciones de grandes requisitos pueda ser
aconsejable el uso de la escritura asn-
crona.
ReadCl i ent es usado para leer los
datos del entity que no estn disponi-
bles directamente en el buffer apuntado
por el campo lpbData de la estructura
EXTENSION_CONTROL_BLOCK. Su sig-
natura es:
BOOL (WINAPI *
ReadClient)(HCONN ConnID, LPVOID
lpvBuffer, LPDWORD lpdwSize);
Donde lpvBuffer apunta al buffer que
contiene los datos a enviar al cliente.
lpdwSize es un puntero a una variable
que contiene el nmero de bytes a
leer y que retorna el nmero de bytes
ledos.
ServerSupportFuncti on nos permite
ejecutar ciertas funciones de propsito
general especficas a la versin en uso
de IIS. Su signatura es:
BOOL (WINAPI *
ServerSupportFunction)(HCONN hConn,
DWORD dwHSERequest, LPVOID lpvBuffer,
LPDWORD lpdwSize, LPDWORD
lpdwDataType);
El parmetro dwHSERequest indica la
funcionalidad a usar. Los valores que
puede tomar son:
HSE_REQ_SEND_URL_REDIRECT_RESP
HSE_REQ_SEND_URL
HSE_REQ_SEND_RESPONSE_HEADER
HSE_REQ_DONE_WITH_SESSION
HSE_REQ_END_RESERVED
HSE_REQ_MAP_URL_TO_PATH
HSE_REQ_GET_SSPI_INFO
HSE_REQ_TRANSMIT_FILE
Nosotros, en nuestra aplicacin, usaremos
la funcin ServerSupportFunction con el
parmetro HSE_REQ_SEND_RESPON-
SE_HEADER. En este caso el parmetro
lpvBuffer se utiliza para indicar el cdigo
de estado a retornar. Si el puntero es nulo
es equivalente a explicitar 200 OK.
lpdwSize indica el tamao del buffer
lpdwDataType que sirve para cabeceras
opcionales.
Conclusiones
En esta entrega hemos visto los
elementos bsicos para implementar una
extensin IIS. Si bien lo aprendido puede
ser usado para la creacin de una
extensin con propsitos mltiples, en el
prximo artculo nos centraremos en la
aplicacin de los conceptos para crear
nuestro sistema de distribucin OTA que
es el objetivo final de la serie.
El lector encontrar en el cdigo fuente
que complementa a este artculo una
minuciosa explicacin de cmo ejecutar el
administrador de Midlets.
24
DISPOSITIVOS MVILES
http://digital.revistasprofesionales.com
Variables del servidor
Variable Descripcin
ALL_HTTP
Devuelve todas las cabeceras HTTP que se han recibido
pero anteponiendo el prefijo HTTP_.
ALL_RAW
Devuelve todas las cabeceras HTTP que se han recibido
sin procesar.
APPL_PHYSICAL_PATH Path fsico donde est situada la extensin.
CONTENT_LENGTH
Nmero de bytes en el entity o cuerpo de la peticin
en curso.
CONTENT_TYPE El tipo de contenido del entity.
PATH_INFO
Es la porcin de la URL despus del nombre de la
extensin (DLL) y antes de la query si se ha proporcionado.
PATH_TRANSLATED Conversin del PATH_INFO a su directorio fsico real.
REMOTE_ADDR
Proporciona la IP del cliente o agente (en el caso de
haber un cortafuegos, proxy o gateway) que ha
enviado la peticin.
REMOTE_HOST
Proporciona el nombre del cliente o agente que ha
enviado la peticin.
REMOTE_USER
El nombre del usuario que se ha conectado. Si el nombre
de usuario no necesita autenticacin (es annimo) el
valor ser una cadena vaca.
REQUEST_METHOD El mtodo de conexin (GET, POST...).
SERVER_NAME Es el nombre de Host o IP de la mquina del servidor.
SERVER_PORT Es el puerto por el que se ha recibido la peticin.
SERVER_PROTOCOL
Especifica el nombre y versin del protocolo asociado
a la peticin (HTTP/1.x).
SERVER_SOFTWARE Nombre y versin del web server.
Figura 5. Todas las peticiones y acciones
importantes de la aplicacin quedan
registradas en los ficheros diarios de log.
SOLO PROGRAMADORES n 127 26
MIDDLEWARE
Novedades en los lenguajes
de .NET 2.0 (y III)
Novedades en los lenguajes
de .NET 2.0 (y III)
http://digital.revistasprofesionales.com
Generics
Hemos dejado para esta tercera y ltima entrega
una de las novedades ms importantes que la nueva
versin de .NET Framework 2.0 nos trae. Como
comentamos de forma introductoria en el primer
artculo de esta serie (vase Slo Programadores
125), con generics podemos crear o usar clases
con mayor rendimiento y control, con la ventaja
aadida de que una misma clase o coleccin puede
sernos igualmente til sin importarnos (o casi) el
tipo de datos que finalmente contendr.
Para no reinventar la rueda, vamos a utilizar un
ejemplo clsico que clarifica perfectamente la uti-
lidad de utilizar colecciones generics frente a las
colecciones clsicas.
Cuando creamos una coleccin en .NET 1.x, el tipo
de datos que internamente usa la coleccin es
Object. Esto es as, ya que al ser el tipo bsico de
todos los tipos de .NET nos permite almacenar cual-
quier tipo de datos. El problema que tienen las
colecciones de tipo Object, es que si bien podemos
aadir nuevos elementos sin mucha prdida de ren-
dimiento (salvo en el caso de los tipos por valor), ese
rendimiento se ve penalizado cuando accedemos al
contenido de la coleccin, ya que debemos hacer
una conversin (cast) para poder recuperar el valor
en el tipo que originalmente usamos para almace-
narlo.
Aunque esta peculiaridad no es la nica desventa-
ja, ya que al ser una coleccin de tipo Object, no
podremos controlar qu tipo de datos se aaden, ya
que cualquier tipo que usemos ser vlido, por la
sencilla razn de lo que hemos comentado antes:
todos los tipos de .NET se derivan de Object. Para
poder restringir el tipo de datos, debemos hacer
nuestras propias comprobaciones en el cdigo, ya
que, por ejemplo, aunque nuestra intencin sea
almacenar solamente datos de tipo Cliente, nada
nos impide aadir una cadena o un valor entero. La
nica forma que tendramos de admitir slo obje-
tos de tipo Cliente sera creando nuestra propia
coleccin personalizada.
Generics en VB y en C#
En este artculo veremos los tipos generic tanto desde el
punto de vista del desarrollador de Visual Basic como el de
Visual C# e intentaremos mostrar las diferencias al usarlos
desde estos dos lenguajes.
Pero si la coleccin es generic, podemos hacer res-
tricciones y de esa forma ser el propio compilador
el que se encargue de hacer las comprobaciones
pertinentes, de forma que slo admita los tipos de
datos que hemos indicado al crear la coleccin.
En los listados 1 y 2 (VB y C# respectivamente)
podemos ver un ejemplo de estos dos casos, el pri-
mero es usando una coleccin de tipo ArrayList a
la que podemos aadir datos de distintos tipos, y en
el segundo, usamos una coleccin genrica (List) a
la que limitaremos el tipo de datos que podemos
aadir para que slo admita cadenas.
La primera coleccin del tipo ArrayList admite
cualquier tipo de datos, si nuestra intencin es
mantener slo elementos numricos, nada nos
impide agregar uno de cualquier otro tipo, sin
embargo, en la segunda coleccin hemos
usado una del espacio de nombres
System.Collections.Generic a la que le indicamos
que el tipo de datos que contendr ser de tipo
cadena (string). Esta coleccin no slo contendr
Para finalizar esta serie de tres
artculos sobre las novedades de
.NET Framework 2.0 y los dos
lenguajes principales (VB y C#),
vamos a ver una de las caractersticas
que ms darn que hablar, y de la que
tambin se escribir bastante: los
tipos generic.
GUILLERMO SOM EL GUILLE
(MVP de Visual Basic desde 1997)
Los tipos
generic
permiten la
creacin de tipos
de uso general sin
prdida de
rendimiento
LISTADO 1 Ejemplos con colecciones normales y del tipo generic (VB)
Sub Main()
Dim lista1 As New System.Collections.ArrayList
lista1.Add(Pepe)
lista1.Add(12)
Dim lista3 As New System.Collections.Generic.List(Of String)
lista3.Add(Hola)
lista3.Add(22)
End Sub
SOLO PROGRAMADORES n 127 27
MIDDLEWARE
http://digital.revistasprofesionales.com
internamente objetos del tipo indicado sino
que en tiempo de compilacin se comprobar
que el valor asignado sea del tipo correcto, en
caso contrario se producir un error, que en el
caso de Visual Basic, ste se mostrar justo
cuando escribamos el cdigo, mientras que si
elegimos C#, el error se producir al compilar.
Adems, el IDE de Visual Basic nos ofrece
ayuda para corregir el error, tal como pode-
mos ver en la figura 1.
El IDE de Visual Basic
Realmente esta ayuda que ofrece Visual Basic no est
relacionada con los generics, sino con el propio IDE.
De esta y otras peculiaridades o novedades del
entorno de desarrollo de Visual Studio nos ocupare-
mos en prximos nmeros de la revista.
Como podemos comprobar en el listado 1, para
declarar una coleccin generic en Visual
Basic debemos usar la instruccin Of seguida
del tipo de datos que queremos que contenga
dicha coleccin. Esta sintaxis es muy til para
los angloparlantes, ya que se leera como: list
of string (lista de string). En C# la sintaxis es
diferente y se utiliza el tipo de datos a usar por
la coleccin generic encerrado entre signos
de mayor y menor. Aunque la recomendacin
para leer este tipo de declaraciones es de la
misma manera que en VB: lista de string.
Esta peculiaridad (o forma de actuar) de los
generics est implementada en el propio CLR
(el runtime de .NET Framework), por tanto el
cdigo de Visual Basic y C# es mutuamente
compatible, ya que el cdigo IL (Intermediate
Language o lenguaje intermedio) generado
por los compiladores es el que finalmente se
usar en tiempo de ejecucin. Esto significa
que es el CLR el que realmente se encarga de
gestionar todo lo relacionado con las clases y
colecciones generic. Es decir, no es nada arti-
ficial que los compiladores de VB y C# tengan
que hacer, sino que es algo intrnseco del pro-
pio .NET.
Los tipos de colecciones generic
Las colecciones normales de .NET (las que no
son generic) se dividen principalmente en
tres tipos, segn la interfaz que implementen:
Las basadas exclusivamente en
ICollection, como Stack o Queue.
Las basadas en IList, como ArrayList y
todas las que accedan al valor que contie-
nen mediante un ndice numrico.
Las basadas en IDictionary, como
Hashtable y todas las que accedan al
valor que contienen mediante una clave.
Estas interfaces indicarn el comportamiento
de cada una de las colecciones, por ejemplo,
las que estn basadas en IList se comporta-
rn de forma distinta a las que estn basadas
en IDictionary, al menos en lo que se refiere
a la hora de aadir, recuperar o recorrer los
elementos que contienen. En el caso de las
colecciones de tipo diccionario los elementos
que contienen siem-
pre estn formados
por un par
clave/valor, y nor-
malmente para
recuperar el valor
guardado debemos
indicar la clave que
tiene relacionada.
Por otro lado, las
basadas en la inter-
faz IList los ele-
mentos se almace-
nan de forma que podamos acceder a ellos
indicando la posicin que ocupan, como si de
un array se tratase, de hecho, los arrays (que
realmente estn basadas en la clase Array),
tambin implementan la interfaz IList. Para
no crear confusin, debemos aclarar que tanto
las colecciones basadas en IList como las que
se basan en IDictionary tambin se basan o
implementan la interfaz ICollection, de
hecho todas las clases del espacio de nombres
System.Collections se basan en esa interfaz.
Y que tiene que ver todo esto con los tipos de
colecciones generic?
Pues que todas las colecciones del espacio de
nombres System.Collections.Generic tam-
bin estn basadas en estos tres tipos de inter-
faces, aunque en las versiones generic de las
mismas, es decir, las interfaces tambin defi-
nen un parmetro con el tipo de datos que
internamente manipularn.
Al igual que ocurre con las colecciones no
generic, todas las colecciones del espacio de
nombres System.Collections.Generic se
basan en la interfaz ICollection, aunque slo
unas pocas clases son las que utilizan esa
interfaz de forma exclusiva, tal como
ocurre con su hermana no generic. En el
espacio de nombres Generic tambin encon-
traremos colecciones basadas en las otras dos
interfaces: IList e IDictionary. De hecho la
coleccin Generic.List, (usada en el listado 1),
es una coleccin que implementa la interfaz
IList.
Como es de suponer, todas estas interfaces (y
sus colecciones derivadas), al ser del tipo
generic, nos sirven para usarlas con cual-
quier tipo de datos, (el indicado en el cons-
tructor). Despus de crearlas, las usaremos
como cualquier otra coleccin. Es importante
destacar que en el caso de las colecciones
basadas en Generic.IDictionary debemos
tener en cuenta un pequeo detalle, y es que
las colecciones de tipo IDictionary, sean o no
generic, para recorrer los elementos que
contienen siempre tendremos que hacerlo uti-
lizando un tipo especial, ese tipo nos permiti-
r acceder al par clave/valor que es lo que real-
mente la coleccin contiene. En las coleccio-
nes normales el tipo de datos que usaremos
en el bucle es DictionaryEntry, mientras que
en las colecciones generic usaremos un
objeto del tipo KeyValuePair; tanto uno
como otro contienen dos propiedades, Key y
Value, con las que podremos acceder respec-
tivamente a la clave y al valor propiamente
dicho. En el caso del tipo DictionaryEntry,
esas dos propiedades son de tipo Object, sin
Novedades en los lenguajes de .NET 2.0 (y III)
LISTADO 2 Ejemplos con colecciones normales y del tipo generic (C#)
static void Main(string[] args)
{
System.Collections.ArrayList lista1 = new System.Collections.ArrayList();
lista1.Add(Pepe);
lista1.Add(12);
System.Collections.Generic.List<string> lista3 = new
System.Collections.Generic.List<string>();
lista3.Add(Hola);
lista3.Add(22);
}
Figura 1. Error y sugerencia para solucionar el error de asignacin
de tipo no adecuado.
SOLO PROGRAMADORES n 127
embargo el tipo KeyValuePair, al ser gene-
ric, los tipos de las dos propiedades deben ir
en consonancia con los indicados al instanciar
la coleccin en la que lo usemos para recorrer
los elementos.
Aclaremos este punto. Al crear una coleccin
basada en Generic.IDictionary, al contener
elementos del tipo clave/valor, debemos indi-
car de qu tipo ser tanto la clave como el
valor, por tanto al recorrer los elementos
usando un tipo KeyValuePair, tambin ten-
dremos que indicar los tipos a los que accede-
r. En los listados 3 y 4 (para VB y C# respec-
tivamente) tenemos un ejemplo en el que
almacenamos valores de tipo Cliente y para
la clave utilizamos un tipo String.
Como puede verse en los listados, al declarar
la coleccin indicamos los tipos a usar, aadi-
mos algunos valores y para recorrer todos los
elementos usamos un bucle For Each con
una variable del tipo KeyValuePair a la que le
indicamos los mismos tipos que contiene la
coleccin (vase tambin la figura 2). Tal como
podemos comprobar, al acceder a cada ele-
mento, ya sea directamente mediante el indi-
zador (propiedad predeterminada) o por
medio de la variable usada en el bucle, pode-
mos utilizar directamente las propiedades de
la clase almacenada (del tipo Cliente). Si esto
mismo lo hubisemos hecho con una colec-
cin no generic, tendramos que haber
hecho una conversin del tipo interno al tipo
real. En los listados 5 y 6 podemos ver el
cdigo equivalente usando una coleccin del
tipo Hashtable (no generic). Como vemos,
en las colecciones normales siempre se usa
un objeto de tipo Object para almacenar los
valores, incluso par clave/valor del tipo
DictionaryEntry tambin es de tipo Object,
lo que nos obliga a hacer una conversin del
tipo interno al tipo real, en nuestro ejemplo
de tipo Cliente.
Incluso si definiramos una coleccin perso-
nalizada nos veramos obligados a hacer dicha
conversin de datos aunque fuese de forma
interna, ya que externamente al estar prepa-
rada para soportar objetos de tipo Cliente
no tendramos que hacer ninguna conversin.
Con idea de no alargar el artculo con dema-
siado cdigo extra, los ejemplos para este caso
y las definiciones de la clase Cliente se inclu-
yen en el cdigo que acompaa a la revista.
Mtodos generic
Tal como hemos comprobado, existe un espa-
cio de nombres en el que se incluyen las colec-
ciones generic, por tanto todas las clases o
tipos incluidos en ese espacio de nombres nos
permitirn crear colecciones que utilicen esta
nueva caracterstica de .NET 2.0; pero la ven-
taja de esta nueva tecnologa es que nos-
otros tambin podemos definir nuestros pro-
pios tipos de datos generic, con lo cual
podremos crear clases y colecciones que pue-
dan ser restrictivos a la hora de usarlos, y
como veremos en breve, no slo se podrn
hacer restricciones por medio del tipo usado
para declarar el objeto, sino que tambin
podremos poner nuestras propias normas o
condiciones a esos tipos, de forma que deban
tener ciertas caractersticas para que poda-
mos usarlos para crear
esos objetos.
Pero antes de entrar en las
interioridades de los tipos
generic, veamos cmo
podemos crear mtodos
con parmetros de tipo
genrico, de forma que
podamos usarlos con
cualquier tipo de datos.
Para definir un mtodo
con argumentos genri-
cos, simplemente usamos la misma sintaxis
que para las colecciones del espacio de nom-
bres Generic. El cdigo del listado 7 nos per-
mitir llamar al mtodo Mostrar usando
cualquier tipo.
Este mtodo mostrado en el listado 7 pode-
mos usarlo indicando cualquier tipo de datos,
por ejemplo:
Mostrar(10)
Mostrar(Hola)
Cuando usamos este mtodo, el tipo indica-
do en Visual Basic con Of, (T en el ejem-
plo), o el incluido dentro de <> si estamos
usando C#, lo podemos usar como el tipo de
28
MIDDLEWARE
http://digital.revistasprofesionales.com
LISTADO 3 Ejemplo de coleccin Generic.Dictionary (VB)
Dim di As New Dictionary(Of String, Cliente)
di.Add(uno, New Cliente)
di.Add(dos, New Cliente(Pepe, Lpez))
di(uno).Nombre = Juan
di(uno).Apellidos = Ruiz
For Each kv As KeyValuePair(Of String, Cliente) In di
Console.WriteLine(Clave: {0} Valor: {1}, _
kv.Key, kv.Value.Nombre)
Next
LISTADO 4 Ejemplo de coleccin Generic.Dictionary (C#)
Dictionary<string, Cliente> di = new Dictionary<string, Cliente>();
di.Add(uno, new Cliente());
di.Add(dos, new Cliente(Pepe, Lpez));
di[uno].Nombre = Juan;
di[uno].Apellidos = Ruiz;
Console.WriteLine(Usando Dictionary);
foreach(KeyValuePair<string, Cliente> kv in di)
Console.WriteLine(Clave: {0} Valor: {1}, kv.Key, kv.Value.Nombre);
LISTADO 5 Ejemplo de coleccin Hashtable (VB)
Dim di As New Hashtable
di.Add(uno, New Cliente)
di.Add(dos, New Cliente(Pepe, Lpez))
TryCast(di(uno), Cliente).Nombre = Juan
CType(di(uno), Cliente).Apellidos = Ruiz
For Each de As DictionaryEntry In di
Console.WriteLine(Clave: {0} Valor: {1}, _
de.Key, CType(de.Value, Cliente).Nombre)
Next
Figura 2. Las colecciones generic saben qu tipos de datos
contienen.
SOLO PROGRAMADORES n 127
datos que se usar al llamar al mtodo. Por
esa razn se puede usar esa letra para indi-
car un tipo de datos, que es el caso del argu-
mento pasado al mtodo. Es decir, el tipo
genrico slo se conocer cuando se use el
mtodo, pero nosotros podemos hacer refe-
rencia a l usando el parmetro con tipo
(type parameter). El problema que nos pode-
mos encontrar en estos casos es que no
podemos hacer grandes cosas con ese tipo
dentro del mtodo. Por la sencilla razn de
que ese tipo puede ser de cualquier tipo
(valga la redundancia), por tanto no podre-
mos llamar a mtodos que suponemos que
pueda tener, ni realizar operaciones aritmti-
cas, etc. Realmente los nicos mtodos que
podremos usar son los propios del tipo
Object, por la sencilla razn de que estn
presentes en todos los tipos de datos de .NET.
Sabiendo esto, podramos pensar que mejor
sera indicar el parmetro como de tipo
Object y no nos complicamos tanto la vida.
Pero si as fuera, que como veremos no esta-
mos tan restringidos, tambin valdra la pena
usar generic, la principal razn es la que
apuntamos anteriormente de que el tipo
usado realmente es el tipo que indiquemos al
llamar al mtodo (o cualquier otro elemento
que utilice generic), por tanto el rendimien-
to lo tenemos asegurado, ya que en el caso
de los tipos por valor, el CLR no se ver en la
necesidad de hacer boxing y unboxing, es
decir, convertir de tipo por valor a tipo por
referencia y viceversa. Y en el caso de los
tipos por referencia no tendremos que hacer
conversiones para convertirlo de Object al
tipo real.
Declaracin de tipos generic en
VB y C#
La forma de declarar los tipos generic es algo con lo
que tendremos que acostumbrarnos a convivir, ya
que este tipo de datos lo utilizaremos con bastante
frecuencia, no slo porque ahora vayamos a definir
muchos de nuestros tipos o mtodos usando gene-
ric, sino porque la nueva versin de .NET est plaga-
da de ellos, por tanto, los utilizaremos con bastante
frecuencia. Si bien es cierto que la sintaxis de C#,
aunque en principio pudiera parecer ms rebuscada,
a la larga resulta ms intuitiva o al menos no tan
repetitiva como la de Visual Basic, ya que en este
ltimo lenguaje tanto para la declaracin del tipo que
contendr como para los parmetros, (tal como
podemos comprobar en el cdigo del listado 7), debe-
mos indicarlos entre parntesis, con lo que puede
parecer una redundancia que hasta que no nos acos-
tumbremos a usarlos, seguramente nos complicar
un poco la existencia.
Restricciones (constraints)
En el cdigo del listado 7 simplemente indica-
mos que se usan tipos generic, y tal como
hemos comentado no podemos hacer ningn
tipo de operacin con el objeto usado interna-
mente, salvo usar los mtodos y propiedades
de la clase Object. Por tanto, si queremos
hacer algo dentro del mtodo Mostrar, no
podramos, ya que no sabemos cul ser el
tipo de datos que el usuario finalmente usar.
Cmo solucionamos estos inconvenientes?
Usando restricciones.
Aunque parezca lo contrario, las restricciones
nos permiten afinar en el tipo que podremos
pasar como argumento.
Supongamos que queremos usar slo tipos
por valor en nuestro mtodo (o clase gene-
ric), simplemente hacemos una restriccin
para que el compilador sepa que esa es nues-
tra intencin. O bien podemos restringir a
tipos de datos que se deriven de otros o que
implementen cierta interfaz o que tenga un
constructor o que sea un tipo por referencia.
En el cdigo de los listados 8 y 9 hemos crea-
do una versin del mtodo Mostrar para que
slo acepte como argumento un objeto que
sea de tipo por valor, por tanto slo admitir
los tipos por valor definidos en los lenguajes (y
el propio .NET), as como todas las estructuras
que nosotros definamos.
Con esta restriccin lo nico que conseguimos
es no permitir usar valores de tipos por refe-
rencia, pero tampoco podemos hacer ningn
tipo de operacin con el parmetro que recibe
el mtodo. Aunque tambin podemos hacer
restricciones que afinen ms, es decir, pode-
mos hacer mltiples restricciones, por ejem-
plo, si queremos comparar los objetos pasados
al mtodo, podemos aadir una nueva restric-
cin: que implemente la interfaz ICom-
parable.
Antes de ver el cdigo, (el cual recordemos que
podemos obtener al completo en el material
complementario de este artculo), debemos
fijarnos en cmo se hacen las restricciones
tanto en VB como en C#. En el caso de Visual
Basic, la restriccin la hacemos indicando As
<tipo> junto a la declaracin del tipo a usar
en el mtodo, mientras que en C# las restric-
ciones las haremos usando where y despus
del tipo de parmetro (separado por dos
puntos) indicaremos la restriccin.
Hacer varias restricciones
Cuando queramos hacer ms de una restric-
cin, la sintaxis de C# sigue siendo la misma,
es decir, despus de where <tipo del parme-
tro> : indicaremos cada una de las restriccio-
nes que creamos oportunas, simplemente
separndolas con una coma. Mientras que en
Visual Basic la sintaxis cambia un poco, ya que
si hay ms de una restriccin estas deben
incluirse dentro de un par de llaves y dentro de
las llaves las separaremos con comas: <tipo
del parmetro> As {restriccin1, restriccin2,
..., restriccinN}.
En el cdigo del listado 10 podemos ver las
declaraciones de un mtodo Mostrar que res-
trinja los datos a usar para que slo se acepten
tipos por valor y tipos que implementen la inter-
faz En este cdigo utilizamos dos parmetros
que son del mismo tipo que el parmetro con
tipo (type parameter) que podemos usar: los dos
tienen las mismas restricciones.
Pero tambin podemos indicar ms de un
parmetro tipado de forma que los parme-
tros del mtodo puedan ser de cualquiera de
esos tipos, e incluso de tipos normales, es
decir, tipos que no tengan porqu estar defini-
dos en la lista de parmetros con tipo.
Para indicar ms de un tipo de parmetro del
mtodo genrico (esto tambin ser aplicable
29
MIDDLEWARE
Novedades en los lenguajes de .NET 2.0 (y III)
http://digital.revistasprofesionales.com
LISTADO 6 Ejemplo de coleccin Hashtable (C#)
Hashtable di = new Hashtable();
di.Add(uno, new Cliente());
di.Add(dos, new Cliente(Pepe, Lpez));
((Cliente)di[uno]).Nombre = Juan;
((Cliente)di[uno]).Apellidos = Ruiz;
foreach(DictionaryEntry de in di)
Console.WriteLine(Clave: {0} Valor: {1}, de.Key,
((Cliente)de.Value).Nombre);
LISTADO 7
Un mtodo con
argumentos generic
Cdigo para Visual Basic
Sub Mostrar(Of T)(ByVal p As T)
Console.WriteLine(p)
End Sub
// Cdigo para C#
static void Mostrar<T>(T p)
{
Console.WriteLine(p);
}
SOLO PROGRAMADORES n 127
a las clases o tipos genricos que definamos), lo
haremos en el sitio donde se indican los parme-
tros con tipo, separndolos con comas. Esos tipos
tambin podrn tener restricciones diferentes, (en
un momento veremos cmo aplicarlas), para que
de esta forma podamos hacer distinciones entre
esos parmetros, y esas restricciones se tengan en
cuenta al pasar los argumentos reales al mtodo.
En el listado 11 podemos ver cmo indicar dos
tipos de parmetros con restricciones distintas. En
la lista de parmetros del mtodo podremos usar-
los en conjunto con cualquier otro tipo de datos.
Es decir, los parmetros del mtodo se definen de
la forma habitual, independientemente de que se
utilicen tipos normales o los definidos en la lista
de tipos de parmetros genricos que se indicarn
al llamar al mtodo.
En esta definicin lo que hacemos es utilizar dos
parmetros genricos, el primero debe implemen-
tar la interfaz IComparable, el segundo debe ser
un tipo por referencia adems de implementar esa
misma interfaz. En la lista de parmetros del
mtodo usamos esos dos tipos adems de uno del
tipo DateTime.
Como podemos comprobar, la forma de definir los
tipos de parmetros genricos y las restricciones
aplicables a cada uno depender de que lenguaje
estemos usando. En VB siempre se hacen las res-
tricciones en el mismo sitio en el que definimos los
tipos y solamente usamos una vez la instruccin
Of. Sin embargo en C#, la lista de tipos de par-
metros la hacemos justo despus de la definicin
del mtodo y las restricciones las hacemos des-
pus de la lista de parmetros del mtodo, para
cada tipo utilizamos una instruccin where y las
restricciones que correspondan. En ambos casos
utilizamos la instruccin class para indicar que el
argumento que pasemos al llamar al mtodo debe
ser un tipo por referencia, en caso de hacerlo junto
a otras restricciones, en C# esa instruccin debe
aparecer antes que el resto de restricciones, en VB
da igual donde lo indiquemos.
Tipos de restricciones que podemos hacer
Tal como hemos estado viendo en los cdigos
de ejemplo, podemos hacer varios tipos de
restricciones al indicar los parmetros con
tipo, las restricciones que podemos usar son
las siguientes:
Que sea un tipo por valor, para ello utiliza-
remos struct (C#) o Structure (VB).
Que sea un tipo por referencia, lo indicare-
mos con class (C#) o Class (VB).
Que tenga un constructor sin parmetros,
lo indicaremos con new() (C#) o New
(VB).
Cualquier clase, en este caso el argumen-
to indicado debe derivarse de esa clase.
Una o ms interfaces, el argumento
debe implementar todas las interfaces
indicadas.
Si indicamos que el argumento a pasar debe
ser por valor o por referencia, en C# ste debe
aparecer antes que el resto de restricciones, en
VB puede aparecer en cualquier orden.
Y si indicamos que debe tener un constructor
sin parmetros, en C# lo debemos indicar al
final de las restricciones, en VB no importa el
orden.
Cualquiera de los tipos o interfaces que indi-
quemos pueden ser normales o generic.
Definir nuestros tipos generic
Para ofrecer un repaso completo a los tipos
genricos, vamos a explicar cmo definir nues-
tros propios tipos genricos, ya sean clases,
estructuras o interfaces.
La forma de definir nuestros propios tipos
genricos no vara mucho a como definimos los
mtodos genricos. La parte importante es que
podemos indicar uno o ms tipos de parmetro
a usar al declarar la clase, con sus correspon-
30
MIDDLEWARE
http://digital.revistasprofesionales.com
LISTADO 8 Un mtodo que restringe el parmetro a tipos por valor (VB)
restringir a slo tipos por valor (estructuras)
Sub Mostrar1(Of T As Structure)(ByVal p As T)
Console.WriteLine(p)
End Sub
LISTADO 9 Un mtodo que restringe el parmetro a tipos por valor (C#)
// restringir a slo tipos por valor (estructuras)
static void Mostrar1<T>(T p) where T : struct
{
Console.WriteLine(p);
}
LISTADO 10 Declaracin de un mtodo con mltiples restricciones (VB y C#)
Cdigo para Visual Basic
Sub Mostrar2(Of T As {Structure, IComparable})(ByVal v1 As T, ByVal v2 As T)
// Cdigo para C#
static void Mostrar2<T>(T v1, T v2) where T : struct, IComparable
LISTADO 12 Definicin de una clase generic (VB)
Public Class ListaPersonas(Of T As Persona)
Implements IEnumerable

Private lista As New List(Of T)

Public Sub Add(ByVal valor As T)


lista.Add(valor)
End Sub

Default Public ReadOnly Property Item(ByVal index As Integer) As T


Get
Return lista(index)
End Get
End Property
Public Function GetEnumerator() As IEnumerator Implements
IEnumerable.GetEnumerator
Return lista.GetEnumerator
End Function
End Class
LISTADO 11 Varios tipos con distintas restricciones (VB y C#)
Sub Mostrar3(Of T1 As IComparable, T2 As {IComparable, Class})(ByVal v1 As T1,
ByVal v2 As T2, ByVal v3 As DateTime)
static void Mostrar3<T1, T2>(T1 v1, T2 v2, DateTime v3) where T1 : IComparable
where T2 : class, IComparable
{
SOLO PROGRAMADORES n 127
dientes restricciones y ese tipo (o tipos) los
podemos usar dentro de la clase para indicar el
tipo de datos a usar en las propiedades, mto-
dos, etc. que definamos. Aclaremos las cosas
viendo un poco de cdigo. En los listados 12 y
13 tenemos la definicin de una clase/coleccin
en la que utilizamos como parmetro de tipo
genrico un objeto que sea o se derive de la
clase Persona. Ese tipo est indicado con el
smbolo T. Ese tipo annimo lo utilizamos
para la coleccin interna como parmetro del
mtodo Add y como el valor devuelto por la
propiedad predeterminada (indizador). Para
almacenar los elementos que contenga la clase
de los listados anteriores utilizamos una colec-
cin Generic.List porque nos permite almace-
nar tipos genricos, en este caso del tipo T,
es decir el indicado al crear nuestra clase/colec-
cin. Los tipos de datos que se pueden aadir a
nuestra coleccin sern del tipo T y el valor
que devuelve la propiedad predeterminada
(Item en VB, el indizador en C#), tambin ser
del mismo tipo que el usado al instanciar nues-
tra clase.
Adems de la definicin de esta clase genrica,
hemos creado tres clases: La clase Persona y
otras dos clases derivadas de sta. Como la res-
triccin que hemos hecho es que sea del tipo
Persona, tambin podremos usar como tipo
de nuestra clase cualquiera que se derive de ella
(en nuestro caso hemos definido una clase
Cliente y otra Empleado que se derivan de
Persona), por tanto podemos usar un cdigo
como el mostrado en los listados 14 y 15.
En la clase ListaPersonas no hacemos ningn
uso especfico del tipo indicado como par-
metro de tipo, por tanto podramos pensar
que no haca falta indicar esa restriccin, pero
es que en este caso, nos interesaba que nues-
tra clase genrica solamente aceptara objetos
que se deriven de la clase Persona, por eso
hemos hecho esa restriccin. De esta forma,
si la clase Persona define algn mtodo o
propiedad que nos interese utilizar en el tipo
indicado al crear nuestra clase genrica, lo
podremos hacer sin ningn tipo de problema.
Conclusiones
Confiamos en que lo aqu expuesto sirva para
aclarar cmo funcionan los tipos genricos y
nos aliente a experimentar con ellos, ya que
como suele ocurrir con las novedades de cual-
quier lenguaje, slo se pueden saborear cuan-
do realmente nos acostumbramos a utilizarlas,
y eso es lo que hemos pretendido con esta
serie de tres artculos sobre las novedades de
.NET Framework 2.0 y de los dos lenguajes
principales de la familia de Visual Studio 2005:
mostrar las novedades ms importantes y tra-
tar de explicar, con las limitaciones de espacio
propias de una revista, cmo podemos usarlas.
Precisamente por eso incluimos el cdigo de
ejemplo completo en el CD de la revista, cdi-
go que debemos advertir que es vlido para la
versin beta 2 de Visual Studio 2005 y que se
puede usar indistintamente con las versiones
Express de los lenguajes, y como no es costum-
bre que despus de una beta 2 haya muchos
cambios en los lenguajes, esperamos que sigan
siendo vlidos en la versin definitiva.
31
MIDDLEWARE
Novedades en los lenguajes de .NET 2.0 (y III)
http://digital.revistasprofesionales.com
LISTADO 13 Definicin de una clase generic (C#)
public class ListaPersonas<T> : IEnumerable where T : Persona
{
//
private List<T> lista = new List<T>();
//
public void Add(T valor)
{
lista.Add(valor);
}
//
public T this[int index]
{
get
{
return lista[index];
}
}
//
public System.Collections.IEnumerator GetEnumerator()
{
return lista.GetEnumerator();
}
}
LISTADO 14 Usando nuestra clase genrica (VB)
Dim emp As New ListaPersonas(Of Empleado)
Dim cli As New ListaPersonas(Of Cliente)
Dim per As New ListaPersonas(Of Persona)

emp.Add(New Empleado(Pepe, Snchez, 1200))


emp.Add(New Empleado(Juan, Ruiz, 1300))
emp.Add(New Empleado(Luisa, Gmez, 1500))

cli.Add(New Cliente(Muebles Snchez, 12200))


cli.Add(New Cliente(Electricas Unidas, 7500.55D))

For Each p As Persona In emp


per.Add(p)
Next
For Each c As Persona In cli
per.Add(c)
Next

For Each p As Persona In per


Console.WriteLine(Tipo: {0}, Contenido: {1}, p.GetType.Name, p)
Next
LISTADO 15 Usando nuestra clase genrica (C#)
ListaPersonas<Empleado> emp = new ListaPersonas<Empleado>();
ListaPersonas<Cliente> cli = new ListaPersonas<Cliente>();
ListaPersonas<Persona> per = new ListaPersonas<Persona>();
//
emp.Add(new Empleado(Pepe, Snchez, 1200));
emp.Add(new Empleado(Juan, Ruiz, 1300));
emp.Add(new Empleado(Luisa, Gmez, 1500));
//
cli.Add(new Cliente(Muebles Snchez, 12200));
cli.Add(new Cliente(Electricas Unidas, 7500.55M));
//
foreach (Persona p in emp)
per.Add(p);
foreach (Persona c in cli)
per.Add(c);
//
foreach (Persona p in per)
Console.WriteLine(Tipo: {0}, Contenido: {1}, p.GetType().Name, p);
SOLO PROGRAMADORES n 127 32
MIDDLEWARE
http://digital.revistasprofesionales.com
Introduccin
En el nmero anterior vimos lo que nos puede
aportar Struts a la hora de desarrollar aplicacio-
nes J2EE e incluimos una aplicacin de referen-
cia donde plasmamos los conceptos bsicos de la
arquitectura MVC que propone Struts (Actions,
ActionMappings, ActionsForms, libreras de eti-
quetas). En este artculo vamos a centrarnos en
aspectos ms avanzados que, aunque no son
imprescindibles en el desarrollo de aplicaciones
bsicas, s nos facilitan mucho la vida a la hora
de abordar aplicaciones de cierta complejidad.
En primer lugar habilitaremos nuestra aplicacin
para el soporte de varios idiomas (haremos que
nuestra aplicacin de ejemplo soporte los idio-
mas ingls y espaol). Luego veremos cmo usar
plantillas a la hora de disear la interfaz de
usuario, un concepto que no existe en J2EE y que
introduce el componente Tiles de Struts. Por lti-
mo veremos cmo realizar las validaciones de
campo en las interfaces de usuario de una forma
sencilla, basada en la definicin de ciertas reglas
mediante ficheros XML, usando el framework de
Jakarta commons-validator.
Internacionalizacin
Actualmente, es muy comn que las aplicaciones
web deban ofrecer sus contenidos adaptados a
usuarios de distintos pases y con distintos idio-
mas. Lgicamente, esto no puede traducirse en
que tengamos que duplicar los elementos de la
interfaz de usuario (en nuestro caso, pginas
JSP) para cada nuevo idioma que queramos
soportar. Esto dificultara enormemente el man-
tenimiento de las aplicaciones y la solucin debe
pasar por tener una nica pgina JSP que din-
micamente muestre su contenido en el idioma
del usuario que la est visitando.
Resource Bundles en Java
La plataforma Java ya tiene resuelta esta situa-
cin mediante lo que se conoce como Resource
Bundes. Se trata de externalizar todos aquellos
recursos que utilice la aplicacin en distintos
ficheros properties. Cada usuario tiene asocia-
do un Locale que consiste en un identificador
de un idioma en un determinado pas. As por
ejemplo, para identificar el idioma espaol se
usa el identificador es y para referimos a la
localizacin de Espaa, usaremos ES (los iden-
tificadores de cada idioma y cada pas vienen
definidos por los estndares ISO-639 e ISO 3166
respectivamente). El Locale completo sera
es_ES. Java utiliza este identificador (Locale),
para decidir en qu fichero se deben obtener los
recursos solicitados (normalmente textos o im-
genes). El mecanismo de bsqueda es muy sen-
cillo. Imaginemos que un usuario tiene configu-
rado su navegador con el Locale en_US (ingls
de Estados Unidos). Si por ejemplo se requiere
Struts prctico (II)
Struts prctico (II)
En la primera entrega de este curso
sobre Struts vimos una introduccin
a este popular framework de
desarrollo J2EE. En este artculo
veremos aspectos ms avanzados
que nos simplificarn enormemente
el desarrollo de las interfaces de
usuario, sin duda una de las facetas
que ms tiempo consume en el
desarrollo de aplicaciones.
SCAR ARANDA CRESPO (Arquitecto J2EE)
Registro de un usuario utilizando la interfaz en Espaol.
SOLO PROGRAMADORES n 127
un mensaje del Resource Bundle mensa-
jes, en primer lugar se buscara el
fichero mensajes_en_US.properties. Si
este fichero no existiese, se buscara men-
sajes_en.properties, es decir, el fichero
con mensajes en ingls, sin especificar
lugar. Por ltimo, si dicho fichero tampoco
existiese se mostraran los mensajes del
fichero por defecto, mensajes.properties.
Los ficheros properties consisten en
ficheros de texto plano que contienen los
mensajes a mostrar por la aplicacin. Cada
lnea cosiste en un identificador nico de
mensaje seguido del signo = y el conte-
nido del mensaje en el idioma del fichero
en concreto. Esta ltima parte es la que
variar entre los ficheros properties para
los distintos idiomas. En la aplicacin que
acompaa al artculo podemos ver
en el directorio WebContent/WEB-
INF/source/com/sp/spshop/resources que
contamos con dos Resource Bundles:
mensajes y pantallas. Cada uno de ellos
contiene dos ficheros, uno para ingls
(mensajes_en.properties y pantallas_
en.properties) y otro como idioma por
defecto en espaol (mensajes.properties
y pantallas.properties). Se puede observar
como todos los ficheros de cada bundle
contienen los mismos identificadores de
mensaje, aunque con distinta traduccin.
Struts se basa en este mecanismo del que
dispone Java para la internacionalizacin
(abreviado con i18n) y que acabamos de
explicar. Segn el patrn de diseo MVC
Model 2, que sigue Struts, los mensajes
mostrados en la interfaz de usuario
pueden provenir de dos fuentes:
Textos incluidos en el diseo de la inter-
faz de usuario.
Mensajes que se generen tras la ejecu-
cin de una operacin (ya sean de error
o simplemente informativos). Estos
mensajes pueden lanzarse por ejemplo
desde un ActionForm que tiene que
informar que el valor de un determina-
do campo no esta permitido o por
ejemplo, desde un Action que atrap
una excepcin producida al invocar a la
lgica de negocio.
Struts nos ofrece facilidades para que estas
dos tareas resulten ms sencillas.
i18n en JSPs
Lo comn es que la mayor parte de los tex-
tos que se muestran al usuario y deben
internacionalizarse estn en las pginas
JSP. Ya vimos en el artculo anterior que
Struts proporciona una potente librera de
etiquetas para facilitar el desarrollo de JSPs.
La mayor parte de las etiquetas usadas para
representar controles grficos HTML,
soportan tres atributos extras para que sus
contenidos sean mostrados en funcin del
Locale particular de cada usuario. Estos tres
atributos son:
bundl e: Identificador del Resource
Bundle. Dado que la forma de referir-
se a un Resource Bundle en Java es
mediante su localizacion completa
(por ejemplo com.sp.spshop.resour-
ces.pantallas) y puede resultar un
poco tedioso escribir estos identifica-
dores en cada una de las etiquetas,
Struts nos permite asignarles alias
en el fichero struts-config.xml. Para
ello usar la etiqueta XML <message-
resources>. Ejemplo: Para los recur-
sos relacionados con la interfaz de
usuario definiremos el Resource
Bundle:
<message-resources
parameter=com.sp.spshop.resources.
pantallas key=ui>
locale: Su uso no es muy comn e indica
el nombre donde se almacena el objeto
Locale en la session de cada usuario. Si no
se usa, se toma el valor por defecto de
Struts org.apache.struts.Globals.LOCA-
LE_KEY.
key: Indica el identificador del mensaje
al que nos referimos, por ejemplo:
<html:option
key=spshop.lista.mediospago/>
En algunas etiquetas este atributo
variar su nombre.
Por ejemplo, para mostrar una imagen
mediante la etiqueta <html:img> o
<html:image> usaremos srcKey o
pageKey para que la URL de la imagen
se extraiga del fichero properties
correspondiente. Para indicar el texto
alternativo (alt) o descripcin (title)
de los elementos HTML, usaremos
altKey y titleKey. Por ejemplo la pgi-
na catalogo.jsp contiene una imagen
con el texto Categoras que lgica-
mente debe ser distinta en espaol que
en ingls. Para ello pondremos:
<html:img pageKey=
spshop.img.head.categorias
altKey=spshop.img.head.alt.
categorias bundle=ui />
Los textos normales dentro de una
pgina HTML no necesitan estar dentro
de una etiqueta. Para aadir el soporte
i18n, tendremos que sustituirlos por
una etiqueta que indique el identifica-
dor del mensaje y opcionalmente el
bundle donde localizar el mensaje. La
etiqueta <bean:message> se encarga
de esto. Por ejemplo, para poner el titu-
lo de la pgina de nuestra tienda pon-
dremos (head.jsp):
<head>
<title>
<bean:message key=spshop.titulo
bundle=ui/>
</title>
i18n en Actions y ActionForms
Si observamos cualquiera de los Actions de
la aplicacin Sp.Shop, vemos que se sigue el
esquema del listado 1.
El Action crea una instancia de
ActionMessages (objeto que almacena uno
o ms errores). En caso de que se produzca
una excepcin, se aadir un mensaje
mediante la creacin de un objeto
ActionMessage. Para crear una instancia de
ActionMessage, es imprescindible indicar
un identificador de mensaje (no se nos per-
mite indicar un texto hardcoded), por lo
que Struts nos obliga a seguir la buena
33
MIDDLEWARE
Struts prctico (II)
http://digital.revistasprofesionales.com
Registro de un usuario utilizando la
interfaz en Ingls.
SOLO PROGRAMADORES n 127
prctica de tener los mensajes de usuario
externalizados.
Si se produjo algn error, lo siguiente es
guardar el objeto ActionMessages en la
request, mediante el mtodo saveErrors()
y redirigir a una JSP que contenga la etique-
ta <html:errors>. Esta etiqueta muestra
por defecto los mensajes que hayan sido
guardados en la request mediante el
mtodo saveErrors() aunque podramos
mostrar otro objeto ActionErrors que se
hayan almacenado bajo cualquier otro
nombre.
Pero antes de que se pueda llegar a produ-
cir un error en la ejecucin de un Action, es
posible que la validacin del ActionForm no
sea satisfactoria y por tanto se deban incluir
los mensajes de error oportunos para mos-
trrselos al usuario. La firma del mtodo
validate() nos indica que se debe devolver
un objeto ActionErrors. ActionErrors es una
clase que hereda de ActionMessages y la
idea es la misma que ya explicamos ante-
riormente. Cuando los ActionForms detec-
ten algn error debern aadir un nuevo
ActionError al objeto ActionErrors que se
devolver. En caso de devolver null o un
objeto ActionErrors vaco, la validacin se
entender que ha sido correcta. El listado 2
muestra el mtodo validate del ActionForm
DatosLoginForm.
Se puede apreciar cmo cuando no se relle-
na el campo usuario o el campo contrase-
a, se aade un nuevo ActionError con el
identificador del mensaje que queremos
mostrar al usuario. La pgina que poste-
riormente muestre los errores pintar el
mensaje en el idioma correspondiente en
funcin del Locale del usuario.
Gestin del Locale
Una pregunta que habr surgido al lector es,
cmo elige el usuario el Locale con el que
quiere navegar? Cmo podemos hacer que el
usuario pueda modificar este Locale?
Struts almacena en la sesin de cada usuario
el objeto Locale (java.util.Locale) bajo la
clave org.apache.struts.Globals.LOCALE_KEY.
Cada vez que hay que buscar un mensaje con
soporte i18n se consulta este valor y se busca
en el properties correspondiente. Ahora
bien, Quien se encarga de asignar el valor
inicial de esta variable de sesin? Si se pre-
gunta por el Locale y este no tiene valor ini-
cial (normalmente, porque el usuario acaba
de entrar en la aplicacin), entonces Struts
asigna uno por defecto basndose en los
campos de la cabecera HTTP Accept-langua-
ge, es decir, en el lenguaje que haya configu-
rado el usuario en su navegador. Para permi-
tir al usuario el cambio de Locale, basta con
modificar el valor de la variable de sesin
Globals.LOCALE_KEY mediante el mtodo
setLocale() disponible en cualquier Action.
Veamos ahora en la aplicacin Sp.Shop el
Action encargado de cambiar el Locale. Este
Action recibir como parmetro el lenguaje
que se quiere asignar al usuario (vase el
listado 3).
Struts Tiles
Un problema comn a la hora de mantener
un sitio web suele consistir en la dificultad
de aplicar cambios de diseo a todas las
pginas que la componen, pues muchas
veces implica tener que modificar cada una
de estas pginas. La especificacin JSP
incluye mecanismos para poder reutilizar
fragmentos de JSP que se incluyen en
numerosas pginas. Si nos fijamos en la
aplicacin Sp.Shop que acompaa al art-
culo, podemos ver que todas las pginas
siguen un diseo comn, y todas contienen
una cabecera, un men (a la izquierda) y un
pie de pgina con el copyright del sitio web.
Mediante la directiva <%@ include %>
podemos incluir en todas nuestras pginas
una determinada JSP (por ejemplo,
pie.jsp) de modo que si en el futuro tene-
34
MIDDLEWARE
http://digital.revistasprofesionales.com
LISTADO 1 Esquema de los Actions de Sp.Shop
ActionMessages errors = new ActionMessages();
ActionForward forward = new ActionForward();
try {
// invocar lgica de negocio
} catch (Exception e) {
errors.add(error, new ActionMessage(error.id.XXX));
}
if (!errors.isEmpty()) {
saveErrors(request, errors);
forward = mapping.findForward(error);
} else {
forward = mapping.findForward(ok);
}
LISTADO 2 Mtodo validate de DatosLoginAction
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
ActionErrors errors = new ActionErrors();
if ((usuario == null) || (usuario.length() == 0)) {
logger.debug(Falta usuario en peticin de login);
errors.add(usuario, new ActionMessage(error.login.faltaUsuario));
}
if ((contrasena == null) || (contrasena.length() == 0)) {
logger.debug(Falta contrasea en peticion de login);
errors.add(usuario, new ActionMessage(error.login.faltaContrasena));
}
return errors;
}
LISTADO 3 Action CambiarLocale
public class CambiarLocaleAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionForward forward = new ActionForward();
try {
String lenguaje = request.getParameter(lenguaje);
Locale loc = new Locale(lenguaje);
setLocale(request, loc);
} catch (Exception e) {
}
forward = mapping.findForward(ok);
return (forward);
}
}
SOLO PROGRAMADORES n 127
mos que modificar dicho pie (modificar el
texto de copyright, por ejemplo), slo lo
tendramos que hacer en una nica JSP.
Pero eso slo resuelve parte del problema.
Todas las pginas que deban mostrar el pie
de pgina, deben tener cuidado de situarlo
en el mismo lugar de la pgina. Qu ocu-
rre si se toma la decisin de modificar la
ubicacin en la pgina de uno de los ele-
mentos que hemos aadido, mediante la
directiva include? No habra ms remedio
que modificar todas las pginas JSP y cam-
biar el lugar donde se realiza el include.
Para resolver este problema, debemos
introducir un concepto nuevo ya utilizado
en otras tecnologas para el diseo de
interfaces de usuario, el de template o
plantilla y que no existe directamente en la
especificacin JSP de J2EE. La idea consiste
en especificar de manera nica, el diseo o
layout de un conjunto de pginas. Esta
plantilla o layout sera lo nico que hubie-
se que cambiar en caso de querer modificar
el diseo comn de un conjunto de pgi-
nas. Esta plantilla debe maquetar la ubica-
cin de los distintos elementos dinmicos
que irn variando de pgina a pgina. Las
pginas concretas que se mostrarn como
resultado de una operacin se limitarn a
referenciar a una cierta plantilla y asigna-
rn el contenido de las distintas piezas que
usa la plantilla usada (cabecera, men, pie y
contenido).
Aunque ya hemos comentado que J2EE no
dispone de este mecanismo de forma expli-
cita, Struts lo implementa mediante el fra-
mework denominado Struts Tiles. Esta solu-
cin no est limitada a su uso con Struts y
hace tiempo que se generaliz y se puede
usar perfectamente con otros frameworks
MVC.
Esta solucin ha conseguido introducir el
concepto de diseo basado en plantillas en
el desarrollo J2EE y adems otro de sus
logros es que su uso es enormemente sen-
cillo, en parte, porque est basado en libre-
ras de etiquetas personalizadas, concepto
muy usado en el desarrollo con JSPs.
Plantillas con Struts Tiles
Una vez definido el concepto de plantilla
vamos a pasar a contar cmo definirlas median-
te el uso de Struts Tiles. Afortunadamente no
tenemos que aprender un nuevo lenguaje o tec-
nologa para disear las plantillas, ya que estas
se definen en una JSP. Echemos un vistazo al lis-
tado 4 donde hemos diseado la plantilla prin-
cipal que vamos a usar para nuestra aplicacin
de ejemplo Sp.Shop. Si observamos la plantilla
(WebContent/plantillas/plantillaPrincipal.jsp) no
observamos ninguna diferencia con respecto a
otras JSPs. Contiene el cdigo HTML necesario
para posicionar mediante tablas las cuatro par-
tes (o tiles segn la terminologa de Struts) que
ya hemos mencionado anteriormente. Mediante
la etiqueta <tiles:insert> indicamos que el
resultado de la JSP debe insertar la JSP que se
indique bajo las variables cabecera, men,
contenido y pie. Mediante el atributo attribu-
te indicamos la variable que contendr el nom-
bre de la JSP que se procesar y cuyo resultado
se incluir en la pgina. Si opcionalmente usa-
mos ignore=true indicaremos que en caso de
que no se encuentre valor para la variable indi-
cada, no se provocar un error y se seguir el
procesamiento de la JSP sin incluir nada en la
pgina resultante. Si por el contrario usamos la
etiqueta getAsString indicaremos que directa-
mente se incluir el valor de la variable indicada
(sin tomar el valor como el nombre de una JSP).
A continuacin veremos cmo se realiza la asig-
nacin de estas variables en cada una de las
pginas.
Uso de plantillas
Una vez definidas las plantillas, slo nos queda
explicar cmo usarlas. En primer lugar, mediante la
etiqueta <tiles:insert> indicaremos la plantilla
que queremos usar (mediante el atributo page).
A continuacin daremos valor a las distintas varia-
bles que se definen en dicha plantilla. Esto lo hare-
mos mediante la etiqueta <tiles:put>. Veamos la
pgina WebContent/homeRegistroUsuario.jsp
en el listado 5.
Mediante las plantillas, conseguimos el
objetivo de no duplicar el diseo y centrali-
zarlo en un nico punto (la plantilla). Se
35
MIDDLEWARE
Struts prctico (II)
http://digital.revistasprofesionales.com
LISTADO 4 Plantilla para Sp.Shop
<%@ page contentType=text/html;charset=ISO-8859-1 language=java %>
<html>
<%@ taglib uri=/WEB-INF/struts-tiles.tld prefix=tiles %>
<head>
<title><tiles:getAsString name=titulo ignore=true/></title>
<link href=css/forAll.css rel=stylesheet type=text/css>
</head>
<body>
<table align=center width=760 height=100% border=0 cellpadding=0
cellspacing=0 background=images/bg_main.gif>
<tr>
<td height=65>
<tiles:insert attribute=cabecera/>
</td>
</tr>
<tr>
<td valign=top>
<table width=100% border=0 cellspacing=0 cellpadding=0>
<tr valign=top>
<tiles:insert attribute=menu ignore=true/>
<tiles:insert attribute=contenido/>
</tr>
</table>
</td>
</tr>
<tr>
<td height=37 background=images/down_bg.gif>
<tiles:insert attribute=pie/>
</td>
</tr>
</table>
</body>
</html>
Diseo de la plantilla para Sp.Shop.
SOLO PROGRAMADORES n 127
recomienda al lector comparar este nuevo
cdigo con el entregado en el nmero anterior,
donde no se usaba el concepto de plantillas.
Antes de pasar a otro punto, vale la pena acla-
rar que el atributo flush indica si se debe
vaciar el stream de salida (donde se est escri-
biendo la respuesta HTTP) antes de procesar la
etiqueta. Se recomienda usar siempre
flush=true.
Definitions
Ya hemos visto cmo adaptar nuestras pginas
para que usen el template que hemos definido.
Si modificamos el resto de pginas enseguida nos
daremos cuenta de que todas sern muy similares
y que realmente slo cambia el ttulo y el conteni-
do, ya que el resto de tiles siempre es igual. Para
evitar esto Struts Tiles introduce un nuevo con-
cepto, el de definicin (definition). Una definicin
consiste en una instanciacin de una plantilla con
unos valores predefinidos. Es decir, en nuestro
caso nos interesara declarar una definicin que
asignase unos valores por defecto a las variables,
cabecera, men y pie. Tambin opcionalmente
podramos asignar un titulo por defecto para que
todas las pginas mostrasen el mismo.
Struts permite que las definiciones se declaren de
dos maneras, mediante JSPs (usando la etiqueta
<tiles:definition>) o mediante ficheros XML.
Vamos a ver cmo se hara usando esta ltima
forma.
Para poder declarar definiciones mediante XML,
necesitamos incluir un plug-in dentro del fiche-
ro de configuracin de Struts (struts-
config.xml) segn se indica a continuacin:
<plug-in
className=org.apache.struts.tiles.
TilesPlugin>
<set-property property=definitions-
config value=/WEB-INF/tiles-
defs.xml />
<set-property property=definitions-
parser-validate value=true />
</plug-in>
La primera propiedad (definitions-config)
indica el nombre del fichero donde se buscarn
las definiciones declaradas. En el listado 6
podemos ver la forma de declarar una defini-
cin (fichero WebContent/WEB-INF/tiles-
defs.xml).
Cualquier pgina que use esta definicin, esta-
r usando la plantilla plantillaPrincipal.jsp y
no tendr que asignar valores para las variables
titulo, cabecera, menu y pie. A pesar de
usar una definicin, la pgina puede perfecta-
mente sobrescribir alguno de los valores asig-
nados. Veamos por ejemplo el contenido de la
JSP WebContent/homeVerCesta.jsp que refe-
rencia a la definicin que acabamos de
declarar:
<tiles:insert
definition=spshop.default
flush=true>
<tiles:put name=titulo value=Cesta
de la compra/>
<tiles:put name=contenido
value=/verCesta.jsp />
</tiles:insert>
En el caso anterior, el valor asignado a la
variable titulo, sobrescribe al ttulo por
defecto declarado en la definicin.
Otra ventaja que nos ofrecen las definicio-
nes es que permiten herencia. Es decir, una
definicin puede extender otra y as dis-
pondremos de las ventajas que ya conoce-
mos del concepto de herencia. Imaginemos
que queremos usar otra definicin muy
parecida a la que acabamos de ver y quere-
mos que la nueva pgina tenga un men
diferente (menu2.jsp). Para ello indicare-
mos que la nueva definicin herede de la
definicin spshop.default y sobrescribire-
mos el valor del tile pie:
<definition name=spshop.menu.alt
extends=spshop.default>
<put name=menu value=/arbol2.jsp
/>
</definition>
Internacionalizacin
Otra ventaja que nos ofrece el uso de defi-
niciones es el poder usar distintas defini-
ciones en funcin del Locale de usuario de
la aplicacin. Para modificar las dos defini-
ciones que hemos visto para usuarios con
el idioma ingls, bastar con crear un fiche-
ro con el nombre WEB-INF/tiles-
def_en.xml (aadir el sufijo del Locale
deseado, igual a como se nombran los
ficheros properties para los ficheros de
mensajes internacionalizados). El lector
puede consultar este nuevo fichero donde
hemos hecho que el titulo por defecto est
en ingls y se utilicen las pginas
arbol2.jsp para el men y pie2.jsp para el
pie de pgina.
Commons-validator
Una de las tareas ms tediosas dentro del
desarrollo de aplicaciones suele ser el tener
que realizar las validaciones de los distintos
campos de la interfaz de usuario. Si adems
se trata de una aplicacin web, el trabajo es
doble, ya que las buenas prcticas nos dicen
que la validacin tiene que ser tanto en el
lado cliente mediante Javascript como en el
lado servidor mediante Java (ActionForms si
usamos Struts). Esto sin duda supone un
problema pues de nuevo nos encontramos
en la situacin no deseable de tener cdigo
duplicado y en distintos lenguajes, lo
que dificulta el mantenimiento de las
aplicaciones.
El proyecto commons-validator de Jakarta
trata de resolver este tipo de problemas.
Validator es un framework genrico que per-
mite crear validadores de datos a partir de una
definicin en XML. Usado con frameworks
como Struts, esto se traduce en que mediante
la declaracin en XML de los datos de un for-
36
MIDDLEWARE
http://digital.revistasprofesionales.com
LISTADO 6 Definicin en el documento tiles-defs.xml
<tiles-definitions>
<definition name=spshop.default path=/plantillas/plantillaPrincipal.jsp>
<put name=titulo value=Sp.Shop - La tienda de msica en internet />
<put name=cabecera value=/head.jsp />
<put name=menu value=/arbol.jsp />
<put name=pie value=/pie.jsp />
</definition>
</tiles-definitions>
LISTADO 5 Contenido del fichero homeRegistroUsuario.jsp
<%@ taglib uri=/WEB-INF/struts-tiles.tld prefix=tiles %>
<tiles:insert page=/plantillas/plantillaPrincipal.jsp flush=true>
<tiles:put name=titulo value=Registro de Usuario />
<tiles:put name=cabecera value=/head.jsp />
<tiles:put name=menu value=/arbol.jsp />
<tiles:put name=contenido value=/registroUsuario.jsp />
<tiles:put name=pie value=/pie.jsp />
</tiles:insert>
SOLO PROGRAMADORES n 127
mulario, Validator se encargar automtica-
mente de la validacin de nuestros
ActionForms (es decir, no tendremos que
codificar el mtodo validate()) y adems, si lo
deseamos, puede incluir automticamente el
cdigo Javascript necesario para validar los
datos antes de ser enviados al servidor. A con-
tinuacin vamos a ver cmo utilizar com-
mons-validator para validar los formularios de
registro de usuario y de solicitud de pedido en
nuestra aplicacin Sp.Shop.
Usando commons-validator
Como ya hemos contado, mediante el uso de
commons-validator no ser necesario progra-
mar el mtodo validate() en las clases
ActionForms donde hasta ahora tenamos que
codificar la validacin de cada uno de los cam-
pos cuando el formulario era enviado al servi-
dor. Pero para que esto sea as, debemos hacer
que nuestro ActionForm herede de la clase
org.apache.struts.validator.ValidatorForm en
lugar de org.apache.struts.action.ActionForm
como hasta ahora. La clase ValidatorForm ya
contiene un mtodo validate() que se encar-
gar de realizar la validacin conforme a la vali-
dacin que hayamos declarado en los ficheros
de configuracin. El lector puede ver el cdigo
final de los nuevos ActionForms en las clases
DatosRegistroForm y DatosPedidoForm.
A continuacin pasaremos a declarar cada uno
de los formularios que queremos validar
mediante commons-validator. Para ello creare-
mos el fichero WEB-INF/validations.xml (con-
sultar dicho fichero en el material complemen-
tario de este artculo). Este fichero define dos
formularios (datosRegistro y datosPedido)
dentro de la etiqueta <formset>. Cada for-
mulario contiene una etiqueta field por cada
uno de los campos del mismo que queremos
validar. El formato genrico para la definicin
de cada campo es el siguiente:
<field property=nombreDelCampo
depends=validacion1,,validacionN>
<arg0 key=key.mensaje.campo1 />

<argN key=key.mensaje.campoN />


<var>
<var-name>nombreVariable1</var-name>
<var-value>valorVariable1</var-value>
</var>

<var>
<var-name>nombreVariableN</var-name>
<var-value>valorVariableN</var-value>
</var>
</field>
Podemos observar como cada etiqueta
field tiene dos atributos obligatorios:
property, donde indicaremos el nombre
del campo al que queremos aplicar la vali-
dacin (debe corresponderse con el nombre
del campo en el ActionForm) y depends,
donde se indicar la lista de reglas que debe
cumplir el valor del campo. Struts imple-
menta una serie de reglas bsicas que
hemos listado en el cuadro Reglas de vali-
dacin incluidas en Struts (aunque como
veremos ms adelante, commons-validator
permite definir nuestras propias reglas).
Cada regla muestra un mensaje localizado
que lgicamente queremos personalizar
para cada campo y que muestre por ejem-
plo el campo que no cumple la validacin.
Para esto se utilizan las etiquetas
<arg0><argN>. Por ejemplo, las reglas
Intrange y Floatrange muestran el men-
saje:
errors.range=El campo {0} debe estar
entre {1} y {2}
A la hora de componer el mensaje, Struts
sustituir las cadenas {0},{1} y {2}
por lo que hayamos indicado en las etique-
tas <arg0>, <arg1> y <arg2>. Por
ejemplo, la siguiente validacin provocar
el mensaje El campo Cantidad debe estar
entre 1 y 5:
38
MIDDLEWARE
http://digital.revistasprofesionales.com
Reglas de validacin incluidas en Struts
Regla Descripcin
Required El campo es obligatorio y debe contener valor.
minlength
El campo debe tener un valor con una longitud
mnima de caracteres.
maxlength
El campo debe tener un valor con una longitud
mxima de caracteres.
Mask
El valor del campo debe cumplir con una cierta
expresin regular.
Byte
El valor del campo debe ser vlido para un tipo de dato
Byte.
Short
El valor del campo debe ser vlido para un tipo de dato
Short.
Integer
El valor del campo debe ser vlido para un tipo de dato
Integer.
Long
El valor del campo debe ser vlido para un tipo de
dato Long.
Float
El valor del campo debe ser vlido para un tipo de
dato Float.
Double
El valor del campo debe ser vlido para un tipo de dato
Double.
Date
El valor del campo debe ser vlido para un tipo de
datos Date, segn el patrn de fecha indicado.
intRange
El valor del entero indicado debe encontrarse en el
rango de valores especificados.
floatRange
El valor del float indicado debe encontrarse en el
rango de valores especificados.
creditCard
El valor del campo debe ser un nmero de tarjeta de
crdito vlido.
Email
El valor del campo debe ser una direccin de correo
electrnico vlida (sintcticamente).
validwhen
El valor ser vlido cuando se evale a true la
expresin indicada.
SOLO PROGRAMADORES n 127
<field property=cantidad
depends=required,intRange>
<arg0
key=error.ejemplo.campoCantidad />
<arg1 key=1 resource=false/>
<arg2 key=5 resource=false/>

</field>
Notar como el valor a sustituir se puede
indicar directamente (resource=false) o
localizado (resource=true o sin atributo
resource)
La etiqueta <var> nos permite pasar
parmetros a los validadores. Imagina-
mos por ejemplo que queremos que el
valor de un campo slo contenga valores
alfabticos, como por ejemplo el campo
nombre del formulario de registro. Para
ello tendremos que indicar mediante una
variable la expresin regular que debe
cumplir el valor del campo:
<field property=nombre
depends=required,mask>
<arg0
key=error.registro.faltaNombre />
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z]*$</var-value>
</var>
</field>
Notar en este caso que el atributo mask
debe indicar una expresin regular siguien-
do la sintaxis de Perl5.
Configurar Validator con Struts
Para usar commons-validator junto con
Struts, debemos seguir los siguientes
pasos:
Incluir los ficheros commons-validator-
1.1.4.jar y jakarta-oro.jar en el direc-
torio WEB-INF/Lib.
Aadir el fichero XML con la definicin
de las reglas de validacin utilizadas
(WEB-INF/validator-rules.xml).
El fichero que el lector encontrar en el
material complementario de este art-
culo, contiene la configuracin
de las reglas de validacin bsicas
implementadas por Struts y comenta-
das anteriormente. Ms adelante,
veremos el formato de este fichero
para incluir nuestro propio
validador.
Aadir el plugin de commons-valida-
tor en el fichero de configuracin de
Struts (struts-config.xml). Para ello
hay que aadir el siguiente cdigo:
<plug-in
className=org.apache.struts.
validator.ValidatorPlugIn>
<set-property property=pathnames
value=/WEB-INF/validator
rules.xml,/WEB
-INF/validations.xml/>
</plug-in>
Habilitar validaciones Javascript
Ya slo nos queda hacer que validator
genere automticamente el cdigo
Javascript necesario para validar los cam-
pos en el navegador basndose en las
validaciones definidas en el fichero vali-
dations.xml.
En primer lugar debemos incluir la etique-
ta <html:javascript> en la pgina JSP
donde se incluye el formulario. A esta eti-
queta le aadiremos el atributo
formName donde indicaremos el nom-
bre del formulario segn esta definido en
el fichero struts-config.xml. En las
pginas registroUsuario.jsp y modi-
ficacionRegistro.jsp (que usan el mismo
ActionsForm datosRegistro) hemos
aadido la etiqueta de la siguiente
manera:
<html:javascript
formName=datosRegistro />
Esta etiqueta aadir una serie de funcio-
nes Javascript para realizar las validacio-
nes. Pero a nosotros nos interesa slo
una, que ser la que se encargue
de validar el formulario completo y
que se llamar validateDatosRegistro
(validate seguido del nombre del form
indicado en el atributo formName). Esta
funcin recibir un nico argumento
que ser el objeto formulario y tendremos
que invocarla antes de enviar el
formulario. En el caso de las pginas de
registro de usuario, modificaremos el
cdigo del botn aceptar por el
siguiente:
<html:img srcKey=spshop.img.aceptar
bundle=ui border=0 onclick=if
(validateDatosRegistro(
document.forms[0])) {
document.forms[0].submit()} />
39
MIDDLEWARE
Struts prctico (II)
http://digital.revistasprofesionales.com
IE nos informa sobre qu campos son obligatorios.
SOLO PROGRAMADORES n 127
Crear nuestro propio Validador
A continuacin vamos a ver lo sencillo que
resulta aadir un nuevo validador a com-
mons-validator. El nuevo validador se
encargar de comparar el valor del campo
al que se aplica, con algn otro campo del
formulario (que se informar mediante la
variable segundoCampo). En el caso de la
pgina de registro de usuario, se compro-
bar que la contrasea y la confirmacin
son iguales.
En primer lugar crearemos un mtodo est-
tico llamado compara en la clase
SpShopValidator, tal como muestra el lis-
tado 7.
Como se puede apreciar, resulta muy senci-
llo y el cdigo es bastante claro. Las clases
ValidatorUtils y GenericValidator nos
ayudan a extraer los valores introducidos
por el usuario, as como los valores con los
que se defini la validacin en el XML vali-
dations.xml.
El siguiente paso es dar de alta la nueva
regla de validacin en el fichero validator-
rules.xml:
<validator name=compara
classname=com.sp.spshop.commons.vali
dator.SpShopValidator
method=compara
methodParams=java.lang.Object,
org.apache.commons.validator.Validator
Action, org.apache.commons.
validator.Field,
org.apache.struts.action.
ActionMessages,
javax.servlet.http.HttpServletRequest
depends=
msg=errors.compara>
<javascript>
...
</javascript>
</validator>
Bsicamente se indican el nombre de la regla
(compara), la clase Java donde se implemen-
ta el mtodo, nombre del mtodo y los argu-
mentos que toma de entrada, que normal-
mente siempre son los cinco indicados.
Tambin se indica el texto que se mostrar
cuando no se cumpla la validacin (clave del
mensaje en el fichero properties). Por ltimo
y de forma opcional, se puede indicar el cdi-
go Javascript necesario para que la validacin
se pueda incluir cuando se use la etiqueta
<html:javascript>. En el fichero validator-
rules.xml hemos incluido el cdigo Javascript
necesario para que se pueda realizar la com-
paracin de campos en el navegador.
i18n con Validator
Un ltimo apunte sobre commons-valida-
tor. En muchos casos las reglas de valida-
cin definidas en el fichero
validations.xml pudieran tener que ser
distintas. Imaginemos por ejemplo un caso
en el que se tuviese que introducir una
fecha mediante una caja de texto. En este
caso por ejemplo sera interesante aceptar
que el formato de fecha permitido fuese
distinto en funcin del Locale de usuario. La
etiqueta <formset> nos permite definir
validaciones para un determinado idioma o
Locale mediante los atributos country y
language. El siguiente ejemplo muestra
este caso:
<form-validation>
<formset>
<form name=datosRegistro>
<field property=fecha
depends=required,date>
<arg0 key=error.XXXX />
<var><var-name>datePattern</
var-name><var-value>dd/MM/yyyy</
var-value></var>
</field>
</form>
<formset language=en>
<form name=datosRegistro>
<field property=fecha
depends=required,date>
<arg0 key=error.XXXX />
<var><var-name>datePattern</
var-name><var-value>MM-dd-yyyy</
var-value></var>
</field>
</form>
Ntese que slo es necesario definir aque-
llos campos que difieran de las reglas del
formset por defecto (el que no lleva ni
country ni language).
Instalacin de la aplicacin Sp.Shop
En el material que acompaa a la revista se
encuentra el cdigo fuente completo de la
aplicacin Sp.Shop, as como el instalable de
Tomcat 5.5 para Windows y el motor de base
de datos HSQLDB.
El fichero Leeme.txt contiene las
instrucciones paso a paso del proceso de
instalacin.
Conclusiones
En este segundo artculo sobre Struts
hemos visto cmo mejorar la aplicacin
Sp.Shop sobre la que estbamos trabajan-
do. Hemos visto las facilidades que nos da
Struts para dar soporte multi-idioma a
nuestra aplicacin, hemos visto cmo dise-
ar sitios web basndonos en plantillas
mediante Struts Tiles y por ltimo hemos
visto cmo realizar fcilmente las siempre
tediosas validaciones de datos. En la prxi-
ma entrega concluiremos nuestro curso
sobre Struts explicando ms sobre este fra-
mework para el desarrollo J2EE.
40
MIDDLEWARE
http://digital.revistasprofesionales.com
LISTADO 7 Mtodo del validador compara()
public static boolean compara(Object bean, ValidatorAction va, Field field,
ActionMessages errors, HttpServletRequest request) {
// obtenemos el valor del campo
String value = ValidatorUtils.getValueAsString(bean, field.getProperty());
// leemos la variable que contiene el nombre del segundo campo a comparar
String sProperty2 = field.getVarValue(segundoCampo);
// obtenemos el valor del segundo campo
String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);
// vemos si se asign algn valor al campo
if (!GenericValidator.isBlankOrNull(value)) {
// comparamos los valores
if (!value.equals(value2)) {
// aadimos error
errors.add(field.getKey(), Resources.getActionMessage(request, va,
field));
// retornamos false para indicar que no se cumpli la validacin
return false;
}
// ok, validacin correcta
return true;
}
SOLO PROGRAMADORES n 127 42
REDES
Creacin de aplicaciones
web con ColdFusion MX 7 (II)
Creacin de aplicaciones
web con ColdFusion MX 7 (II)
http://digital.revistasprofesionales.com
Introduccin
En la primera entrega de la serie se introdujeron
las ventajas que proporciona ColdFusion para el
desarrollo web, a lo que hay que aadir una gran
sencillez en el aprendizaje y una gran rapidez en
los tiempos de desarrollo. Se mostr el uso de las
principales etiquetas del lenguaje de programa-
cin de ColdFusion (CFML), adems de ejemplos
de acceso a bases de datos, y de las principales
tareas en programacin web.
En esta segunda entrega se mostrar la utilidad
de las funciones predefinidas que proporciona el
lenguaje, las facilidades para el tratamiento de
XML, XSL y servicios web, las diferentes formas
de capturar los errores en ColdFusion, y varios
ejemplos mostrando la utilizacin de la mayora
de herramientas del lenguaje vistas hasta el
momento.
Las funciones en ColdFusion
ColdFusion, adems de las etiquetas presentadas
en la anterior entrega, proporciona multitud de
funciones predefinidas que hacen ms sencilla la
manipulacin de datos. Existen muchsimas y
muy variadas, y se pueden dividir en distintas
categoras de funciones.
Funciones de manipulacin de cadenas de texto,
que facilitan el parseo, la comparacin y la con-
versin de cadenas de texto. Ejemplos de estas
funciones son: Compare, Find, LCase,
Insert, LTrim, Replace, etc.
Las funciones de fecha y hora permiten tratar
este tipo de datos, hacer comparaciones de
fechas, etc. ColdFusion tiene un objeto fecha/hora
que es una representacin interna de esa fecha,
que no est diseada para ser mostrada sin ms.
Se debern usar las funciones de formato de
fecha/hora para poder mostrar estos datos
correctamente. Ejemplos de este tipo de funcio-
nes son: CreateDate, CreateTime, Date
Compare, DayOfWeek, isDate, Now, Date
Format, etc.
Existen tambin funciones matemticas que per-
miten realizar clculos complejos, como Abs,
Rand, Cos, Log, etc.
Las funciones para el tratamiento de listas y
arrays permiten tratar los elementos de este tipo
de variables.
Con las funciones de sistema, se puede leer y
escribir en ficheros, directorios, y recuperar los
datos del entorno de ejecucin. Ejemplos de este
tipo son: FileExists, DirectoryExists, Get
Locale, etc.
Y en general, hay funciones para solucionar todo
tipo de problemas, como funciones de tratamien-
to XML, de bsqueda en textos, de evaluacin
dinmica, etc.
En definitiva, las funciones predefinidas de
ColdFusion ayudan al desarrollador con las tareas
ms comunes de la manipulacin de datos, dando
lugar a programas ms comprensibles, menos
extensos y que se realizan en menos tiempo.
A continuacin, se van a mostrar sencillos ejem-
plos de algunas de las funciones ms utilizadas y
de mayor inters.
ColdFusion proporciona multitud de
funciones para el tratamiento de
datos, fechas, operaciones
matemticas o informacin del
sistema y sus recursos.
RICARDO DEZ FERREIRA
Sitio web de ColdFusion Developer Center, donde se
pueden encontrar multitud de ejemplos y artculos:
http://www.macromedia.com/devnet/mx/coldfusion/.
SOLO PROGRAMADORES n 127 43
REDES
Creacin de aplicaciones web con ColdFusion MX 7 (II)
http://digital.revistasprofesionales.com
Funciones de cadenas de texto
El tratamiento cmodo de cadenas de texto es
necesario en cualquier lenguaje que se precie.
Esta comodidad hace que lenguajes como Perl
sean muy populares, principalmente por pro-
porcionar la potencia de las expresiones regu-
lares. ColdFusion lo hace con las funciones de
tratamiento de cadenas de caracteres. De ellas,
las fundamentales son:
Find(subcadena, cadena, posicin):
Es una funcin que busca el contenido de
subcadena en cadena, comenzando en
el carcter indicado por posicin. La posi-
cin es un parmetro optativo.
Replace(cadena, subcadena1, sub-
cadena2, mbito): Esta funcin sustitu-
ye en cadena el valor de subcadena1
por subcadena2. El parmetro mbito es
opcional y puede ser one, para slo susti-
tuir una ocurrencia, o all, para sustituir
todas.
Compare(cadena1, cadena2):
Compara la cadena1 con la cadena2,
devolviendo 1 si cadena1 es alfabtica-
mente menor, 0 si son iguales, y 1 si es
alfabticamente mayor.
Lcase(cadena): Devolver la cadena con
letras minsculas. La funcin Ucase(cade-
na) realiza la operacin contraria.
I nsert(subcadena, cadena, posi-
cin): Esta funcin introducir la subca-
dena dentro de la cadena a partir de la
posicin indicada, desplazando los ele-
mentos que estuvieran actualmente en esa
posicin.
Trim(cadena): Elimina todos los espacios
sobrantes al inicio y al final de la cadena.
Esta funcin viene muy bien para cuando
un usuario ha introducido espacios innece-
sarios en los campos de un formulario.
Funciones de fecha
En todos los lenguajes de programacin el tra-
tamiento de las fechas es un tema de vital
importancia, y en algunos de ellos puede llegar
a ser realmente pesado tratar con ellas. En
ColdFusion las funciones de fecha/hora hacen
esta labor muy llevadera. Las principales fun-
ciones de esta categora son:
Now( ): Es una funcin que devuelve la
fecha y hora actuales del sistema.
CreateDateTi me(ao, mes, di a, hora,
mi nuto, segundo) : Crea un nuevo
objeto fecha/hora con los parmetros
que se le pasen.
DateFormat( fecha, mascara) : Sirve
para poder mostrar un objeto fecha de
una manera concreta. La mscara ser
del estilo dd/mm/yyyy o similar.
Da t e C o mp a r e ( f e c h a 1 , f e c h a 2 ,
preci si on) : Esta es la funcin de
comparacin de fechas, que devolver
-1, 0 o 1, dependiendo de si fecha1 es
menor, igual o mayor que fecha2 res-
pectivamente. El dato de precisin es
opcional y permite indicar si se quiere
afinar la comparacin a segundos,
minutos, horas, das, etc.
Con estas pocas funciones, se pueden realizar
la mayora de labores de tratamiento de
fechas. De todas formas, existen multitud de
funciones ms para el tratamiento de
fechas, como DateDiff, DateConvert,
DayOfWeek, DayOfYear, que ayudan con
el resto de labores menos usuales en la
programacin.
Funciones matemticas
Este grupo de funciones sirven para realizar
todo tipo de clculos matemticos, aparte
de las sumas, restas, multiplicaciones y
divisiones, que se realizan mediante opera-
dores y que ya fueron explicadas en la pri-
mera entrega de la serie. A modo de ejem-
plo, se van a mostrar unas cuantas:
Abs( nmero) : Esta funcin devolver
el nmero sin signo.
RandRange( nmero1, nmero2) :
El resultado ser un nmero aleatorio
entre el nmero1 y el nmero2.
Cos( ngul o) : En este caso se conse-
guir el valor del coseno del ngulo
indicado en radianes.
Log( nmero) : Esta funcin devuelve
el logaritmo del nmero indicado.
Funciones de sistema
Como ya se ha indicado, las funciones de siste-
ma de ColdFusion ayudan al tratamiento de
ficheros y directorios, as como a recuperar o
modificar informacin relevante del entorno
de ejecucin del servidor. Algunas de las ms
utilizadas son las siguientes: FileExists,
DirectoryExists y GetLocale:
Fi l eExi sts( path): Devolver verdade-
ro si el fichero indicado en el path
absoluto existe. Hay una funcin simi-
lar para directorios llamada Directo-
ryExists(path).
GetLocal e( ): El resultado ser el valor
del lenguaje y zona geogrfica del
entorno de ejecucin.
GetEncodi ng( mbi to): Esta funcin
devuelve el tipo de codificacin utiliza-
da en el formulario o la URL (UTF-8,
ISO-8859-1, etc). El valor de mbito
puede ser FORM o URL.
s e t E nc odi ng( mb i t o, c odi f i c a-
ci n): En este caso cambiar el tipo de
codificacin en el mbito elegido
(FORM o URL). El valor de codificacin
puede ser UTF-8, US-ASCII, etc.
Otras funciones interesantes
Hay muchas ms funciones en ColdFusion
que no pertenecen a ninguno de los tipos
anteriores, pero que tambin son intere-
santes por lo que aportan al desarrollador.
LISTADO 1 Practicando con las funciones de fecha
<cfset hoy = Now()>
<cfset cumple = CreateDateTime(2005, 10, 11, 0, 0, 0)>
<html>
<body>
Ejemplo de funciones de fecha<br><br>
<cfoutput>
<ul>
<li>La fecha de hoy es: #hoy#
<li>Usando DateFormat sin mascara: #DateFormat(hoy)#
<li>Usando DateFormat con mascara: #DateFormat(hoy, dd-mm-yyyy)#
<cfif DateCompare(hoy, cumple, d) eq 0>
Hoy es mi cumpleaos.
</cfif>
</ul>
</cfoutput>
</body>
</html>
En la ayuda que se instala junto con la
aplicacin, se pueden ver ejemplos de
todas las funciones predefinidas.
SOLO PROGRAMADORES n 127
Encr ypt ( cadena, cl ave): Esta fun-
cin devuelve la cadena de texto
encriptada utilizando la clave que se
proporciona. Se realiza con un algorit-
mo simtrico por clave. La funcin
Decrypt(cadena,clave) desencripta la
cadena de texto anteriormente encrip-
tada. A continuacin se muestra un
breve ejemplo de su uso:
<cfset cadena = Mi perro se llama
copi>
<cfset clave = mipassword>
<cfset txt_encriptado = encrypt
(cadena, clave)>
<cfset txt_desencriptado =
decrypt(txt_encriptado, clave)>
U r l E n c o d e d F o r ma t ( c a d e n a ) :
Convierte una cadena de texto en otra
que se pueda usar para generar una
URL. Sustituye los espacios en blanco
por %20, y los acentos por su cdigo
respectivo. Sirve para poder enviar
cualquier parmetro que contenga este
tipo de caracteres en una llamada GET.
La funcin UrlDecode(cadena) realiza
la operacin contraria.
Ar r ayToLi st ( ar r ay) : Convierte un
array unidimensional en una lista de
valores. Evidentemente, la funcin
ListToArray(lista) hace la operacin
inversa.
Li s t Sor t ( l i s t a, t i po_or den, s ent i-
do_orden, del i mi tador): Esta fun-
cin ordena todos los elementos de una
lista. Para ello recibe como parmetros
la lista a ordenar, el tipo de orden, que
puede ser numeric, text o textnoca-
se, que seran orden numrico, alfab-
tico, o alfabtico sin tener en cuenta
maysculas y minsculas. Tambin se
debe introducir el sentido del orden,
que puede ser asc o desc, y final-
mente el delimitador de la lista, que
es opcional e indica cul es el carcter
de separacin entre los elementos
(coma por defecto).
Tratamiento de XML con ColdFusion
Hoy en da, con el auge de los servicios web,
el formato XML ha pasado a utilizarse de
forma masiva en todo tipo de aplicaciones
como herramienta para representar infor-
macin.
Como se ha adelantado en la introduccin,
ColdFusion tambin incluye ciertas funcio-
nalidades para facilitar el tratamiento de
XML permitiendo, en muy pocas lneas,
hacer cosas que suponen bastante trabajo
en otros lenguajes, como el parseo de
documentos, o la transformacin de XML
con XSLT, as como la utilizacin de servi-
cios web.
Todo esto se hace mediante una etiqueta y
varias funciones predefinidas. Las funda-
mentales son las siguientes:
<cfxml vari abl e=nombre_obj e-
to>: Esta etiqueta crea un nuevo objeto
documento de ColdFusion. Todo lo que
haya entre la apertura de la etiqueta
(<cfxml>) y el cierre de la misma
(</cfxml>), se convertir en el objeto
documento. En el siguiente ejemplo se
puede ver cmo funciona esta etiqueta:
<cfxml variable="documento">
<familia>
<marido>Pepe</marido>
<mujer>Luisa</mujer>
<cfloop index = "i" from = "1" to
= "3">
<hijo>
Hijo numero
<cfoutput>#i#</cfoutput>
</hijo>
</cfloop>
</familia>
</cfxml>
Como se puede observar en el ejemplo, se
pueden introducir otras etiquetas como
<cfloop>, dentro de la etiqueta
<cfxml>, para poder introducir lgica en
la creacin del documento XML.
Xml Parse( cadenaXML): Esta funcin
parsea el valor de la cadena de texto,
que contiene el XML, devolviendo un
objeto documento. En el siguiente
ejemplo, suponiendo que tenemos el
mismo XML del ejemplo anterior en un
fichero llamado familia.xml, se puede
leer el fichero y convertirlo en un objeto
documento:
<cffile action=read file=
C:\familia.xml variable=familia>
<cfset documento=XmlParse(familia)>
Lo mismo podra hacerse con la respuesta
de una llamada HTTP a un servicio web,
utilizando la etiqueta <cfhttp>.
Xml Tr ansf or m( XML, XSLT): Esta
funcin le aplica una hoja de estilo XSLT
al XML, realizando la transformacin, y
devolviendo el resultado en una cadena
de texto. El parmetro XML puede ser
una cadena que contenga el XML o un
objeto documento. El parmetro
XSLT slo puede ser una cadena de
texto. A continuacin, se muestra un
ejemplo de una transformacin, supo-
niendo que tenemos una hoja de estilo
XSLT escrita para el XML anterior:
<cffile action=read file=
C:\familia.xml variable=familia>
<cffile action=read file=
C:\familia.xsl variable=hoja_estilo>
<cfset resultado = XmlTransform
(familia, hoja_estilo)>
<cfoutput>#resultado#</cfoutput>
Xml Sear c h( obj et o_doc ument o,
expresi on_xpath): Esta funcin per-
mite hacer bsquedas dentro del objeto
44
REDES
http://digital.revistasprofesionales.com
Arquitectura general de la implementacin de servicios web con ColdFusion.
SOLO PROGRAMADORES n 127
documento al estilo de XPath, que
trata el XML como si fueran directorios.
Devolver un array con todos los ele-
mentos del documento que se encuen-
tren. En el siguiente ejemplo, se mues-
tra cmo se buscaran todos los ele-
mentos hijo de un XML como los
anteriores:
<cffile action=read file=
c:\familia.xml variable=familia>
<cfset documento=XmlParse(familia)>
<cfset hijos = XmlSearch(documento,
/familia/hijo)>
<cfloop from=1
to=#ArrayLen(hijos)# index=i>
<cfoutput>#hijos[i].xmlText#
</cfoutput></cfloop>
T o S t r i ng ( o b j e t o _d o c ume nt o ) :
Como indica su nombre, esta funcin
permite convertir un objeto documen-
to en la cadena de texto con el XML.
Como se puede comprobar en los ejemplos
anteriores, con estas etiquetas o funciones
se pueden realizar, rpida y limpiamente,
operaciones que en otros lenguajes supo-
nen la utilizacin de complicados parsers y
muchas lneas de cdigo. Por lo tanto, uti-
lizando ColdFusion el programador se abs-
trae de todos los detalles de la implementa-
cin.
Adems de todas estas funciones, tambin
se proporcionan herramientas para crear
servicios web. En el administrador de
ColdFusion existe un apartado para la
publicacin de servicios web, donde se
publican los ficheros WSDL para que se
pueda acceder al servicio web en el servi-
dor.
Tratamiento de errores
Los errores en ColdFusion pueden capturar-
se y tratarse de una manera que recuerda
mucho a Java. Existen varias etiquetas cre-
adas para esta labor, y las ms importantes
son <cftry> y <cfcatch>, pero existen
algunas ms. A continuacin se detalla el
uso de estas dos etiquetas:
<cftry>
<!-A continuacin el cdigo a
controlar->
<cfif
<!-Final del cdigo a controlar->
<cfcatch type = Any>
Se ha producido un error:<br>
<cfoutput>#cfcatch.message#<br><br>
Error de tipo #cfcatch.type#
</cfoutput>
</cfcatch>
</cftry>
En el ejemplo se puede observar que la etique-
ta <cfcatch> va siempre dentro de <cftry>,
y que tiene una propiedad llamada type, que
en este ejemplo tiene como valor Any. Esta
propiedad sirve para indicar el tipo de error que
se quiere capturar, y en este caso, sera de cual-
quier tipo. Hay muchos otros posibles valores
de esta propiedad como por ejemplo
Database para errores de base de datos,
Application para errores de aplicacin o
Security para errores de seguridad. Tambin
puede observarse que se devuelven dos varia-
bles conteniendo: el mensaje de error y el tipo
del error.
En principio se pueden poner todas las etique-
tas <cfcatch> que se deseen dentro de un
nico <cftry>.
Existe otra etiqueta llamada <cferror>, que
permite mostrar una pgina comn cuando se
produzca un error. En el siguiente ejemplo se
muestra cmo introducir la etiqueta indicando
en sus propiedades que redirija a la pgina
error.cfm, que ser la que muestre el error:
<cferror type = request template =
error.cfm mailTo =
admin@prueba.com>
45
REDES
Creacin de aplicaciones web con ColdFusion MX 7 (II)
http://digital.revistasprofesionales.com
En el administrador de ColdFusion hay
una seccin donde se pueden publicar los
servicios web.
LISTADO 2
Contenido de la
pgina error.cfm
<html>
<body>
Se ha producido un error:<br>
#error.diagnostics#<br><br>
Error producido a las #error.dateTime#<br>
IP: #error.remoteAddress#
Navegador: #error.browser#
</body>
</html>
LISTADO 3 Mostrando los datos de los empleados
<cftry>
<cfquery name=empleados datasource=cfdocexamples>
SELECT FirstName, LastName, EMail, Phone
FROM Employees
ORDER BY FirstName
</cfquery>
<cfcatch type = Database>
Se ha producido un error en la consulta a la base de datos.
</cfcatch>
</cftry>
<cfif empleados.recordcount gt 0>
<cfset hoy=Now()>
<cfxml variable=documento>
<plantilla>
<fecha>#DateFormat(hoy, dd-mm-yyyy)#</fecha>
<num_empleados>#empleados.recordcount#</num_empleados>
<cfoutput query=empleados>
<empleado>
<nombre>#FirstName#</nombre>
<apellido>#LastName#</apellido>
<email>#email#</email>
<telefono>#Phone#</telefono>
</empleado>
</cfoutput>
</plantilla>
</cfxml>
<cfif FileExists(c:\empleados.xsl)>
<cffile action=read variable=xsl file=c:\empleados.xsl>
<cfset transformacion = XMLTransform(documento, xsl)>
<cfoutput>
#transformacion#
</cfoutput>
<cfelse>
<cfoutput>
#ToString(documento)#
</cfoutput>
</cfif>
</cfif>
SOLO PROGRAMADORES n 127
A continuacin, en el listado 2, se muestra
el cdigo que puede tener la pgina
error.cfm.
Como se puede ver en dicho listado, la
pgina error.cfm, que es la que muestra el
error, recibe una serie de variables con
datos genricos del error como el mensaje,
la fecha, el navegador del usuario, etc.
De todas formas, esta ltima opcin es
menos aconsejable que la de <cftry> y
<cfcatch>, que proporciona un manejo
ms flexible de los errores.
Una aplicacin sencilla
A continuacin se va a realizar una aplicacin
sencilla para ilustrar algunos de los conceptos
explicados a lo largo de esta entrega, como el
control de errores, el tratamiento de XML y el
uso de funciones predefinidas de ColdFusion.
Tambin se utilizarn algunas de las etiquetas
explicadas en la primera entrega, como las de
control de flujo como <cfif> o de salida de
datos como <cfoutput>.
En la primera entrega ya se utiliz una base de
datos Access que proporciona ColdFusion en
la instalacin para sus ejemplos, y que se llama
cfdocexamples. En este caso, la volveremos a
utilizar.
Nuestra aplicacin de ejemplo hace una con-
sulta de los datos de los empleados de una
compaa en la tabla Employees, sacando su
nombre, apellido, email y telfono y genera un
documento XML con ello. A continuacin,
mediante una hoja de estilo XSLT, realiza la
transformacin mostrndola finalmente al
usuario. El listado 3 muestra la pgina .cfm
que realiza todas estas operaciones.
Como se observa en el cdigo del listado, se
realiza un control de los errores de tipo
Database, lo que nos permitir mostrar un
mensaje explicando el error en caso de que
falle la consulta a la base de datos.
En el cdigo anterior se comprueba la existen-
cia y posteriormente se abre un fichero de
hoja de estilo XSLT llamado empleados.xsl.
Este fichero puede tener un formato como el
que luce el listado 4.
A la vista del ejemplo, se observa que el uso de
las etiquetas es muy intuitivo, y que una apli-
cacin como esta, en cualquier otro lenguaje,
hubiera sido bastante ms extensa, principal-
mente en la transformacin del fichero XML
con la hoja de estilo, que en ColdFusion es
muy clara y sencilla.
Adems, como ya se coment en la primera
entrega, la etiqueta <cfquery> permite abs-
traerse totalmente de la implementacin del
acceso a la base de datos.
Conclusiones
En esta segunda entrega se ha profundizado un
poco ms en las herramientas que ColdFusion
pone en manos del programador, para que
pueda programar ms rpido y de forma ms
sencilla.
Una ayuda fundamental son las funciones pre-
definidas, de las cuales se han mostrado las
principales de cada tipo, y se ha podido observar
la potencia de algunas de ellas. Los ejemplos han
ilustrado la sencillez del uso de estas funciones.
El tratamiento de documentos XML es muy
potente en este lenguaje, permitiendo realizar
operaciones complejas con etiquetas y funcio-
nes predefinidas. La utilizacin de servicios web
(SOAP, WDSL, etc) tambin es sencilla de des-
arrollar en ColdFusion, pero queda fuera del
objeto de este artculo.
Finalmente, se han visto las diferentes formas en
que se pueden tratar los errores en este lengua-
je de una manera sencilla y que permite generar
los mensajes de salida adecuados dependiendo
del tipo de error que se haya producido.
En la siguiente entrega se explicarn los con-
ceptos ms avanzados de Coldfusion, como la
creacin de etiquetas o funciones propias, la
compatibilidad con otros lenguajes de progra-
macin, como por ejemplo Java, y los principa-
les temas relativos a la administracin del ser-
vidor de ColdFusion, para intentar maximizar
su rendimiento, sacndole todo el partido
posible.
46
REDES
http://digital.revistasprofesionales.com
Esta figura muestra el resultado de
ejecutar nuestro pequeo ejemplo.
LISTADO 4 Contenido del fichero empleados.xsl
<?xml version=1.0?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version=1.0
xmlns=http://www.w3.org/TR/REC-html40 xmlns:xlink=http://www.w3.org/1999/xlink>
<xsl:template match=/>
<html>
<head>
<title>Empleados</title>
</head>
<body>
Informe de plantilla a <xsl:value-of select=/plantilla/fecha/><br/>
Numero de empleados: <xsl:value-of select=/plantilla/num_empleados/>
<table border=1 width=350>
<tr>
<td>Nombre</td>
<td>Apellido</td>
<td>Email</td>
<td>Telefono</td>
</tr>
<xsl:for-each select=/plantilla/empleado>
<tr>
<td align=center><xsl:value-of select=nombre/></td>
<td align=center><xsl:value-of select=apellido/></td>
<td align=center><xsl:value-of select=email/></td>
<td align=center><xsl:value-of select=telefono/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
SOLO PROGRAMADORES n 127 48
DISEO
http://digital.revistasprofesionales.com
Introduccin
Model Driven Architecture
Como muchos lectores sabrn, OMG (Object
Management Group, http://www.omg.org) es
una organizacin internacional sin nimo de
lucro que engloba a prcticamente todas las
grandes empresas de desarrollo de software, y a
cientos de pequeas empresas. Su objetivo es el
desarrollo de especificaciones estndar para
mejorar la interoperabilidad entre sistemas; una
de las ms conocidas actualmente es MDA
(Model Driven Architecture, http://www.omg.
org/mda/). MDA engloba una serie de especifica-
ciones de modelado como son MOF (Meta Object
Facility), UML (Unified Modeling Language), XMI
(XML Metadata Interchange) y CWM (Common
Warehouse Model).
La arquitectura MDA permite definir, en base a
los estndares citados anteriormente, modelos
de negocio independientes de la plataforma,
separando as la lgica de negocio de la tecnolo-
ga en la que se soporta. Por lo tanto, una vez
construido el modelo de nuestro software, debe-
ra ser posible generar el cdigo para cualquier
plataforma conocida, como por ejemplo Java o
.NET.
Eclipse Modeling Framework
Por su parte, EMF (Eclipse Modeling Framework,
http://www.eclipse.org/emf/) es un framework
Open Source para la construccin automtica de
cdigo a partir de modelos. EMF es, por lo tanto,
una implementacin de MDA para la plataforma
Java que permite trabajar con la mayora de las
especificaciones englobadas dentro de MDA.
EMF Proporciona su propio metamodelo (ecore)
para describir los modelos de datos UML de las
aplicaciones. Dispone de un serializador XMI
como mecanismo de persistencia de los modelos,
herramientas para transformar modelos repre-
sentados en UML, XML o interfaces Java en
metamodelos ecore as como herramientas de
generacin de cdigo a partir del modelo ecore.
Por tanto, EMF y MDA comparten el mismo prin-
cipio fundamental, que es el de generar imple-
mentaciones ejecutables a partir de modelos
lgicos.
EMF incorpora muchos de los conceptos y estn-
dares de MDA, como es el uso de un modelo en
UML como entrada para el desarrollo automti-
co de cdigo, el uso de XMI como formato inter-
medio para los datos de modelos y metamodelos,
y una implementacin de su modelo de objetos
basada en el un subconjunto del estndar MOF,
denominado EMOF (Essential MOF).
La finalidad de EMF, como la de cualquier otra
implementacin de la arquitectura MDA, es la de
automatizar ciertas tareas asociadas al desarro-
llo de aplicaciones acortando por tanto los tiem-
pos dedicados a dicha fase del ciclo de vida de
las aplicaciones. Asimismo, como ya se ha men-
cionado con anterioridad, es posible obtener
diferentes implementaciones de un mismo
modelo de negocio para tantas plataformas tec-
nolgicas como se desee.
En este artculo, el lector va a descubrir cmo,
partiendo de un modelo en UML consistente en
un conjunto de clases de negocio relacionadas,
EMF genera un modelo de objetos que lo imple-
mentan. EMF se encarga adems de gestionar la
persistencia de los objetos del modelo en docu-
mentos XML. Una vez que EMF ha generado una
implementacin Java del modelo, el equipo de
desarrollo puede centrarse en implementar la
lgica propia del negocio.
El motor de generacin de cdigo de EMF, JET,
puede producir cualquier tipo de contenido en
modo texto. En la actualidad se usa para generar
cdigo Java, ficheros XML o ficheros de propie-
dades, pero es posible realizar modificaciones
sobre las plantillas usadas por JET para generar
cdigo para otros lenguajes de programacin.
Generacin de cdigo con EMF
En el presente artculo haremos una introduc-
cin a EMF mediante un ejemplo prctico, vere-
mos cmo instalarlo y las posibilidades que tiene
EMF es un plug-in Open Source de
Eclipse que permite la generacin
automtica de cdigo Java a partir
de un modelo (UML, XMI,
XSD...). Adems genera el cdigo
necesario para crear editores
integrados en la plataforma
Eclipse.
OSCAR COMBARROS, IRENE JIMNEZ
Generacin de cdigo a
partir de modelos con EMF
Generacin de cdigo a
partir de modelos con EMF
SOLO PROGRAMADORES n 127 49
DISEO
http://digital.revistasprofesionales.com
para el desarrollo automtico de cdigo a
partir de un modelo.
Eclipse no es slo un entorno de progra-
macin, sino que est diseado como una
plataforma de desarrollo que permite ges-
tionar recursos y manejar programas Java,
y que puede ampliarse mediante unidades
de ejecucin denominadas plug-ins.
En la actualidad existen plug-ins disponi-
bles para Eclipse que permiten hacer uso
de una gran variedad de funcionalidades,
como editar documentos XML, desplegar
EJBs en los servidores ms comunes, des-
arrollar aplicaciones J2EE, modelar con
UML o disear interfaces grficos de modo
visual mediante el plug-in VE (vase Slo
Programadores 122).
EMF es un plug-in que ampla la capacidad
de la plataforma Eclipse, en este caso
generando editores que nos permiten
manejar de forma sencilla los objetos del
modelo.
Instalacin de EMF
La instalacin de EMF es muy simple, slo
tenemos que copiar los ficheros del plug-in
en los directorios plugins y features de
Eclipse. EMF se puede obtener de la direccin
http://download.eclipse.org/tools/emf/scripts/
downloads.php, aunque tambin se ha inclui-
do una copia en el CD-ROM.
Una vez obtenidos el fichero emf-sdo-xsd-
SDK-2.0.2.zip (de la web o del CD-ROM)
basta con descomprimirlo y copiar el conteni-
do del directorio features bajo el directorio
features de Eclipse y el contenido del direc-
torio plugins bajo el directorio plugins de
Eclipse. El paquete de EMF Runtime incluye el
generador EMF y un conjunto de plug-ins
relacionados. Tras instalar el paquete, habr
que comprobar que estn disponibles en el
entorno Eclipse. Esto se puede hacer acce-
diendo a la opcin de informacin de la pla-
taforma Eclipse (About Eclipse Platform), para
ello pulsaremos en el men Help -> About
Eclipse Platform. Una vez all hacemos clic en
Plug-in Details y comprobamos que el con-
junto de plug-ins propios de EMF estn pre-
sentes, nos deberan aparecer entradas como
org.eclipse.emf.ecore, org.eclipse.emf.code-
gen y org.eclipse.emf.edit.
Qu es EMF?
EMF es un entorno de trabajo que permite
modelar y generar cdigo a partir de un
modelo, pudindose construir herramientas
y aplicaciones basadas en modelos de datos
estructurados. EMF soporta el uso de la
especificacin XMI (XML Metadata
Interchange) como modo de representacin
y serializacin de modelos y metamodelos.
EMF es muy genrico permitiendo importar
modelos desde diversas fuentes, como
esquemas XSD, documentos UML y mode-
los especificados mediante anotaciones en
cdigo Java. Tambin es posible crear un
modelo desde cero.
EMF se divide en tres mdulos principales:
EMF: El core incluye un metamodelo
(ecore) con el que se describen los
modelos y caractersticas de soporte en
tiempo de ejecucin que incluyen noti-
ficacin de cambios en el modelo, per-
sistencia en documentos con formato
XML y un API para la manipulacin de
objetos EMF.
EMF. Edi t: El entorno de trabajo
EMF.Edit incluye clases reusables con
las que construir editores de modelos
EMF. Proporciona clases para la visuali-
zacin de contenidos, etiquetas y pro-
piedades, que permiten mostrar los
modelos EMF mediante vistas y hojas
de propiedades. Asimismo, incluye un
entorno de comandos genricos que
pueden ser incluidos en editores.
EMF. Codegen: Este mdulo de gene-
racin de cdigo es capaz de proporcio-
nar las clases necesarias para construir
un editor visual para un modelo EMF
determinado.
Para cada objeto del modelo, EMF generar
una serie de clases que se pueden estructu-
rar en 3 paquetes, (Modelo, Adaptadores y
Editor):
Model: Son el conjunto de clases e
interfaces que representan nuestro
modelo. Para cada una de nuestras cla-
ses definidas en el modelo, EMF genera
un interfaz y una clase que lo imple-
menta.
Adapters: Son una serie de clases que
permiten separar la interfaz grfica del
modelo de negocio. Por cada una de
nuestras clases del modelo se genera un
adaptador (itemProviders), que dicta
cmo se representa grficamente cada
clase e indica cules de sus atributos
son editables.
Edi t or: EMF construye de manera
opcional dentro de Eclipse un editor
estructurado que nos permite modificar
de forma grfica nuestro modelo.
La comunicacin entre los diferentes
paquetes generados por EMF se realiza
mediante tres patrones de diseo bsicos,
Adapter, Command y Observer como se
puede ver en la figura 2.
Ejemplo prctico
En nuestro ejemplo vamos a modelar un
conjunto de clases que representan la
estructura de una base de datos. Para ello
nos creamos las siguientes clases en UML
(vase la figura 3):
Generacin de cdigo a partir de modelos con EMF
Figura 1. El modelo EMF.
Figura 2. Relacin entre paquetes.
SOLO PROGRAMADORES n 127
Proveedor: La empresa proveedora de
la base de datos.
Ti posDeDatos: Representa el conjun-
to de tipos de datos soportados por las
bases de datos del proveedor en cues-
tin.
Ti po: Un tipo de datos especfico, como
puede ser CLOB, SMALLINT o VAR-
CHAR.
BaseDeDatos: Una determinada base
de datos.
Tabl a: Con esta clase representamos
una tabla de la base de datos.
Col umna: Columna de la tabla. Cada
columna tiene un tipo determinado de
entre los definidos como objetos de la
clase Tipo.
EMF soporta la utilizacin de los elementos ms
comunes de un diagrama de clases en UML,
como son clases, atributos y las asociaciones.
Cabe destacar que EMF requiere que el modelo
de clases obtenido mediante Rational cumpla
ciertas condiciones. Las asociaciones entre cla-
ses deben ser navegables si queremos que stas
sean reconocidas por EMF. Por ejemplo, si no
establecisemos una asociacin navegable
entre Tabla y Columna, EMF no nos facilita-
ra la opcin de crear objetos Columna para
una Tabla. Por otro lado, es necesario definir
las asociaciones entre clases del tipo composi-
cin siempre que queramos asociar todas las
instancias de la clase que es destino de la aso-
ciacin con el tiempo de vida de sta. Las aso-
ciaciones de agregacin o asociacin son trans-
formadas por EMF en una propiedad de la clase
origen de la asociacin.
Una vez creado el modelo del ejemplo en UML
como se muestra en la figura 3, lo importamos
en el entorno Eclipse. Para ello seleccionamos
File -> New -> Project y, dentro de la car-
peta Eclipse Modeling Framework, selecciona-
mos EMF Project, dando por nombre a nues-
tro ejemplo EjemploEMF, y pulsamos Next.
Seleccionamos la opcin Load from a Rose
class model y hacemos clic en Next. En este
momento debemos especificar la ruta al fiche-
ro con el modelo generado por la herramienta
Rational, cuya extensin es .mdl (el fichero con
el modelo se ha incluido en el material comple-
mentario de este artculo, y lleva por nombre
bd.mdl) y pulsamos Next. En este paso se
indica el nombre del modelo generado por EMF,
siendo en nuestro caso bd.genmodel.
Seleccionamos el paquete raz y pulsamos
Finish. Una vez finalizado el proceso de crea-
cin del proyecto, podemos inspeccionar su
contenido, encontrando dos ficheros bd.ecore
y bd.genmodel dentro de la jerarqua de car-
petas src/model, tal y como se puede observar
en la figura 4. Como hemos indicado con ante-
rioridad, es posible generar un modelo ecore a
partir de un documento vaco, mediante el edi-
tor que EMF proporciona a tal fin.
El fichero bd.ecore representa, mediante un
documento en formato ecore basado en
estndares de OMG, el modelo de negocio que
hemos definido en Rational. Dicho fichero
puede ser modificado con el editor especfico
proporcionado por EMF o con cualquier otro
editor, al tratarse de un fichero en formato
XML.
Todos los elementos del modelo se representan
mediante nodos. En el ejemplo, la representa-
cin de la clase BaseDeDatos mediante este
lenguaje es la que se muestra en el listado 1.
En el fragmento de cdigo del listado aparecen
varios nodos correspondientes a diferentes
elementos dentro de un modelo ecore. Estos
nodos son eClassifiers y eStructuralFeatures
que permiten definir clases, enumeraciones y
tipos de datos los primeros, as como atributos
y relaciones los segundos.
El fichero bd.genmodel no especifica cmo es
el modelo, sino cmo ser generado el cdigo
fuente a partir de ste. Contiene informacin
relativa a la plataforma especfica para la que
se genera el cdigo. Al igual que sucede con los
ficheros .ecore, EMF proporciona editores para
la visualizacin y modificacin de ficheros
.genmodel. Visto de otra forma, el modelo
generacin (.genmodel) aade al modelo de
negocio (.ecore) un conjunto de atributos
especficos para la generacin de plug-ins para
Eclipse de modo que, si fuese necesario obte-
ner otra implementacin del modelo de nego-
cio (.ecore) bastara con modificar el documen-
to de definicin del modelo de generacin
(.genmodel), nunca el documento ecore.
Una vez obtenidos estos ficheros, procedemos
a generar el cdigo correspondiente a las cla-
ses del modelo y los editores que nos permiti-
rn crear implementaciones de ste. Para ello
editamos el fichero bd.genmodel con el edi-
tor especfico de EMF, EMF Generator, hacemos
clic con el botn derecho del ratn sobre el
nodo raz del rbol y seleccionamos la opcin
Generate All en el men contextual. En la
figura 4 se puede ver el men de generacin
del modelo con la opcin Generate All.
EMF necesita de los modelos ecore y genmodel
para obtener el cdigo fuente, adems de un
conjunto de plantillas denominadas Java
Emitter Templates (JET), con una sintaxis simi-
lar a la de las pginas JSP. Es posible configu-
rar el proceso de generacin modificando el
modelo generador o estas plantillas.
50
DISEO
http://digital.revistasprofesionales.com
Figura 3. Nuestro modelo.
LISTADO 1 Fragmento del fichero bd.ecore relativo a la clase BaseDeDatos
<eClassifiers xsi:type=ecore:EClass name=BaseDeDatos>
<eStructuralFeatures xsi:type=ecore:EReference name=Tabla upperBound=-1 eType=#//Tabla containment=true/>
<eStructuralFeatures xsi:type=ecore:EAttribute name=Nombre eType=ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString/>
<eStructuralFeatures xsi:type=ecore:EAttribute name=Esquema eType=ecore:EDataType
http://www.eclipse.org/emf/2002/Ecore#//EString/>
</eClassifiers>
SOLO PROGRAMADORES n 127
Volviendo al ejemplo, tras eje-
cutar la opcin Generate All
podemos comprobar que se
han creado tres plug-ins dife-
rentes: model, edit y editor.
El plug-in model, creado den-
tro del proyecto original
EjemploEMF, contiene el cdi-
go que implementa el modelo
independiente de plataforma
(PIM) previamente definido con
UML. Generalmente se crea una
estructura de interfaces e
implementaciones de los mis-
mos, que no es necesario modi-
ficar salvo en ciertas ocasiones,
como cuando hemos aadido
mtodos a las clases de negocio
en el modelo UML. Esto es debi-
do a que no es posible especificar informacin
semntica en un modelo EMF hasta despus
de generado el cdigo.
Este plug-in de modelo hace referencia nica-
mente a otros dos plug-ins que forman parte
de la estructura bsica de EMF y son org.eclip-
se.core.runtime y org.eclipse.emf.ecore. Es
posible configurar determinadas opciones en
el documento genmodel de modo que este
modelo EMF.model pueda ser ejecutado
fuera del entorno Eclipse. Una de las principa-
les caractersticas de EMF.model es la inclu-
sin de caractersticas de notificacin en cada
objeto del modelo de modo que se notifique a
aquellos objetos registrados a los cambios en el
modelo. En la figura 4 puede verse la estructu-
ra de proyectos y de paquetes creada.
En el ejemplo podemos comprobar que dentro
del directorio src del proyecto EjemploEMF
se han creado tres paquetes:
ej empl oemf: Contiene los interfaces
Java para cada uno de los objetos del
modelo. Adems se crean dos interfaces
ms: el primero que hereda de
EPackage y se corresponde con el
paquete donde estn incluidas las cla-
ses del modelo, y el segundo, heredero
de EFactory, donde se definen todos
los mtodos de creacin de objetos de
negocio.
ej empl oemf. i mpl: Contiene la imple-
mentacin de los objetos del modelo. Al
igual que en el caso anterior, tendremos
una clase por cada clase del modelo as
como las implementaciones de los
interfaces Factory y Package.
ej empl oemf. uti l: Contiene dos clases
auxiliares. La clase AdapterFactory,
que proporciona adaptadores para cada
objeto del modelo y la clase Switch.
El plug-in edit se crea dentro de un nuevo
proyecto de Eclipse denominado Ejemplo
EMF.edit. Este plug-in separa la capa de pre-
sentacin, representada por el plug-in edi-
tor, del modelo de negocio, que ya vimos con
anterioridad, definiendo un conjunto de
adaptadores denominados ItemProvider para
cada uno de los objetos de negocio. Estos
adaptadores nos permiten modificar el com-
portamiento de nuestros objetos en situacio-
nes tales como una notificacin de cambio en
el modelo. Tambin podemos modificar los
adaptadores para cambiar la representacin
grfica de los objetos del modelo, as como de
sus atributos, en los diferentes componentes
grficos de Eclipse. Ms adelante veremos un
ejemplo de esto ltimo, cuando modifique-
mos la etiqueta y el icono de un determinado
objeto.
Por ltimo, se genera el plug-in editor junto
con el proyecto EjemploEMF.editor, que pro-
porciona diferentes vistas y editores con los
que poder crear y modificar instancias de
nuestro modelo de clases. Junto con el editor
se crea un conjunto de clases por defecto,
EjemploemfEditor, que construye las dife-
rentes pginas con los editores,
EjemploemfActionBarContributor, que
construye los diferentes mens contextuales
y pop-up que se mostrarn junto con los edi-
tores de nuestro modelo, Ejemplo
emfModelWizard, que representa el wizard
de creacin de las instancias del modelo de
negocio, y la clase de definicin e inicializa-
cin del plug-in, BdEclipsePlugin.
Creando objetos en el editor
Una vez visto las clases generadas por EMF,
vamos a ejecutar el editor que se ha creado.
Para ello accedemos a la opcin Run -> Run
as -> Run-time Workbench. Esto abrir una
nueva instancia del entorno Eclipse, pero esta
vez con los plug-ins de nuestro ejemplo acce-
sibles. A continuacin creamos un proyecto,
para ello hacemos File -> New -> Project
-> Simple y le damos un nombre, por ejem-
plo ProyectoEMF. Una vez que lo tenemos,
nos creamos una nueva instancia a partir de
nuestro modelo de negocio. Esto se hace eje-
cutando la opcin de men File -> New ->
Other... y desplegando la carpeta Example
EMF Model Creation Wizards, dentro de la cual
seleccionamos Ejemploemf Model y pulsa-
mos Next. De la lista de carpetas selecciona-
mos la del proyecto ProyectoEMF creado
anteriormente y pulsamos Next. Ahora selec-
cionamos el objeto del modelo a partir del que
queremos crear la nueva instancia del modelo,
en nuestro caso va a ser Proveedor, y pulsa-
mos en Finish.
Ahora vamos a crearnos objetos y darle valores
a los atributos. Para ello, en la vista Selection
de nuestro editor, titulada con el literal
Resource Set aparecer el fichero plat-
form:/resource/ProyectoEMF/My.ejemploemf.
Esto representa la ruta al fichero donde se
almacenar nuestro modelo en el entorno de
trabajo. EMF utiliza la serializacin como
mecanismo de persistencia, almacenando los
objetos del modelo en documentos con forma-
to XML.
Si abrimos el documento utilizando el editor
generado por EMF, podremos observar que se
ha creado un objeto de la clase Proveedor por
defecto, junto con su atributo Nombre.
Vamos a darle un valor al atributo para, a con-
tinuacin crear ms objetos dependientes del
proveedor. Para ello debemos seleccionar el
objeto Proveedor en el editor, esto mostrar
en la vista de propiedades una tabla con el atri-
buto Nombre sin valor. Para ver las propieda-
des del objeto Proveedor pulsaremos con el
botn derecho del ratn sobre Proveedor y en
el men contextual elegiremos Show
Properties View. Para dar un valor al atributo
Nombre basta con pulsar en la columna
Value y asignar el nombre del proveedor de la
base de datos. Para aadir objetos al modelo,
pinchamos sobre el objeto Proveedor y abri-
mos su men contextual. Tenemos dos opcio-
nes (New Chile): crear un objeto
BaseDeDatos o un objeto TiposDeDatos.
Empezaremos creando un objeto
BaseDeDatos. Si vemos sus propiedades,
podemos comprobar que tiene dos atributos,
Esquema y Nombre. Podemos asignarles los
valores SP y BDEjemplo.
Ahora vamos a crearnos un objeto Tabla.
Pulsamos sobre el objeto BaseDeDatos y
abrimos el men contextual, seleccionando
New Chile -> Tabla. En este caso, pre-
senta dos atributos, Descripcin y
Nombre, a los que procedemos a asignar
valores. Siguiendo el mismo procedimiento
51
DISEO
Generacin de cdigo a partir de modelos con EMF
http://digital.revistasprofesionales.com
Figura 4. Estructura de proyectos y de paquetes creada
despus de pulsar en Generate All.
SOLO PROGRAMADORES n 127
que hasta ahora, seleccionamos el objeto
Tabla y le asignamos una Columna, New
Chile -> Columna. Las propiedades de la
Columna son Descripcin, Longitud,
Nombre, Nulo, Clave y Tipo. Es posible
asignar valores a cada uno de ellos. Todas las
propiedades de la columna tienen tipos sim-
ples por valor, salvo la propiedad Tipo, que
almacena un valor de la clase Tipo, perte-
neciente a nuestro modelo de negocio. De
hecho, si intentamos asignar un valor a la
propiedad Tipo, se nos mostrar un combo
con todos los tipos definidos en la instancia
del modelo actual, es decir, se nos muestra
una lista vaca. Esto es debido a que an no
hemos creado el conjunto de tipos permiti-
dos para los campos de nuestro proveedor
de bases de datos. Para ello, creamos un
objeto TipoDeDatos por debajo del Pro-
veedor, y le aadimos un conjunto de objetos
Tipo, que podremos utilizar en la definicin de
las columnas. Un ejemplo para este editor
podra ser el de la figura 5.
Tambin es posible editar el modelo utilizando el
editor de texto, en cuyo caso tendremos acceso
al documento XML que representa el modelo
recin creado que, en caso del ejemplo, podra
ser el mostrado en el listado 2.
Ya hemos visto que es posible modificar el cdi-
go generado en cualquiera de los mdulos ante-
riores. Podremos introducir mtodos en las cla-
ses del modelo, modificar el comportamiento de
los adaptadores y personalizar el editor, aa-
diendo nuevas acciones, etc.
Modificando el editor generado
En este ejemplo vamos a realizar varias modifi-
caciones sobre las clases generadas.
El primer cambio consiste en modificar un
adaptador, cambiando el nombre de una etique-
ta y el icono asociado a sta.
Vamos a cambiar el nombre de la etiqueta para
el objeto BaseDeDatos. Para ello nos vamos a la
clase BaseDeDatosItemProvider, al mtodo
getText(Object object).
Antes de empezar, debemos saber que si modi-
ficamos un mtodo generado y regeneramos el
modelo, perderemos los cambios. Para que no
ocurra esto, debemos hacer lo siguiente:
Hacemos una copia del mtodo que quere-
mos modificar, as siempre tendremos una
copia del mtodo generado.
Renombramos el original aadindole
Gen al final, con lo que el nombre del
mtodo quedara getTextGen. Esto
indica que este mtodo es generado
automticamente por el editor.
Al nuevo mtodo creado le modificare-
mos el tag @generated por @gene-
rated NOT. Esto indica que este mtodo
no es generado automticamente por el
editor y si regeneramos todo el modelo
no se sobrescribir.
Una vez hecho esto vamos a hacer los cam-
bios sobre el mtodo no generado, que con-
sistir en mostrar el valor del atributo
Nombre del objeto BaseDeDatos en el
editor. Vase esto en los listados 3 y 4.
Hecho esto, ahora cambiaremos el icono.
Para ello volvemos a la clase Base
52
DISEO
http://digital.revistasprofesionales.com
Figura 5. Nuestro editor en funcionamiento.
LISTADO 2 Cdigo del ejemplo en XML
<?xml version=1.0 encoding=UTF-8?>
<ejemploemf:Proveedor xmi:version=2.0 xmlns:xmi=http://www.omg.org/XMI xmlns:ejemploemf=http:///ejemploemf.ecore
Nombre=BD Generica>
<BaseDeDatos Nombre=BD Ejemplo Esquema=SoloP>
<Tabla Nombre=Productos Descripcin=Almacena la lista de productos>
<Columna Tipo=//@TiposDeDatos/@Tipo.1 Nombre=COD_PRO Descripcin=Contiene el codigo del producto
Longitud=3 Clave=true/>
<Columna Tipo=//@TiposDeDatos/@Tipo.0 Nombre=Libro Descripcin=Contiene el nombre del producto
Longitud=15/>
</Tabla>
</BaseDeDatos>
<TiposDeDatos>
<Tipo Nombre=String/>
<Tipo Nombre=Integer/>
</TiposDeDatos>
</ejemploemf:Proveedor>
LISTADO 3 Cdigo de la clase, generado automticamente
/**
* This returns the label text for the adapted class.
* @generated
*/
public String getTextGen(Object object) {
String label = ((BaseDeDatos)object).getNombre();
return label == null || label.length() == 0 ?
getString(_UI_BaseDeDatos_type) :
getString(_UI_BaseDeDatos_type) + + label;
}
SOLO PROGRAMADORES n 127 53
DISEO
Generacin de cdigo a partir de modelos con EMF
http://digital.revistasprofesionales.com
DeDatosItemProvider, al mtodo
getImage() (mostrado en el listado 5). Al
igual que en el caso anterior, haremos una
copia del mtodo original. Una vez hecho
esto vamos a hacer los cambios sobre el
mtodo no generado, que consistir en
cambiar el icono del atributo Nombre del
objeto BaseDeDatos en el editor (vase
ahora el listado 6).
La imagen que queremos modificar debe
estar almacenada en el directorio eclipse/
workspace/EjemploEMF.edit/icons/full/obj16.
Si ejecutamos de nuevo el editor podemos
ver estos cambios, tal como se refleja en la
figura 6.
El segundo cambio consiste en aadir una
accin al men pop-up asociado a un obje-
to del modelo mostrado en el editor.
El primer paso es crearnos una clase
que ser la accin. En el plug-in Ejemplo
EMF.editor crearemos el paquete ejemplo-
emf/action y la clase GenerarDDL.java
dentro de l. Esta clase heredar de
org.eclipse.jface.action.Action, al igual que
cualquier accin que queramos aadir al
editor (vase el listado 7).
Lo nico que va a contener esta clase es el
constructor y la implementacin del mto-
do run(), que es invocado por el entorno
de ejecucin de Eclipse cuando se seleccio-
na la accin Generar DDL en el men pop-
up o contextual. Una vez creada la clase
accin, debemos hacer unos cambios en el
cdigo generado por el editor para aadirla
al men pop-up que se muestra al pulsar el
botn derecho del ratn con el cursor sobre
alguno de los objetos del modelo.
La clase que tenemos que modificar es
EjemploemfActionBarContributor.java,
que se encuentra en el paquete presenta-
tion del plug-in EjemploEMF.editor. Ya se
coment con anterioridad que esta clase es
la encargada de dar forma a los diferentes
mens a los que se tiene acceso al abrir
algn editor generado por EMF.
La primera modificacin a esta clase consis-
te en importar la clase que representa nues-
tra nueva accin. Esta es la modificacin:
import ejemploemf.action.GenerarDDL;
El siguiente paso consiste en la creacin de
una variable de dicha clase GenerarDDL,
que ser la instancia de la accin que aa-
diremos a los diferentes mens. Este objeto
ser el responsable de ejecutar la accin
cuando pulsemos la nueva opcin creada
en el men pop-up de los objetos. A la defi-
nicin de esta variable corresponde el
siguiente cdigo, tambin aadido a la
clase:
/**
Figura 6. Primer cambio sobre el cdigo generado.
LISTADO 4 Cdigo de la clase, ahora modificado
/**
* This returns the label text for the adapted class.
* @generated
*/
public String getTextGen(Object object) {
String label = ((BaseDeDatos)object).getNombre();
return label == null || label.length() == 0 ?
getString(_UI_BaseDeDatos_type) :
getString(_UI_BaseDeDatos_type) + + label;
}
/**
* This returns the label text for the adapted class.
* @generated NOT
*/
public String getText(Object object) {
String label = ((BaseDeDatos)object).getNombre();
return label == null || label.length() == 0 ?
getString(_UI_BaseDeDatos_type) :
label;
}
LISTADO 5 Cdigo del mtodo, generado automticamente
/**
* This returns BaseDeDatos.gif.
* @generated
*/
public Object getImage(Object object) {
return getResourceLocator().getImage(full/obj16/BaseDeDatos);
}
LISTADO 6 Cdigo del mtodo, ahora modificado
/**
* This returns BaseDeDatos.gif.
* @generated
*/
public Object getImageGen(Object object) {
return getResourceLocator().getImage(full/obj16/BaseDeDatos);
}
/**
* This returns BaseDeDatos.gif.
* @generated NOT
*/
public Object getImage(Object object) {
return getResourceLocator().getImage(full/obj16/BaseDeDatos2);
}
SOLO PROGRAMADORES n 127
* @generated NOT
*/
protected GenerarDDL generarDDL;
El siguiente cambio es efectuado en el mto-
do selectionChanged. Este mtodo es invo-
cado cada vez que se selecciona un objeto
diferente en el editor de nuestro modelo, de
modo que se crean todas las posibles accio-
nes que apareceran en el men pop-up de
ese objeto en particular. Esto es debido a que
es posible personalizar los mens para cada
objeto del modelo, mostrando unas acciones
y ocultando otras en funcin de qu objeto
aparece seleccionado en el momento de
acceder al men.
Dentro de este mtodo creamos una instan-
cia de la accin aadiendo el siguiente cdi-
go a la clase:
generarDDL = new GenerarDDL(selection);
El cdigo del mtodo quedara tal como
muestra el listado 8.
Para finalizar, modificaremos el mtodo
menuAboutToShow. Este mtodo compone
el men pop-up a partir de un conjunto de
botones y separadores. Para nuestro
ejemplo aadiremos la siguiente lnea de
cdigo:
//Aadimos la accin al men pop-up
menuManager.insertBefore(additions,
generarDDL);
El cdigo del mtodo modificado quedara
como muestra el listado 9.
Una vez realizados estos cambios, ya pode-
mos ejecutar de nuevo el editor para com-
probar el efecto de los mismos. Podemos ver
en la figura 7 el resultado de ejecutar la
nueva accin creada en el pop-up men.
Como se puede comprobar, es relativamente
sencillo ampliar la funcionalidad por defecto
de los editores generados por EMF aadien-
do acciones aplicables tanto a un objeto en
particular como a todo el conjunto de obje-
tos del modelo en general.
Conclusiones
EMF es una herramienta muy poderosa para la
generacin automtica de cdigo, ya que como
se ha visto, a partir de un modelo permite gene-
rar las clases Java que implementan ese mode-
lo. A esto, hay que aadir un uso intensivo de
patrones de diseo en el cdigo generado
(Observer, Command, Adapter...) que garantizan
que ste est bien codificado y sea fcil de
entender.
54
DISEO
http://digital.revistasprofesionales.com
LISTADO 7 Cdigo de la clase GenerarDDL.java
public class GenerarDDL extends Action {
/**
* The object select in the browser. If it is a Entry, the action is
enabled
*/
private Object selection;
public GenerarDDL(Object selection) {
super(Generar DDL);
this.selection = selection;
}
public void run() {
Shell shell =
Workbench.getInstance().getActiveWorkbenchWindow().getShell();
MessageDialog.openInformation(shell,GenerarDDL,La generacin se ha
completado);
}
LISTADO 8 Cdigo del mtodo modificado
/**
* This implements {@link org.eclipse.jface.viewers.ISelectionChangedListener},
* handling {@link org.eclipse.jface.viewers.SelectionChangedEvents} by querying
*for the children and siblings
* that can be added to the selected object and updating the menus accordingly.
* @generated NOT
*/
public void selectionChanged(SelectionChangedEvent event) {
...
ISelection selection = event.getSelection();
generarDDL = new GenerarDDL(selection);
...
}
LISTADO 9 Cdigo del mtodo modificado
/**
* This populates the pop-up menu before it appears.
* @generated NOT
*/
public void menuAboutToShow(IMenuManager menuManager) {
...
//Aadimos la accin al men pop-up
menuManager.insertBefore(additions, generarDDL);
}
Figura 7. Creacin de una accin.
SOLO PROGRAMADORES n 127 56
ALGORITMOS
http://digital.revistasprofesionales.com
Introduccin
La aplicacin que se va a desarrollar como ejem-
plo que resuma esta serie de tres artculos con-
siste bsicamente en una especie de Admi-
nistrador de tareas de Windows. Mostrar una
lista con las aplicaciones que se estn ejecutan-
do en ese momento en el sistema y adems per-
mitir acceder a esas ventanas para activarlas y
modificar su tamao.
Los elementos de la interfaz
La ventana de la aplicacin consta de cuatro ele-
mentos: una lista donde se mostrarn todas las apli-
caciones que se estn ejecutando en ese momento
en Windows, un botn para que la lista se cargue y,
por ltimo, un botn que har que la aplicacin
seleccionada en la lista pase al frente modificando
adems el tamao de su ventana a 800x600 pxeles.
Todos estos componentes quedan reflejados en el
fichero de recursos, resources.rc. El botn que
obtiene la lista de las aplicaciones se identifica con
el valor numrico 2, el botn que trae al frente la
ventana cambiando su tamao se identifica con el
valor 3, y la lista se identifica con el valor 3. Estos
identificadores son necesarios para poder acceder a
los componentes despus. Cuando la aplicacin
principal recibe el mensaje WM_CREATE se crea el
correspondiente dilogo:
hwndDialog =
CreateDialog(GetModuleHandle(NULL),
DIALOG_0, hwnd, DialogProc);
Donde la cadena DIALOG_0 es el identificador
del dilogo, tambin definido en el fichero de
recursos. Posteriormente se ajusta el tamao del
dilogo y se muestra:
GetWindowRect(hwnd, &rectHwnd);
GetWindowRect(hwndDialog,
&rectHwndDialog);
MoveWindow(hwnd, rectHwnd.left,
rectHwnd.top, rectHwndDialog.right-
rectHwndDialog.left, rectHwndDialog.bottom-
rectHwndDialog.top, TRUE);
ShowWindow(hwndDialog, SW_SHOW);
El procedimiento DialogProc es el responsa-
ble de procesar los eventos del dilogo. Se
suele declarar en un fichero de cabecera o
bien, como en este caso, al comienzo del cdi-
go del propio fichero .c. Olvidar esto es un
fallo muy comn y cuando esto sucede la
aplicacin simplemente no compila porque
cuando se hace referencia al procedimiento
del dilogo, en algn punto del cdigo antes
de que el propio procedimiento haya sido
declarado, el compilador no sabe resolver esa
referencia.
Cada vez que el usuario hace clic en alguno de
los botones del dilogo el procedimiento
DialogProc recibe el mensaje WM_COM-
MAND. La parte baja del parmetro lParam
contiene en ese caso el identificador del com-
ponente que origin el evento, es decir, el
identificador del botn. La macro LOWORD
devuelve la parte baja de un valor dado. El
esqueleto del procedimiento de dilogo queda
por lo tanto como se muestra en el listado 1.
Tpicamente el procedimiento de dilogo
En esta tercera y ltima entrega
desarrollaremos un ejemplo
completo de aplicacin, utilizando
para ello nuevos controles y
procedimientos del API Win32.
ADOLFO ALADRO GARCA
API Win32 y C: una programacin
directa y eficaz (y III)
API Win32 y C: una programacin
directa y eficaz (y III)
Fichero resources.rc que define los componentes de la
interfaz.
SOLO PROGRAMADORES n 127 57
ALGORITMOS
API Win32 y C: una programacin directa y eficaz (y III)
http://digital.revistasprofesionales.com
devuelve TRUE cuando procesa el men-
saje que recibe y FALSE en otro caso.
Enumerar ventanas
El procedimiento EnumWindows enumera
todas las ventanas correspondientes a las
aplicaciones que en ese momento se estn
ejecutando en Windows. En el API Win32
queda definido tal y como sigue:
BOOL EnumWindows(WNDENUMPROC
lpEnumFunc, lParam);
Al igual que ocurre con otros muchos pro-
cedimientos del API, EnumWindows utili-
za un mecanismo que se denomina en
ingls callback functions. A grandes ras-
gos ste consiste en que el procedimiento,
durante la enumeracin, llama a otro proce-
dimiento por cada uno de los elementos. El
primer parmetro de EnumWindows es por
lo tanto ese procedimiento, lo que se llama
callback function. El segundo parmetro se
emplea para hacer llegar algn parmetro al
procedimiento que realmente procesa los ele-
mentos. En el caso que nos ocupa se emplea-
r para pasar la direccin de memoria de una
variable donde se ir almacenando la informa-
cin relativa a las ventanas.
Se han definido dos estructuras con el fin de
almacenar la informacin relativa a las venta-
nas abiertas (vase el listado 2).
Cada ventana quedar identificada por una
estructura denominada WindowInfo. Esa
estructura consta del manejador de la venta-
na (hwmd), la cadena de texto correspon-
diente al ttulo y, finalmente, el ndice que
ocupa en la lista de ventanas, la cual est
representada por la estructura WindowList.
El atributo windowInfoList es un array de
elementos WindowInfo que puede llegar a
contener hasta LIST_MAX_LENGTH elemen-
tos. Este valor se define al comienzo del cdi-
go mediante una sentencia define:
#define LIST_MAX_LENGTH 256
El atributo length almacena la ltima
posicin ocupada del array anterior.
Se podra haber optado por una solucin
mejor que consiste en no reservar inicial-
mente ningn espacio para ese array de
datos, e ir solicitando ms memoria nica-
mente cuando se necesite. Aunque eviden-
temente este mtodo es mucho mejor
desde un punto de vista de la optimizacin
de los recursos, adems de que permitira
guardar un nmero variable y no preesta-
blecido de ventanas, su aplicacin compli-
cara el cdigo con llamadas a las funciones
para reservar memoria, liberarla, etc.
En primer lugar se declara una variable glo-
bal de tipo WindowList:
WindowList windowList;
Esta variable se declara global, es decir, al
comienzo del cdigo, para que todos los
procedimientos puedan acceder a ella en
cualquier momento, ya sea durante el pro-
cesamiento de los clics de los botones, o
durante la ejecucin de EnumWindows.
Cuando el usuario hace clic se inicializa la
lista poniendo el atributo length a 0 (la
primera posicin libre del array) y se llama
al procedimiento EnumWindows:
windowList.length = 0;
EnumWindows(EnumWindowsProc,
(LPARAM)(&windowList));
El segundo parmetro es la direccin de
memoria donde se encuentra la variable
windowList. sta se obtiene empleando el
operador ampersand (&). Como Enum
Windows espera como segundo parmetro
algo del tipo LPARAM, simplemente se hace
una conversin de tipos, de forma que la
direccin de memoria de la variable
windowList pasa a ser un valor de tipo LPA-
RAM. El procedimiento EnumWindowsProc
se define tal y como sigue:
LISTADO 1 Esqueleto de DialogProc
BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 2:
{
// Obtener ventanas y rellenar lista
...
break;
}
case 3:
{
// Traer al frente la aplicacin seleccionada
...
break;
}
}
break;
}
default: return FALSE;
}
return TRUE;
}
LISTADO 2
Estructuras de datos para almacenar
la informacin de las ventanas
typedef struct
{
HWND hwnd;
char sWindowText[256];
int iIndex;
} WindowInfo;
typedef struct
{
WindowInfo windowInfoList[LIST_MAX_LENGTH];
int length;
} WindowList;
Documentacin del procedimiento
EnumWindows de Microsoft Platform
SDK.
SOLO PROGRAMADORES n 127
BOOL CALLBACK EnumWindowsProc
(HWND hwnd,LPARAM lParam)
{
WindowList* windowList;
int iCurrentIndex;
...
}
La variable local windowList se emplea
para poder acceder al parmetro lParam
de una forma sencilla. La variable
iCurrentIndex almacenar la propiedad
length de la lista, que como ya se ha
sealado es la longitud de la lista, o tam-
bin la siguiente posicin libre.
El procedimiento EnumWindows normal-
mente suele devolver muchas ms venta-
nas de las que se quieren. El propsito es
obtener una lista lo ms parecida posible a
la que sale en el Administrador de tareas
de Windows. Por lo tanto antes de procesar
la ventana enumerada, aadindola a la
lista, es preciso determinar si es vlida:
if (!IsWindowVisible(hwnd)
|| GetWindow(hwnd, GW_OWNER) != NULL)
{
return TRUE;
}
El procedimiento IsWindowVisible deter-
mina si una ventana es visible o no, como
su propio nombre indica. Todas aquellas
ventanas que no sean visibles sern ignora-
das. Por otro lado, el procedimiento
GetWindow permite acceder a una venta-
na que tiene algn tipo de relacin con otra
ventana dada. El valor GW_OWNER se
emplea para conocer el propietario de la
ventana. Si el valor devuelto por
GetWindow con este parmetro es distin-
to de NULL significa que la ventana enu-
merada es hija de alguna otra, en cuyo caso
tambin se ignorar, ya que el propsito es
obtener la lista de las ventanas principales
de las aplicaciones que en ese momento se
estn ejecutando en Windows, no la lista de
todas las ventanas (todos los componen-
tes). Durante la ejecucin de Enum
WindowsProc si el valor devuelto es
TRUE entonces EnumWindows sigue
con la numeracin. En otro caso la enume-
racin se detiene. En el siguiente fragmen-
to de cdigo se determina el ndice de
insercin en la lista:
windowList = (WindowList*)lParam;
iCurrentIndex = windowList->length;
if (iCurrentIndex>=LIST_MAX_LENGTH) {
return FALSE;
}
windowList->length =
windowList->length + 1;
El valor lParam es la direccin de memo-
ria de la variable original windowList. En
el contexto del procedimiento Enum
WindowsProc, windowList es por lo
tanto una variable de tipo WindowList*,
o lo que es lo mismo, un puntero a una
estructura. Por esta razn de aqu en ade-
lante se accede a los elementos de la
estructura empleando la flecha (->). As
windowList->length devuelve la longi-
tud de la lista, o tambin la posicin den-
tro del array donde se puede almacenar la
informacin correspondiente a la ventana
enumerada. Si el valor de ese indicador
excede el valor mximo permitido, se
devuelve FALSE y la enumeracin con-
cluye. Esto significara que se han consu-
mido todos los elementos disponibles del
array, y ste ya no puede almacenar ms
referencias.
Los datos se van almacenando en la lista
simplemente empleando el ndice deter-
minado en el paso anterior:
windowList->windowInfoList
[iCurrentIndex[.hwnd = hwnd;
windowList->windowInfoList
[iCurrentIndex].iIndex
= iCurrentIndex;
GetWindowText(hwnd, windowList
->windowInfoList[iCurrentIndex].
sWindowText, 256);
El procedimiento GetWindowText guarda el
ttulo de la ventana en el buffer de caracteres
indicado en su segundo parmetro.
En este contexto windowList es un puntero a
una variable de tipo WindowList, que a su vez
es una estructura con dos miembros: length
y windowInfoList. sta ltima es un array de
datos y sus elementos pueden referenciarse
simplemente usando los corchetes. Ahora bien,
cada elemento del array es a su vez una estruc-
tura con los miembros: hwnd, sWindowText
e iIndex. Es importante tener claro todas estas
referencias o de lo contrario se producirn
errores de compilacin, que dentro de lo que
cabe son los menos malos, o errores durante la
ejecucin de la aplicacin por intentar acceder
a una zona de memoria no esperada.
Trabajar con listas
La lista es un control de tipo ListBox tal y
como queda especificado en el fichero de
recursos. Despus de ejecutar el procedi-
miento EnumWindows la estructura
almacenada en la variable global
windowList guarda toda la informacin
necesaria. El primer paso consiste en obte-
ner una referencia a la lista empleando
para ello el procedimiento GetDlgItem:
hwndListBox = GetDlgItem(hwndDialog, 1);
El primer parmetro es el manejador corres-
pondiente al dilogo y el segundo es un valor
que identifica unvocamente al control.
Despus se recorre la estructura y se emplea el
procedimiento SendMessage para ir relle-
nando las entradas de la lista:
int i=0;
for(i=0; i<windowList.length; i++) {
SendMessage (hwndListBox,
LB_INSERTSTRING, i,
(LPARAM)windowList.windowInfoList[i].
sWindowText) ;
}
El mensaje LB_INSERTSTRING indica que se
desea introducir una cadena de texto como
elemento de la lista. El valor i es el ndice de
insercin en la lista. Finalmente, el ltimo par-
metro es la cadena de texto en cuestin.
Obsrvese que en este caso ya no se usa la fle-
cha ya que windowList no es un puntero a
una variable de tipo WindowList sino la varia-
ble misma.
Si en el fichero de recursos se hubiera utilizado
la palabra reservada LBS_SORT entonces la
lista se ordenara alfabticamente de forma
automtica con lo que la insercin podra rea-
lizarse la siguiente forma:
58
ALGORITMOS
http://digital.revistasprofesionales.com
El procedimiento SendMessageTimeout se
utiliza para mandar un mensaje a una
ventana de forma que la llamada sea no
bloqueante.
SOLO PROGRAMADORES n 127
SendMessage (hwndListBox,
LB_ADDSTRING, 0,
(LPARAM)windowList.windowInfoList[i].
sWindowText) ;
Ahora bien, el problema que presenta esta
solucin es que entonces los ndices de la lista
no coincidiran con los ndices del array
windowList.windowInfoList, de forma que
cuando se quisiera saber cul es la ventana
seleccionada no quedara ms remedio que ir
comparando cadenas de caracteres. Se obten-
dra la cadena de texto correspondiente al ndi-
ce seleccionado y despus se buscara en el
array windowList.windowInfoList hasta dar
con la misma cadena, y por lo tanto con el
manejador de la ventana asociada. Por esta
razn es preferible que los nombres de las ven-
tanas aparezcan en la lista en la misma posi-
cin que ocupan en el array rellenado por el
procedimiento EnumWindows, de forma que
si el elemento seleccionado en la lista es
por ejemplo el 3, en windowList.
windowInfoList[3] se encontrar toda la infor-
macin de esa aplicacin.
Cuando el usuario hace clic en el botn identi-
ficado con el valor numrico 3, entonces hay
que traer al frente la aplicacin correspondien-
te y redimensionar la ventana a 800x600 pxe-
les. Para obtener el elemento seleccionado de
la lista se emplea de nuevo otro mensaje,
LB_GETCURSEL:
iSelIndex = SendMessage (hwndListBox,
LB_GETCURSEL, 0, 0);
El valor devuelto, iSelIndex, almacena el
ndice de la lista seleccionado, o -1 en el
caso de que no haya ningn elemento
seleccionado. Como este ndice coincide
con el del array de la estructura
WindowList, acceder a la ventana corres-
pondiente es tan sencillo como hacer:
if (iSelIndex!=-1) {
SetWindowPos(windowList.windowInfoList
[iSelIndex].hwnd, HWND_TOP, 0, 0,
800, 600, SWP_NOMOVE);
}
El procedimiento SetWindowPos tiene diver-
sas funciones y todas dependen normalmente
de la combinacin de valores que tome el lti-
mo de los parmetros. El primer parmetro es
el manejador de la ventana correspondiente.
El siguiente parmetro, en este caso la palabra
reservada HWND_TOP, indica que se quiere
traer la ventana al frente, por encima de
todas las dems ventanas existentes en ese
momento en Windows. Los dos siguiente
parmetros hacen referencia a la posicin de
la ventana, pero como se ver ms adelante
simplemente se ignorarn. A continuacin
estn los parmetros relativos a la anchura y
la altura de la ventana. El ltimo de los par-
metros indica exactamente qu es lo que se
quiere hacer con todos los anteriores. La pala-
bra reservada SWP_NOMOVE seala que no se
desea modificar la posicin de la ventana, as
que esta llamada a SetWindowPos simple-
mente activar la ventana y cambiar el tama-
o de la ventana, pero sin moverla de su posi-
cin original.
En el API Win32 existen muchos procedimien-
tos como SetWindowsPos que tienen un
nombre que podra calificarse de poco afortu-
nado, porque en realidad se emplean para
otras muchas funciones, algunas de las cules
ni siquiera tienen por qu estar relacionadas
con lo que cabra deducirse por nombre.
Normalmente estos procedimientos realizan
una cosa u otra en funcin de un parmetro
de flags, que contiene una combinacin de
palabras reservadas.
Acerca de la identificacin de los recursos
En aplicaciones complejas no es frecuente
identificar los componentes de un dilogo
por su nmero, ya que puede haber un
gran nmero y su gestin puede compli-
carse. Por eso lo ms sencillo es crear un
fichero de cabecera en el que se definan
dichos identificadores. Este fichero se
incluir tanto en el cuerpo del fichero de
recursos, resources.rc, como en el cuerpo
del cdigo, progwin32_03.c. Para el pri-
mer caso se har:
#include ../progwin32_03.h
La indireccin se debe a que el fichero de
recursos se encuentra en el directorio
resources. Para progwin32_03.c la inclu-
sin es:
#include progwin32_03.h
El fichero de cabecera se crea en Dev-C++
seleccionando la opcin File -> New ->
Source File. El aspecto que presenta es
muy simple:
#ifndef _PROGWIN32_03_H_
#define _PROGWIN32_03_H_
59
ALGORITMOS
API Win32 y C: una programacin directa y eficaz (y III)
http://digital.revistasprofesionales.com
LISTADO 3 Contenido del fichero resources.rc
#include <windows.h>
#include ../progwin32_03.h
ICON_MAIN ICON spp.ico
DIALOG_0 DIALOG 0, 0, 436, 204
STYLE DS_SETFONT |WS_CHILD |WS_VISIBLE
FONT 8, Tahoma
LANGUAGE LANG_NEUTRAL, 0
BEGIN
CONTROL Get list of windows,BUTTON_GETAPPSLIST,...
CONTROL ,LISTBOX_APPLIST,LISTBOX,...
CONTROL 800x600,BUTTON_TOPANDRESIZE,BUTTON,...
END
Aplicacin que muestra las ventanas activas de Windows.
SOLO PROGRAMADORES n 127
#define LIST_MAX_LENGTH 256
#define BUTTON_GETAPPSLIST 2
#define BUTTON_TOPANDRESIZE 3
#define LISTBOX_APPLIST 1
#endif /* _PROGWIN32_03_H_ */
Las sentencias de preprocesador ifndef y
endif se emplean para evitar que el fichero
se incluya varias veces de forma accidental.
Si la constante _PROGWIN32_03_H_ (un
nombre que se ha escogido al azar, no tiene
que ser necesariamente se) no est defini-
da entonces se define, y el preprocesador
comienza a analizar el cuerpo del fichero de
cabecera. Si ms tarde por algn motivo
ese fichero intenta procesarse otra vez, la
variable de preprocesador PROG-
WIN32_03_H_ ya estar definida y por lo
tanto se ignorar el cuerpo, saltando direc-
tamente al final de la sentencia endif.
Habiendo declarado las constantes BUT-
TON_GETAPPSLIST, BUTTON_TOPANDRE-
SIZE y LISTBOX_APPLIST, el fichero de
recursos puede emplearlas a la hora de
definir los componentes del cuadro de di-
logo. Vea dicho fichero en el listado 3.
Asimismo en el cdigo del programa se
accede a esos componentes utilizando las
constantes:
switch(LOWORD(wParam))
{
case BUTTON_GETAPPSLIST: ...
case BUTTON_TOPANDRESIZE: ...
}
O bien:
hwndListBox = GetDlgItem(hwndDialog,
LISTBOX_APPLIST);
Esta es la forma ms conveniente de traba-
jar con dilogos y por extensin con com-
ponentes. As cualquier modificacin en el
fichero de recursos no origina que haya que
modificar el cdigo fuente principal,
sino simplemente adaptar el fichero de
cabecera.
Iconos de las aplicaciones
Esta simple aplicacin podra crecer hasta
convertirse en una especie de sustituto del
Administrador de tareas de Windows,
pero no estara completa, al menos desde el
punto de vista de la interfaz, si no mostr-
ramos el icono correspondiente adems del
nombre de las ventanas.
Cuando finaliza el procedimiento Enum
Windows en la variable windowList se
guardan todos los manejadores de las ven-
tanas. Por consiguiente a partir de un
manejador dado hay que poder obtener el
icono asociado. Para ello se va a crear un
nuevo procedimiento:
HICON GetWindowIcon(HWND hwnd);
Dependiendo del tipo de aplicacin corres-
pondiente a la ventana, los iconos pueden
obtenerse de muy diversas formas. La pri-
mera de ellas, la ms inmediata, consiste en
mandar un mensaje WM_GETICON al
manejador de la ventana:
SendMessageTimeout(hwnd, WM_GETICON,
ICON_SMALL, 0,
SMTO_ABORTIFHUNG|SMTO_BLOCK, 1000,
(DWORD_PTR *)&hIcon);
El procedimiento SendMessageTimeout es
igual que el procedimiento SendMessage,
con la salvedad de que si la ventana recep-
tora del mensaje no contesta pasado una
determinada cantidad de tiempo, la funcin
desiste, en otras palabras, no se queda blo-
queada. En este caso es importante que se
utilice SendMessageTimeout porque la
aplicacin a la que se manda el mensaje
puede estar ocupada, o incluso colgada, y
de otra manera sera nuestra propia aplica-
cin la que terminara colgndose esperan-
do la respuesta al mensaje mandado.
El parmetro ICON_SMALL hace referen-
cia al tipo de icono que se est requiriendo.
El valor 1000 es el nmero de milisegun-
dos que estamos dispuestos a esperar. La
palabra reservada SMTO_ABORTIFHUNG
indica que la llamada se abortar si se
detecta que la aplicacin est colgada.
Finalmente, SMTO_BLOCK seala que el
procedimiento esperar hasta que se
obtenga la respuesta, o bien transcurra el
tiempo estipulado.
Si el valor de la variable hIcon es igual
NULL despus de ejecutar el procedimien-
to anterior, puede ocurrir que la aplicacin
no tenga ningn icono pequeo, con lo que
se puede intentar pero requiriendo en este
caso el icono grande:
SendMessageTimeout(hwnd, WM_GETICON,
ICON_BIG, 0,
SMTO_ABORTIFHUNG|SMTO_BLOCK, 1000,
(DWORD_PTR *)&hIcon);
Si no se obtiene xito en ninguno de los dos
casos anteriores, la siguiente opcin con-
siste en obtener el icono de la propia clase
de la ventana, para lo cual se emplea el pro-
cedimiento GetClassLong:
hIcon = (HICON)GetClassLong(hwnd,
GCL_HICONSM);
La palabra reservada GCL_HICONSM indi-
ca que se quiere obtener el icono pequeo
asociado a la clase de la ventana. Del
mismo modo que suceda en el caso ante-
rior, esta llamada puede fallar porque la
aplicacin no tenga un icono pequeo, con
lo que tambin se puede intentar para el
icono grande:
hIcon = (HICON)GetClassLong(hwnd,
GCL_HICON);
Si todos los intentos anteriores fallan,
entonces se obtiene el icono por defecto
que Windows emplea para las aplicaciones:
hIcon = LoadIcon(NULL,
IDI_APPLICATION);
Conclusiones
En esta serie se ha hecho una introduccin
a los aspectos bsicos de la programacin
Win32 en C. Evidentemente no hay ms
que echar un vistazo la documentacin dis-
ponible en msdn.microsoft.com para ser
consciente de la cantidad enorme de temas
que es imposible cubrir, bien por la exten-
sin o bien por su complejidad. Aunque hoy
en da pueda parecer que este tipo de
desarrollos estn obsoletos, lo cierto es que
la mayor parte de las aplicaciones comer-
ciales ms conocidas utilizan este API de
forma explcita, ya sea a travs de un ejecu-
table o mediante libreras DLL, para acceder
al corazn de Windows, de la forma
ms rpida, aunque tambin un poco ms
complicada.
60
ALGORITMOS
http://digital.revistasprofesionales.com
El fichero de cabecera almacena las
constantes que identifican a los
componentes del dilogo.
SOLO PROGRAMADORES n 127 62
Tengo un conj unto de fi cheros, sal-
vados por un servi dor de correo
Open Source en formato estndar, y
me gustar a saber si es posi bl e tra-
tarl os con Java de forma automti-
ca, o si por el contrari o l a decodi fi-
caci n de l os caracteres, y de todo
el mensaj e en s , es al go que hay
que programar desde cero.
El API JavaMail permite automatizar la
mayor parte de las tareas de las que hablas.
En realidad sus capacidades van mucho
ms all, de forma que se puede implemen-
tar un servidor o un cliente de correo elec-
trnico completo.
Un fichero que almacena un mensaje de
correo electrnico en un formato estndar
presenta el aspecto del listado 1.
El aspecto que muestra dicho listado puede
variar mucho dependiendo de si hay fiche-
ros adjuntos, del tipo de codificacin
empleada para las cadenas de caracteres,
etc. Realmente existen muchas posibilida-
des. Sin embargo el API JavaMail es capaz
de tratar esta informacin de forma casi
transparente al programador. As por ejem-
plo, el mensaje anterior podra leerse:
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream
(new FileInputStream
(new File(msg.txt)));
MimeMessage mimeMessage = new
MimeMessage((Session)null, bis)
} catch (Exception e) {
e.printStackTrace();
} finally {
try { if(bis!=null) bis.close();}
catch (Exception e) {}
}
El objeto MimeMessage recibe dos par-
metros: el primero es la sesin y el segun-
do es un flujo de lectura de datos. La sesin
es null porque en este caso tan sencillo
slo vamos a emplear el API de forma local,
para leer mensajes almacenados en fiche-
ros, es decir, la aplicacin no se conectar a
ningn servidor de correo para descargarse
los mensajes.
Una vez que el objeto de tipo
MimeMessage est creado puedes acce-
der al asunto del mensaje, la fecha, etc.,
empleando para ello los mtodos que pro-
porciona. Por ejemplo:
System.out.println(mimeMessage.getSu
bject()= + mimeMessage.getSubject());
Quizs la parte ms compleja es la del tra-
tamiento de los ficheros adjuntos, ya que
pueden existir varias posibilidades. Hay
incluso casos en los que los mensajes,
cuando tienen formato HTML, tratan esa
informacin como una especie de adjun-
to. La rutina del listado 2 ofrece una
manera de obtener el cuerpo de un men-
saje, tanto si se trata de un mensaje sim-
ple como si es uno en formato HTML, con
archivos adjuntos, etc.
El mimetype determina el tipo de men-
saje que es. Si el mensaje contiene archi-
DUDAS
http://digital.revistasprofesionales.com
Preguntas y respuestas
Preguntas y respuestas
ADOLFO ALADRO GARCA
Pgina principal de Sun dedicada al API
JavaMail.
LISTADO 1 Mensaje de correo electrnico
From xxx@wanadoo.es Fri Apr 22 04:28:20 2005
Return-path: <xxx@wanadoo.es>
Envelope-to: yyy@ya.com
Delivery-date: Fri, 22 Apr 2005 04:28:20 +0200
Received: from [192.168.1.24] (helo=antivirus02.ya.com)
by mx01.yacom.srv with esmtp id 1DOnu0-0002Ni-00
for yyy@ya.com; Fri, 22 Apr 2005 04:28:20 +0200
Received: from amavis by antivirus02.ya.com with scanned-ok id 1DOnu0-0004jm-00
for yyy@ya.com; Fri, 22 Apr 2005 04:28:20 +0200
Received: from [192.168.1.56] (helo=antimisp02)
by antivirus02.ya.com with esmtp id 1DOntz-0002oN-00
for yyy@ya.com; Fri, 22 Apr 2005 04:28:19 +0200
Received: from mx.ya.com ([192.168.1.50])
by antimisp02 with ya
id y2UK1R002G29f401
for yyy@ya.com; Fri, 22 Apr 2005 04:28:19 +0200
Received: from asmtp02.eresmas.com ([62.81.235.142])
by mx.ya.com with esmtp id 1DOntz-00078s-00
for yyy@ya.com; Fri, 22 Apr 2005 04:28:19 +0200
Received: from [192.168.108.73] (helo=mb03.in.mad.eresmas.com)
by asmtp02.eresmas.com with esmtp (Exim 4.30)
id 1DOntz-00034D-0w
for yyy@ya.com; Fri, 22 Apr 2005 04:28:19 +0200
Received: from nobody by mb03.in.mad.eresmas.com with local (Exim 4.20)
id 1DOnty-0008MA-NM
for yyy@ya.com; Fri, 22 Apr 2005 04:28:18 +0200
From: XXX <xxx@wanadoo.es>
To: adolfoaladro@ya.com
Subject: hola, soy XXX, hay alguien ah??
Date: Fri, 22 Apr 2005 04:28:18 +0200
X-MAILER: ARB/3.0
Content-Type: text/plain; charset=iso-8859-1
Message-Id: <E1DOnty-0008MA-NM@mb03.in.mad.eresmas.com>
X-Spam-Score: 3.5 (+++)
X-Virus-Scanned: by YA.COM
Hola...
vos adjuntos entonces el objeto
MimeMessage es realidad un Multi-
Part, es decir, se compone se varios obje-
tos Part, cada uno de los cuales repre-
senta un fragmento, o una parte del men-
saje original. Entre esas partes se encuen-
tra tambin el texto del propio mensaje.
En un bl og per sonal qui er o of r ecer
al usuar i o l a posi bi l i dad de el egi r
ent r e var i os est i l os a l a hor a de
vi sual i zar l o. Est o se t r aduce en
t ener que cambi ar el CSS de t oda
l a pgi na di nmi cament e, cuando
el usuar i o sel ecci ona uno de l a
l i st a. De qu f or ma puedo hacer-
l o par a que f unci one en l a mayor a
de l os navegador es?
En una pgina HTML pueden definirse
varios elementos link que hagan
referencia a hojas de estilo CSS, pero eso
no significa necesariamente que todos
se empleen. En el siguiente ejemplo se
definen varios estilos, pero utilizando el
atributo disabled se establece cul es el
que se aplica en ese momento:
<link href=blog1.css rel=stylesheet
type=text/css title=blog1.css/>
<link href=blog2.css rel=stylesheet
type=text/css title=blog2.css
disabled/>
<link href=blog3.css rel=stylesheet
type=text/css title=blog3.css
disabled/>
<link href=blog4.css rel=stylesheet
type=text/css title=blog4.css
disabled/>
...
El truco consiste ahora en decidir cul
de ellos est activado cuando el usuario
realiza la seccin. Vase para ello el lista-
do 3.
La funcin SelectStylesheet recibe como
parmetro una cadena correspondiente al
ttulo del CSS (el atributo title) que el
usuario ha elegido.
En primer lugar se obtienen todos los ele-
mentos link de la pgina y se recorren
hasta dar con aquel elemento que se
corresponde con el estilo que en ese
momento se aplica al documento. La pro-
piedad selectedStylesheet del objeto
document es la que determina la hoja de
estilo actual.
Cuando se encuentra, se modifica el valor
del atributo disabled para que la hoja de
estilo no se emplee.
El segundo bucle realiza la operacin
contrario, estableciendo para el docu-
mento cul es la hoja de estilo que debe
aplicarse.
En cuanto a la compatibilidad con los
navegadores quizs la mejor forma de
evitar problemas es simplemente compro-
bando la existencia de los objetos y de los
mtodos, de forma que si el navegador no
lo permite, la funcin simplemente no
hace nada. Por ejemplo:
if (document.getElementById) {
...
}
SOLO PROGRAMADORES n 127 63
DUDAS
Preguntas y respuestas
http://digital.revistasprofesionales.com
LISTADO 2 Obteniendo el cuerpo del mensaje
private final void showMsgBody(Part part)
{
try {
if (part.isMimeType(text/plain)) {
System.out.println(Text plain message);
System.out.println((String)part.getContent());
} else if (part.isMimeType(text/html)) {
System.out.println(HTML text message);
System.out.println((String)part.getContent());
} else if (part.isMimeType(multipart/*)) {
System.out.println(Multipart message);
final Multipart multipart = (Multipart)part.getContent();
final int iMultipartCount = multipart.getCount();
for(int i=0; i<iMultipartCount; i++) {
showMsgBody (multipart.getBodyPart(i));
}
} else {
System.out.println(Other);
final Object object = part.getContent();
if (object instanceof String) {
System.out.println((String)object);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Ejemplo de un blog personal en el que se
permite al usuario seleccionar la hoja de
estilo con la que desea ver el blog.
LISTADO 3 Activando y desactivando hojas de estilo
function SelectStylesheet(styleSheet)
{
var oLinkElements = document.getElementsByTagName(link);
var oLinkElementsLength = oLinkElements.length;
for (var i=0; i<oLinkElementsLength; i++) {
if (oLinkElements[i].title == document.selectedStylesheet) {
oLinkElements[i].disabled = true;
break;
}
}
for (var i=0; i<oLinkElementsLength; i++) {
if (oLinkElements[i].title == newStylesheet) {
oLinkElements[i].disabled = false;
document.selectedStylesheet = newStylesheet;
break;
}
}
}
SOLO PROGRAMADORES n 127
Fuentes
Creacin de un sistema de distribucin de
Midlets (I)
Nuestro objetivo, como el ttulo de esta pri-
mera entrega indica, es extender las funcio-
nalidades del servidor web IIS para que ste
permita la descarga de aplicaciones para
mviles, concretamente, Midlets. El cdigo de
la aplicacin se encuentra empaquetado en
el fichero MidletServer_bin.zip y para poder
integrar y desplegar este cdigo en IIS, ser
necesario seguir los pasos indicados en el
fichero readme.txt o bien seguir las diapo-
sitivas que se incluyen en el directorio
TutorMidletServer.
Novedades en los lenguajes de .NET 2.0
(y III)
Los generics son una de las novedades ms
importantes que presenta la versin 2.0 de
.NET y por lo tanto sus dos lenguajes princi-
pales, VB y C#, ofrecen sentencias para tra-
bajar con ellos. El cdigo que se adjunta en
este punto debe servir como punto de parti-
da para que el lector pueda practicar los
generics
Struts prctico (II)
Llegamos a la segunda entrega de nuestro
curso sobre la programacin de aplicaciones
J2EE con Struts, y esto nos conduce a entre-
gar la segunda versin de nuestra aplicacin
SP.SHOP. En esta segunda versin, las nove-
dades son importantes: internacionalizacin,
Struts Tiles para las interfaces y validacin de
formularios con commons-validator. Para
desplegar SP.SHOP ser necesario seguir los
pasos propuestos en el fichero Leeme.txt.
Creacin de aplicaciones web con
ColdFusion MX 7 (II)
Como se ha venido comentando en las dos
entregas de este curso, ColdFusion ofrece
multitud de funciones que nos permiten
hacer aplicaciones con muchas menos lneas
de cdigo. En lector encontrar en este punto
una batera de ejemplos que demostrarn
cmo ColdFusion puede trabajar con fechas,
XML, controlar los errores, etc.
Generacin de cdigo a partir de modelos
con EMF
EMF es un framework Open Source para la
construccin automtica de cdigo a partir
de modelos. EMF es, por lo tanto, una imple-
mentacin de MDA para la plataforma Java
que permite trabajar con la mayora de las
especificaciones englobadas dentro de MDA.
En el CD-ROM, y bajo el ttulo Desarrollo de
editores con Eclipse EMF se encuentra el
cdigo de los ejemplos propuestos en nues-
tro artculo de la seccin DISEO, esto es,
Generacin de cdigo a partir de modelos
con EMF. Al decir verdad, EMF permite tanto
una cosa como la otra, por lo que animamos
al lector a iniciarse en esta nueva filosofa de
construccin de aplicaciones.
API Win32 y C: una programacin directa
y eficaz (y III)
Con esta tercera entrega, llega a su fin una
serie de tres artculos que nos han servido
para explorar el corazn de Windows.
Conocer el API Win32 permite hacer cosas
realmente difciles de concebir desde una
programacin a ms alto nivel. Sin ir ms
lejos, en el proyecto que se ha incluido en el
CD-ROM (importable desde Dev-C++) el lec-
tor comprobar que el API Win32 nos permi-
te programar nuestro propio Administrador
de tareas de Windows.
Programacin
Microsoft Developer Day
Por gentileza de Microsoft, se ha incluido en
el CD-ROM el material expuesto en el
Developer Day celebrado por la compaa.
Este material consta de una serie de presen-
taciones, algunas acompaadas de ejemplos
en forma de cdigo, que reflejan las noveda-
des ms importantes del mundo .NET. Sin
embargo, queremos advertir que este mate-
rial fue diseado para ser acompaados por
una exposicin oral, por lo que es posible que
en algunas ocasiones el lector encuentre
alguna dificultad para entender el cdigo de
forma ntegra.
Eclipse Modeling Framework 2.0.2
Como se ha dicho, EMF es una implementa-
cin de MDA para la plataforma Java. El art-
culo Generacin de cdigo a partir de
modelos con EMF explica detalladamente
cmo instalar y usar este plugin.
netBeans 4.1
La versin 4.1 de netBeas ha visto la luz
recientemente, y por este motivo hemos con-
siderado apropiado el incluirla en el CD-ROM.
Las novedades incluidas son muchas, pero
quizs la ms llamativa es que incorpora un
asistente para la migracin de proyectos de
Eclipse a netBeans, lo cual sin duda abre las
puertas de este IDE a muchos desarrolladores
Java.
nGallery 1.6.1
Aquellos programadores afines a las tecnolo-
gas ASP.NET y C# pueden sacar partido de
nGallery de varias maneras. nGallery es una
implementacin de una galera de imgenes
que puede ser incorporada a un desarrollo
web ya existente, pero tambin puede servir
para explorar su cdigo y as seguir apren-
diendo sobre el modelo de programacin
propuesto por ASP.NET, dado que nGallery es
un producto Open Source.
PHP Automatic Web Site 0.3
PAWS nace con la idea de permitir a los
usuarios generar sitios web dinmicos de
forma fcil. PAWS es un CMS escrito en PHP
que nicamente necesita para ser instalado
el motor de bases de datos MySQL y el servi-
dor web con soporte a la tecnologa PHP.
PNGwriter 0.5.3
PNGwriter es una librera que permitir a los
programadores C++ tratar con imgenes
PNG. Existe numerosa documentacin en
castellano en la web del proyecto, aunque su
uso es bastante sencillo.
SimpleSQL
SimpleSQL es un motor de bases de datos
relacionales ligero y sencillo que puede fun-
cionar integrndose en una aplicacin o por
el contrario como servidor de bases de datos.
SimpleSQL admite trabajar con C++, Java o
PHP.
Y adems
A modo de complemento para algunos de los
artculos de este nmero, se han incluido
tambin HSQLDB, Tomcat y Dev-C++.
64
CD-ROM
http://digital.revistasprofesionales.com
Contenido del CD-ROM
Contenido del CD-ROM
LIBROS
http://digital.revistasprofesionales.com SOLO PROGRAMADORES n 127 66
OpenGL es sin duda la primera API de grficos
2D y 3D en tiempo real compatible entre plata-
formas. Su excelente estabilidad y su rendi-
miento se encuentran disponibles incluso en los
PC ms bsicos de hoy en da. Se trata, adems,
de un estndar en los sistemas operativos UNIX,
GNU/Linux y Mac, est incluso invadiendo los
espacios mviles e incrustados, a travs de una
nueva especificacin, OpenGL ES.
Este completo manual proporciona todo lo
necesario para programar con la nueva versin
de OpenGL. Analiza el lenguaje Shading, las
extensiones de sombreado ARB de bajo nivel, los
detalles de programacin para Windows, Mac
OS X y GNU/Linux. Diseado tanto para progra-
madores que desean dominarlo y ampliar sus
conocimientos sobre la programacin de
grficos 2D y 3D como para aquellos programa-
dores experimentados que necesitan crear
aplicaciones multiplataforma. Con este libro
podrs
Descubrir los encabezados y bibliotecas que
pueden usarse en OpenGL y configurar su
entorno.
Crear objetos tridimensionales en el PC.
Mover tus objetos por un mundo virtual.
Utilizar tcnicas de interpretacin rpida en
tiempo real en Windows, Mac OS X y GNU/
Linux.
Experimentar con la aceleracin del hardware.
Realizar escenas tridimensionales interactivas.
Aprovechar el hardware de grficos progra-
mable con el nuevo lenguaje Shading.
OpenGL
AUTORES: Richard S. Wright, Benjamin Lipchak
EDITORIAL: ANAYA
ISBN: 84-415-1794-0
PGINAS: 1102
LUGAR Y AO DE PUBLICACIN: Madrid, 2005
IDIOMA: Castellano
OBSERVACIONES: Incluye CD-ROM con el cdigo fuente
de los ejemplos y herramientas de desarrollo con OpenGL.
Esta obra se dirige a todo informtico que desee
dominar la administracin de una base de datos
de Oracle. Repasa los conceptos, definiciones y
reglas del modelo relacional y detalla su uso en
el marco de las herramientas propuestas de
modo estndar como Oracle Server 10g, es decir,
SQL, SQL*Plus, PL/SQL y Java.
Las tcnicas de programacin avanzadas en
PL/SQL se estudian para poder utilizar toda la
potencia del servidor de bases de datos Oracle
10g y las novedades aportadas por esta versin:
la interfaz iSQLPlus, la herramienta de diseo de
aplicaciones web HTMLDB, la nocin de
flashback table y las expresiones regulares.
Numerosos y precisos ejemplos ayudarn al
lector a dominar estos lenguajes de
referencia en el mundo de las bases de datos
relacionales.
Oracle 10g: SQL, PL/SQL, SQL*Plus
AUTOR: J. Gabillaud
EDITORIAL: Ediciones ENI
ISBN: 2-7460-2839-5
PGINAS: 496
LUGAR Y AO DE PUBLICACIN: Barcelona, 2005
IDIOMA: Castellano
Grficos y BBDD Grficos y BBDD

Potrebbero piacerti anche