0% encontró este documento útil (0 votos)
159 vistas68 páginas

Incluye: La Primera Revista de Programación en Castellano

Cargado por

ReneGudmundsson
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
159 vistas68 páginas

Incluye: La Primera Revista de Programación en Castellano

Cargado por

ReneGudmundsson
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 68

Portada SoloP 158 21/2/08 13:17 Página 1

LA PRIMERA REVISTA DE PROGRAMACIÓN EN CASTELLANO

DE
VLUY
DINC

Precio: 6 € (España) (IVA incluido) • AÑO XIV. 2.ª ÉPOCA • Nº 158 • UNA PUBLICACIÓN DE: REVISTAS PROFESIONALES S.L.

OPINIÓN REDES
La singularidad empaquetada Técnicas AJAX profesionales
para el desarrollo de un slideshow
ACTUALIDAD
Entrevista a Antonio Gómez Pavón BASES DE DATOS
de Microsoft 4D v11 SQL: componentes y servicios web
DISPOSITIVOS MÓVILES DISEÑO
Primeros pasos con Android Creando aplicaciones semánticas con Jena
MIDDLEWARE VÍDEO-TUTORIAL
Uso avanzado de LINQ para SQL Menú Arts

PyS60 es una versión de Python que tiene por objeto permitir el


desarrollo de aplicaciones para Symbian OS (Serie 60).
Con PyS60 podremos crear aplicaciones de grandes posibilidades,
que podrán acceder a todos los servicios del dispositivo.

Noticias, javaHispano, Comunidad .NET, Lecturas y DVD


03 Editorial 158 21/2/08 13:18 Página 3

EDITORIAL
Número 158 DESPEDIDA
Ed i t a : R EVISTAS PROFESIONALES S.L.
Si la escritura de este pequeño texto que se publica como editorial
[email protected]
siempre supone un momento intenso de comunicación con los
C/ Valentin Beato 42,3ª 28037 - Madrid
lectores, en esta ocasión este momento es todavía más especial por
www.revistasprofesionales.com
E d i to r lo que acarrea de despedida. En efecto, el mes que viene, la
Agustín Buelta singladura de Sólo Programadores ya no estará al cargo de este que
•••••••••••••••••••••••••••••••••• escribe y, al hacerlo, se despide. Debo a esta publicación y a sus
Co o r d i n a c i ó n T é c n i c a - R e d a c c i ó n lectores una de las mejores experiencias de mi carrera profesional
Carlos Laparra y de mi vida. A lo largo de tantos meses he tenido ocasión de
•••••••••••••••••••••••••••••••••• conocer a programadores excelentes, incluso pioneros en
Maquetación numerosos proyectos, y he recibido el honor de ser invitado a
Raúl Clavijo eventos de gran altura. Además, he tenido el privilegio de llevar
••••••••••••••••••••••••••••••••••
adelante la primera plataforma digital española para una
As e s o r í a d e Pu b l i c i d a d
publicación de este ámbito, que ha acortado las distancias y ha
Felipe Ribagorda
hecho accesibles los artículos de Sólo Programadores a lectores a
Tel.:91 304 87 64
D e l e g a c i ó n e n B a r ce l o n a los cuales no hubiera podido llegar la edición en papel, aportando
C/ Rocafort,241/243,5º 1ª con ello una modesta contribución a la construcción de una Internet
Mariano Sánchez orientada a contenidos. Por todo ello, doy las gracias a todas las
Tel.:93 322 12 38 personas que me han ayudado a hacer lo mejor posible mi trabajo, y
•••••••••••••••••••••••••••••••••• me despido con un afectuoso saludo.
S u s c ri pc i o n e s
Tel:91 304 87 64
Fax:91 327 13 03

SUMARIO
•••••••••••••••••••••••••••••••••••
I m p re s i ó n
L.M.S.Solución Gráfica
[email protected]
••••••••••••••••••••••••••••••••••• OPINION
D i s t ri b u c i ó n 11 La singularidad empaquetada

ACTUALIDAD
12 Entrevista a Antonio Gómez Pavón, de Microsoft
Saturnino Calleja,7
28002 Madrid
Tfno.915 864 933
DISPOSITIVOS MÓVILES
18 Primeros pasos con Android (II)
D I S T R I B U C I O N E N M E X I CO 24 Desarrollo de aplicaciones con pyS60
DIMSA - C/ Mariano Escobedo,218
Col.Anáhuac.11320 México,D.F.
MIDDLEWARE
D I S T R I BUCION EN ARG E N T I N A 28 LINQ para SQL (y II)
Capital Federal:Distrimachisa
Interior:York Agencysa - Tlf:(5411) 433 150 51 BASES DE DATOS
•••••••••••••••••••••••••••••••••• 36 Caso práctico con 4D v11 SQL (y III)
Quedan expresamente prohibidas la reproducción,la
distribución y la comunicación pública de todo o parte de
los textos contenidos en esta publicación,por cualquier REDES
medio y en cualquier soporte,y para cualquier fin, 46 Slideshow de imágenes con AJAX, XML y DOM (y III)
incluyendo la realización de resúmenes de prensa
comerciales,sin la autorización expresa de esta Editorial,
conforme a lo dispuesto en la vigente Ley de Propiedad
DISEÑO
Intelectual.La infracción de la presente prohibición 52 Programando en Java la Web Semántica con Jena (II)
será perseguida penalmente.
Depósito legal:M-26827-1994 VÍDEO-TUTORIAL
P R I N T E D I N S PA I N 66 Menú Arts
P.V.P. 6 euros
Y ADEMÁS. . .
04 Noticias
06 javaHispano: Blue Ray, Grails, Andorid y más
08 Comunidad .NET. Visual Basic 2008
16 DVD. Visual Studio 2008
62 Lecturas. El libro de Django
noticias 21/2/08 12:44 Página 4

NOTICIAS

PRAGSIS
Innovación tecnológica en España
España es uno de los países de la Unión Europea que menos apues-
ta por la innovación tecnológica en sus productos y servicios, y esto
se refleja también en la estructura empresarial a la hora de adap-
tarse a los cambios tecnológicos. Ésta es la conclusión a la que ha
llegado la consultora tecnológica Pragsis Technologies después de
realizar un análisis sobre varios estudios estadísticos correspon-
dientes al año 2007 de diferentes empresas especializadas en el
sector. Con la apertura del nuevo año todo son nuevos propósitos y
las empresas han decidido subirse al tren tecnológico para no que-
darse en la cola de las nuevas revoluciones que se avecinan en cam-
pos como Internet, las conexiones de alta velocidad y la telefonía
móvil, entre otros.
En los días en los que nos encontramos, las innovaciones tecnoló- Entre los indicadores que el estudio ha utilizado para medir la inno-
gicas son un elemento esencial a la hora de estudiar la productivi- vación, nuestro país solo destaca en la venta de productos novedo-
dad de los factores de las economías modernas, ya que este aspec- sos, que representan en torno al 10% de la facturación total. En este
to repercute directamente tanto en una notable mejora de la efi- aspecto, otro indicador significativo es el número de pequeñas y
ciencia en el terreno económico, como en el bienestar de sus habi- medianas empresas que han decidido a lo largo del pasado año dar
tantes. A la hora de analizar el sector tecnológico hay que basarse un vuelco a su organización empresarial para adaptarse y posicio-
principalmente en dos ámbitos: el que se plantea cómo afecta al narse en el ámbito de las nuevas tecnologías potenciando notable-
crecimiento de la economía la introducción de los cambios técnicos, mente sus departamentos para impulsar la innovación.
y el que estudia cuál es el contexto de los mercados que favorecen Un reciente estudio publicado por la BBC recuerda que en 2007 se han
la introducción de los descubrimientos tecnológicos por parte de desarrollado herramientas que borran las fronteras entre el mundo on-
las empresas que compiten en ellos. line y el off-line como pueden ser la implantación de la gigantesca red
Los indicadores que Pragsis ha considerado en sus estudios para valorar social de Facebook, el iPhone o la Nintendo Wii, entre otros. Para este 2008
el panorama tecnológico en nuestro país son las estadísticas de nos encontramos con varios retos como la implantación Ultra Móvil PC,
Investigación y Desarrollo (I+D), los datos de patentes y las encuestas de que consiste en la conversión de la PDA en un verdadero ordenador por-
innovación de la Organización para la Cooperación y el Desarrollo tátil; la consolidación de la televisión por Internet; la tecnología de redes
Económico (OCDE) (http://www.ipyme.org/IPYME/es-ES/UnionEuropea/ inalámbricas de largo alcance WiMax (que ya es una realidad en Estados
OCDE/), estudios estadísticos de la Fundación para la innovación tecno- Unidos) o el afianzamiento de las soluciones de movilidad entre la pobla-
lógica: COTEC (http://www.cotec.es/) y la Oficina estadística comunitaria: ción española, con un amplio abanico de opciones en las que Pragsis está
EUROSTAT (http://es.wikipedia.org/wiki/Eurostat). El barómetro de la trabajando, como la tecnología NFC que permitirá a los usuarios olvidar-
innovación europea sitúa a España en el grupo de países que van a la se de pagar en efectivo o con su tarjeta de crédito en los establecimien-
zaga a la hora de incorporar nuevos métodos tecnológicos a su oferta de tos, o en el caso de la tecnología de Códigos 2D, poder acceder a cualquier
productos y servicios, en el que también nos topamos con países como evento o participar de numerosas promociones directamente a través de
Italia, Croacia y Hungría, entre otros. su teléfono móvil con la mayor rapidez, eficacia y seguridad posible.

PANDA SECURITY dad le permite saber cuándo va a enviarse este tipo de datos y
dónde, con lo que tendrá siempre el control sobre ellos. De esta
Regalos en el Día Internacional de la Internet Segura manera, se aumenta la seguridad de las transacciones y del inter-
cambio de datos online.
Panda Security tiene entre sus principales objetivos conseguir una Además, la suite de Panda permite analizar el equipo con
navegación por Internet más segura. Por eso, apoya la celebración TotalScan Pro, una solución online que ofrece una mayor capaci-
del 5º Día Internacional de la Internet Segura regalando a los usua- dad de detección, ya que está basada en un innovador modelo de
rios un mes gratuito de Panda Internet Security, su suite integral de seguridad denominado “Inteligencia Colectiva”. Este sistema está
seguridad, disponible en la dirección http://www.pandasecurity.com/ basado en la recolección de información sobre malware proce-
spain/homeusers/downloads/internet-security. dente de toda la comunidad de internautas y el procesamiento
En 2007 se ha observado un uso creciente de automatizado de estos datos en
las páginas web como medio para distribuir unos nuevos datacenters. Esto es
troyanos, gusanos y otras variedades de mal- correlacionado y aprovechado para
ware. En ocasiones, esas páginas no son mali- ofrecer una mayor detección y
ciosas, sino páginas legales que han sido mejorar así la seguridad de los
modificadas por los ciber-delincuentes para clientes de Panda.
infectar a todos aquellos usuarios que las visiten. Para proteger Panda Internet Security ofrece, además, otras funcionalidades
frente a esta creciente amenaza, Panda Internet Security cuenta como anti-spyware, un sistema de mejora del rendimiento del
con un sistema de filtrado web, que bloquea las páginas maliciosas PC, Firewall, Anti-Phishing, anti-rootkit, etc.
o fraudulentas. Puede acceder a la descarga gratuita de un mes de Panda Internet
La protección de los datos confidenciales del usuario está reforza- Security en la dirección http://www.pandasecurity.com/spain/
da, además, con la inclusión de “identity Protect”. Esta funcionali- homeusers/downloads/internet-security.

SOLO PROGRAMADORES nº 158 4 www.revistasprofesionales.com


noticias 21/2/08 12:44 Página 5

NOTICIAS

MICROSOFT taciones permitirá que trabajadores remotos reciban, de


manera muy fiel, la experiencia del escritorio de Windows
Tecnologias de virtualización sin la necesidad de tener hardware de alta calidad para
escritorios, al tiempo que permite que los fabricantes de
Microsoft ha presentado el motor principal de su visión software puedan añadir capacidades adicionales. Los térmi-
“Dynamic IT” para la virtualización, dentro de su estrategia para nos financieros del acuerdo no han sido desvelados. Calista
ayudar a acelerar la adopción de esta tecnología de una manera Technologies, con sede en San José, California, es ahora una
generalizada en el mercado. Como apoyo a esta estrategia, la subsidiaria de Microsoft.
compañía ha anunciado la adquisición de Calista Technologies  Soluciones de escritorio de Windows optimizadas. Microsoft
con el objetivo de mejorar la experiencia del usuario final en las ha presentado soluciones que ayudan a la gestión del escrito-
aplicaciones y escritorios virtualizados, así como la ampliación de rio de manera general, a la migración de usuarios y a la ges-
la alianza con Citrix Systems en las áreas de virtualización de ser- tión del cambio de una manera eficiente y flexible de forma
vidores y clientes, más la opción de licenciamiento flexible utili- que los clientes puedan acceder a las aplicaciones y los datos
zando Windows Vista y nuevas herramientas para implementar el que necesiten. Los clientes pueden utilizar una serie de pro-
software de virtualización de Microsoft. ductos de Microsoft, como Windows Vista, Microsoft Desktop
Hoy en día, existe un amplio debate sobre los retos a los que se Optimization Pack, Windows Vista Enterprise Centralized
enfrentan las empresas, desde los elevados costes y la compleji- Desktop y Terminal Services en Microsoft Windows Server
dad asociada con la gestión de los entornos TI hasta las restric- 2008, para satisfacer sus necesidades en este sentido. Más
ciones y la capacidad para aprovechar al máximo las inversiones información en http://www.microsoft.com/virtualization.
de TI ya realizadas. La estrategia y las
inversiones de Microsoft en el área de
la virtualización son una parte clave
de la visión global de la compañía y
de la estrategia de tecnología a largo
plazo para los profesionales de TI y
desarrolladores. Esta visión, llamada
“Dynamic IT”, se dirige a proporcionar recursos informáticos a
las personas en cualquier momento y lugar de una manera vir- Soluciones de gestión integradas para la virtualización
tual, y crear un entorno de TI más eficiente, flexible y económi- En los departamentos de TI, el software de virtualización está
co. Con la tecnología de virtualización como el principal motor transformando los servidores individuales en centro de datos
de su visión “Dynamic IT”, Microsoft ha concretado unas áreas dinámicos, donde las aplicaciones son añadidas en tiempo real,
específicas de inversión con el objetivo de aportar valor a sus permitiendo una flexibilidad aún mayor y un uso de recursos
clientes: más eficiente. Microsoft ofrece software de virtualización de
 Soluciones flexibles de servidor y cliente. infraestructura como parte de la plataforma de Windows, como
 Soluciones de gestión integradas. por ejemplo Hyper-V y Terminal Services disponibles en
 Rapidez de adopción por parte del cliente. Windows Server 2008, junto con Microsoft System Center, para
gestionar tanto aplicaciones e infraestructuras físicas como vir-
Soluciones flexibles de servidor y cliente tuales. La compañía ofrece una solución de gestión integrada y
La estrategia de Microsoft para la virtualización de servidores simple para gestionar toda la infraestructura de sus clientes,
y clientes consiste en brindar el mejor valor dentro del merca- desde la física hasta la virtual, y desde el hardware hasta las
do con un conjunto completo de soluciones de virtualización aplicaciones y servicios.
desde el escritorio hasta el centro de datos. Por ejemplo, los Como parte de su nueva estrategia, Microsoft también ha anun-
clientes pueden virtualizar casi todos los componentes de sus ciado una ampliación de su acuerdo con Citrix:
escritorios -incluido el sistema operativo, las aplicaciones, los  Hypervisor e interoperabilidad de gestión con Citrix. Citrix
datos y las preferencias- y hacerlos accesibles desde cualquier está desarrollando una herramienta de software que permi-
lugar y sobre cualquier máquina de forma virtual. El resultado tirá a los clientes transferir de una manera fácil máquinas
es una amplia flexibilidad para los usuarios, combinada con virtuales entre Citrix XenServer y Windows Server 2008
nuevos niveles de eficiencia y agilidad en los departamentos Hyper-V para asegurar una mayor interoperabilidad en los
de TI. clientes. Estará disponible una versión de prueba en el segun-
Microsoft ha realizado varios anuncios que refuerzan su estra- do trimestre de 2008 y una versión final junto con el poste-
tegia: rior lanzamiento del Hyper-V.
 La adquisición de Calista Technologies. Microsoft ha com- La virtualización ha estado a nuestro alrededor desde hace más
pletado la compra de Calista Technologies, un proveedor de cuatro décadas, pero los clientes están solo empezando a
líder de tecnologías gráficas para soluciones de virtualiza- comprender todas sus aplicaciones como una forma de suminis-
ción de presentaciones y escritorios de nueva generación. El trar y gestionar recursos informáticos. Mayores ventajas econó-
software de Calista mejora la experiencia de usuario de 3-D micas y de infraestructuras, así como herramientas integradas
y multimedia para las aplicaciones de Microsoft, los des- para gestionar nuevas configuraciones, son necesarias para pro-
pliegues de escritorios virtualizados, y las aplicaciones y ducir una amplia adopción por parte de los clientes. El enfoque
escritorios virtualizados y hosteados que Windows Server de Microsoft se centra en un abanico de iniciativas para ayudar
Terminal Services. La suma de la tecnología de Calista para a los clientes a acelerar esa adopción y construir un entorno
futuros productos de virtualización de escritorios y presen- “Dynamic IT”.

www.revistasprofesionales.com 5 SOLO PROGRAMADORES nº 158


Javahispano 21/2/08 12:46 Página 6

JAVAHISPANO

Actualidad Java de la mano


de javaHispano
Oracle adquiere BEA Systems por 8,3 billones

En diciembre del año pasado en esta sección nos hicimos eco de la oferta pública que
Oracle hizo por BEA Systems: 6,6 billones de dolares. BEA declinó la oferta por considerar-
la demasiado baja. Sin embargo, como ya apuntamos en su día, BEA es una compañía
pequeña en el nicho del mercado de servicios en el que compite: entre sus rivales directos
están compañías como IBM, Sun, Oracle, SAP y (aunque sea con otra tecnología) Microsoft.
Dado el momento de bonanza por el que el sector tecnológico está pasando, era cuestión
de tiempo que alguien con suficiente dinero en sus arcas intentase comprar la compañía.
También apuntamos que quizás los propios directivos de BEA, conscientes de esta situa-
ción, estuviesen interesados en la oferta y sólo quisiesen subir su cuantía, y que probable-
mente las negociaciones continuaban en silencio. Efectivamente, las negociaciones conti-
nuaban y finalmente ha habido un acuerdo: 8,5 billones de dólares. La compra de la com-
pañía no se ha hecho efectiva de modo inmediato, sino que llevará todavía varios meses el
resolver todos los detalles legales y hasta entonces ambas compañías continuarán operan-
do de modo independiente.
Oracle ha informado que la línea de productos de BEA se fusionará con la suya propia y que, cuando la adquisición se ejecute, seguirá
dando soporte a los antiguos clientes de BEA. Sin embargo, la compañía ha sido muy parca en los detalles de qué significa que los pro-
ductos de BEA se "fusionen" con los suyos: por ahora no está claro hasta qué punto los componentes del servidor de aplicaciones de
BEA, que en muchos aspectos es superior al de Oracle, serán parte del futuro Oracle Application Server. En cualquier caso, esperamos
que esta compra, a diferencia de algunas compras anteriores de Oracle, esté guiada también por la tecnología y no sólo por el interés
en conseguir los clientes de una compañía rival.

La guerra de los formatos ha acabado: Blue Ray ha ganado

A principios de este año el formato de vídeo de alta


definición Blue Ray ha dado una estocada de muerte
a su enemigo HD-DVD: Warner Bros anunciaba que
produciría sus títulos exclusivamente en Blue Ray.
Hasta aquel momento aproximadamente la mitad de
los grandes estudios de Hollywood apoyaban a HD-
DVD y la otra mitad a Blue Ray. Con este anuncio, el
70% del contenido de alta definición de Hollywood
pasaba a estar disponible sólo en formato Blue Ray.
Este movimiento fue más que suficiente para que la
balanza,
tras casi
dos años en
equilibrio, se comenzase a inclinar claramente hacia
uno de los formatos. La noticia fue seguida pronto por
otras que apuntaban a que el 90% de los reproducto-
res de alta definición que se habían vendido en
Estados Unidos en las semanas inmediatamente pos-
teriores a este anuncio eran reproductores de Blue Ray.
La suerte de HD-DVD parece echada y Blue Ray, un
formato que incluye dentro de su especificación un
entorno de ejecución de aplicaciones Java para pro-
porcionar contenido interactivo, parece asentarse
como el formato estándar para el vídeo de alta defi-
nición.

SOLO PROGRAMADORES nº 158 6 www.revistasprofesionales.com


Javahispano 21/2/08 12:46 Página 7

JAVAHISPANO
Actualidad Java de la mano de javaHispano

Grails 1.0 OPINIÓN

Evolución y Estado de Glassfish

Grails, el popular framework para construcción de aplicaciones web con


Groovy, ha alcanzado su versión 1.0. Grails es un framework dinámico para
aplicaciones web construido en Java y Groovy que integra varias de las solu-
ciones más comúnmente empleadas en aplicaciones Java EE como Spring,
Hibernate y SiteMesh.
El framework trae a la plataforma Java el desarrollo rápido basado en conven-
ciones al estilo de Ruby on Rails, a la vez que permite a los programadores
Java reusar su conocimiento y experiencia en las API que ya estaban acostum-
brados a emplear. Grails se distribuye bajo licencia Apache. Como todos sabemos, Glassfish es el proyecto Open
Source (patrocinado principalmente por Sun) para el desa-
rrollo de un Servidor de Aplicaciones JEE de última genera-
Lanzado un portal en español sobre Android ción. Prueba del soporte de Sun a este servidor es que se
trata del mismo código al que Sun da soporte técnico, sien-
www.android-spa.com es un portal dedicado a Android, la plataforma para do Glassfish el core del producto "Sun Java System
terminales móviles creada por Google. Android tiene un sistema operativo Application Server" (actualmente en su versión 9.1).
basado en la versión 2.6 del Kernel de Linux y un conjunto de librerías Glassfish ha supuesto rehacer casi completamente el anti-
escritas en C y C++ entre las que se encuentran SQLite y Open GL. guo servidor de aplicaciones de Sun, para dotarlo de un
Apoyándose en estas librerías, Android también proporciona un frame-
enfoque nuevo acorde con las últimas tendencias en el
work, basado en Java, para desarrollar aplicaciones. Finalmente, el stack
incluye un conjunto de aplicaciones de correo electrónico, calendario, desarrollo Java EE, lo que se suele llamar el "state of the
mapas, navegador web, etcétera. art". Si con la primera versión se sentaron las bases de éste
nuevo proyecto, con la segunda se le dotó de aquellas
características necesarias para ascenderlo al nivel de sus
más altos competidores, incorporando balanceador de
carga, clustering, JSR-196 (“pluggable authentication”),
JSR-208 (JBI), ECC, etc.
En la tercera versión, lo más importante es que esta-
rá basado en el proyecto HK2, un sistema de módu-
los acoplados que hará de Glassfish un sistema
totalmente modular, que hará entre otras cosas, que
el kernel sea <100K, con lo cual se podrá instalar
incuso en un teléfono móvil.
HK2 se basa en dos tecnologías: el "Subsistema de
Módulos", para conseguir un mejor aislamiento entre los
distintos módulos que lo forman y el "Modelo de
Componentes", que actúan como servicios que se descu-
bren y montan dinámicamente en tiempo de ejecución.
Aun cuando está previsto para principios de 2009, ya
Android-spa.com contiene documentación en español sobre esta platafor- hay "previews" disponibles en la web del proyecto:
ma. Entre ella destacan, además de diversos tutoriales, los “screencast” que animamos a todos a descargarlas y probarlas desde
demuestran cómo configurar y utilizar la plataforma. El portal también
https://glassfish.dev.java.net.
tiene foros donde los usuarios pueden consultar dudas y mantiene un lis-
tado con las noticias más destacadas relacionadas con Android.
Francisco Morero Peyrona, [email protected]

Sobre el autor
Abraham Otero ([email protected]) es responsable de calidad y miembro de la junta de javaHispano.

www.revistasprofesionales.com 7 SOLO PROGRAMADORES nº 158


comunidad 21/2/08 13:23 Página 8

COMUNIDAD .NET

Visual Basic 2008


PEP LLUIS BAÑO (Presidente de SpainNet, miembro del
comité de INETA-Latam y Microsoft MVP– Visual Developer)
Dicho esto, y aunque las publicaciones técnicas no
dejarán de recordarnos y repetirnos estas noveda-
El mes pasado teorizábamos sobre des, empezaremos destacando el mejorado IDE y
un editor que será fruto de las delicias de todos.
lenguajes. Este nos vemos obligados a Uno de los puntos fuertes de Visual Basic siempre
pasar a la práctica. Por lo tanto vamos a ha sido su amigable entorno y agradables facilida-
desvelar las principales novedades de des y, cómo no, su “intellisense” a la hora de escri-
bir código, que por supuesto es una de las carac-
VB9, otramente conocido como Visual terísticas que más atraen a los programadores que
Basic 2008, que como ya imaginareis lo usan. Es claro que esta versión no decepciona-
rá a nadie y más bien nos producirá cierta incre-
un nombre identifica la versión del dulidad, pues en menos de una hora ya estaremos
compilador y el otro concreta la versión tan familiarizados con las nuevas ayudas del edi-
de Visual Studio sobre la que trabaja. tor que no recordaremos más la anterior versión.
Sabéis que a menudo suele pasar al revés: empe-
zamos trabajando con las nuevas versiones pero
LISTADO 1 Declaración de variables
retrocedemos a las anteriores cuando tenernos
‘Explicito.. lo de siempre
Dim MiNombre As String = “Pep Lluis” que implementar algo, hasta que no dominamos
Dim MiEdad As Integer = 19 completamente el escenario. Salvo excepciones os
Dim MisPersonas As Persona = New Persona With {.Nombre = “Fernando”}
puedo asegurar que no os ocurrirá con Visual
‘Implicito, Inferencia en la definicion
Dim TuNombre = “Antonio” Studio 2008. Una de las características que lo fun-
Dim TuEdad = 39 damentan es la posibilidad de poder escoger para
Dim TusPersonas = New Persona With {.Nombre = “Javier”, .Edad = 20}
qué “framework” trabajara nuestra aplicación

‘Nuestra clase Persona (durante el TechEd, fue una de las inquietudes más
Class Persona
Public Nombre = “” comentadas en el stand de Visual Studio).
Public Apellido = “”
Public Edad = 0
End Class Declaración de variables
LISTADO 2 Inicializador With Empezando con la declaración de variables
Private Sub Inicializar() “Implicitly Typed Local Variables”, nos permite que
‘ el tipo de la variable sea inferido desde la expre-
‘Los Inicializadores de siempre
Dim MiPersona = New Persona sión del inicializador… por ejemplo como se
With MiPersona
.Nombre = “Carlos” muestra en el listado 1.
.Apellido = “Arjona” Aunque nos hemos anticipado a ello y lo hemos
.Edad = 28
End With utilizado anteriormente, también disponemos de
‘ un potente inicializador “With” que nos va a sim-
‘Ahora en VB9, inicializadores basados en expresiones plificar el múltiple acceso a los miembros de un
‘no permiten crear colecciones de objetos complejos
Dim TusPersonas = New List(Of Individuo) _ valor agregado sin tener que especificar repetida-
{ _
mente la expresión de destino. Se muestra en el
{ .Nombre = “Jose”, _
.Apellido = “Garcia”} _ listado 2.
{ .Nombre = “Antonio”, _ Otro de los esperados son los tipos Anónimos que,
.Apeliido = “Garrido”} _
} como su nombre, indica son variables que no
End Sub requieren de una declaración previa del tipo al que
pertenecen. Ello nos permite despreocuparnos de
Partial Class Individuo la identidad a la que pertenece una variable recep-
Public Property Nombre As String
Public property Apellido as String tora de una consulta o al crear una instancia de
Public Property Edad as Integer
End Class un “objeto” recorrido por ejemplo por un “for

SOLO PROGRAMADORES nº 158 8 www.revistasprofesionales.com


comunidad 21/2/08 13:23 Página 9

COMUNIDAD .NET
Visual Basic 2008

LISTADO 3 Tipos anónimos rios, por lo que resulta inadecuado intentar


Public Personas() = _ cubrir con diversos ejemplos la multitud de
{ _ posibilidades en este apartado.
New With {.Nombre = “Lidia”, .Apellido = “Martinez”, .Edad = 19}, _
New With {.Nombre = “Jose”, .Apellido = “Gonzalez”, .Edad = 21}, _ Creo que la mejor ilustración para “Query”
New With {.Nombre = “Antonio”, .Apellido = “Perez”, .Edad = 12 } _
} es tener una vista de sus posibles expresio-
nes, así que mirad la tabla 1.
Una expresión clásica de ejemplo con
LISTADO 4 Consulta
NorthWind es como en el listado 6 o como
Dim MenoresDeEdat = From Individuo In Personas _
Where Individuo.Edad < 13 _ en el 7.
Select New With _ Ahora le tocaría el turno a la Extensión de
{.Su_Nombre = Individuo.Nombre, _
.Su_Apellido = Individuo.Apellido, _ Métodos que, como su nombre indica,
.OjO_Es = “Menor” _
} resulta fácil de explicar… pero no sé si tan
Me.DataGridView1.DataSource = MenoresDeEdat.ToList fácil de usar .
La extensión de un método significa dispo-
LISTADO 5 ner de métodos compartidos marcados con
XML Support
atributos personalizados que permiten ser
Dim MiGrupo = _
<?xml version=”1.0”?> invocados desde la sintaxis a través de la
<Personas xmlns=”urn:Mis:Ejemplos:Gente”>
<Persona Id=”1”> instancia. En efecto, la extensión de méto-
<Nombre>”Jose”</Nombre> dos extiende tipos existentes y la construc-
<Apellido>”Garcia”</Apellido>
<Edad>22</Edad> ción de tipos con métodos adicionales.
</Persona>
<Persona Id=”2”> Mirad el listado 8.
<Nombre>”Antonio”</Nombre> Además de extensiones, también podemos
<Apellido>”Fernandez”</Apellido>
<Edad>11</Edad> trabajar con expresiones Lambda, que no
</Persona>
</Personas> son más que una función sin nombre con
Me.DataGridView1.DataSource = _ retorno de un valor. Su expresión genérica
(From TuGrupo In MiGrupo...<Personajes:Persona> _ sería “Function(c) c.Name” y su expresión
Where TuGrupo.<Personajes:Edad>.Value < 13 _
Select Name = TuGrupo.<Personajes:Nombre>.Value, _ práctica la podéis ver en el listado 9.
Apellido = TuGrupo.<Personajes:Apellido>.Value _
).ToList Otra de las características es muy esperada,
sobre todo por los profesionales de las
next”. Por lo tanto podríamos considerarlo hemos visto algunas puestas en escena de su bases de datos relacionales, ya que en su
una manera de crear el sucedáneo de una semántica. Sin embargo no debemos perder semántica tienen presentes valores nulos y
clase en tiempo de compilación. Veamos la de vista que LINQ se integra en el lenguaje es evidente que deja al descubierto la
del listado 3 y dentro de una consulta en el desde cinco flancos diferentes: en Objetos, en inconsistencia con los lenguajes de progra-
listado 4. XML, para (Relacional) ADO .NET en Datasets, mación en este sentido.
Le toca el turno al “XML Support” y aunque SQL y finalmente Entities. Me atrevería a Es importante que los programas manipulen
pueda parecer una extravagancia el nuevo decir que dicha semántica se adapta y perso- esas semánticas de una forma clara y
espacio XLinq es un API específicamente dise- naliza en función a cada uno de los escena- correcta. Es conocido que el CLR da soporte
ñada para dar soporte a la programación de
XML en memoria y dar entre otras cobertura
a las nuevas capacidades de .NET Framework,
TABLA 1: Query
como LINQ. Aunque en un ejemplo muy bási- Project Select <expr>
Filter Where <expr>, Distinct
co… que podemos ver en el listado 5.
Test Any(<expr>), All(<expr>)
En el turno de “Query CompreHensions”. Nos Join <expr> Join <expr> On <expr> Equals <expr>
introduciremos en la parte que dotará al len- Group By <expr>, <expr> Into <expr>, <expr>
guaje de un sintaxis integrada para poder Group Group Join <decl> On <expr> Equals <expr> Into <expr>
efectuar consultas muy similares a SQL, pero Aggregate Count([<expr>]), Sum(<expr>), Min(<expr>), Max(<expr>), Avg(<expr>)
lo suficientemente bien adoptadas para tener Partition Skip [ While ] <expr>, Take [ While ] <expr>
una buena sintonía y aspecto dentro de Set Union, Intersect, Except
Visual Basic. En los ejemplos anteriores Order Order By <expr>, <expr> [ Ascending | Descending ]

LISTADO 6 NorthWind LISTADO 7 Otro ejemplo


Dim db As New Northwind(…) Dim customers = _
Dim contacts = _ From cust In db.Customers _
From cust In db.Customers _ Select cust.Name, cust.City, cust.State, cust.ZIP _
Where cust.City = “London” Order By ZIP _
Select cust.Name, cust.Phone Select Name, City, State
For Each custInfo in contacts
ColdCall(custInfo.Name, custInfo.Phone)
Next

www.revistasprofesionales.com 9 SOLO PROGRAMADORES nº 158


comunidad 21/2/08 13:23 Página 10

COMUNIDAD .NET

LISTADO 8 Extensión de métodos


a esta “nullability” utilizando el tipo genérico <System.Runtime.CompilerServices.Extension()> _
“nullable(of T as Struct)”. Ahora en Visual Module MisExtensiones
Basic podemos usar “T?” como sintaxis para <System.Runtime.CompilerServices.Extension()> _
Function RaizQ(ByVal nro As System.Double) As Double
tipos nulos. Mirad el listado 10. Return Math.Sqrt(nro)
Una de las primeras “topadas” con el anti- End Function
guo Visual Studio del 2002, o sea su prime- End Module
ra versión, fue entender lo de las firmas de Private Sub Extensiones()
los delegados. Estoy convencido que para Dim Numero As Double = 8
MessageBox.Show(Numero.RaizQ().ToString)
los que no somos excesivamente hábiles End Sub
memorizando, nos hemos dado de narices
en diversas ocasiones cuando creamos dele- LISTADO 9 Expresiones Lambda
gados usando “addressof” o “handles”. La Dim Filtro = Personas.Where(Function(p) p.Edad < 13)
noticia es que a partir de ahora podremos Me.DataGridView1.DataSource = _
(From quienes In Filtro _
ser más desordenados (eso sí que me gusta) Select New With {.Nombre = quienes.Nombre}).ToList
y podremos relajarnos olvidándonos de
memorizar si era ”sender”, “Objct”,
“EventHandler”, “EventArgs” o cualquier
LISTADO 10 Tipos nulos
otra forma de firma… Veamos el listado 11. Dim Numero1 As Integer? = Nothing
Dim Numero2 As Integer = 10
Para finalizar al menos completando un Try
‘ El resultado de la suma es nothing
mínimo sobre lo que se estuvo planeando en ‘ Pero este es un valor aceptable para
‘ la variables Numero1
esta versión, o al menos dio que hablar, Numero1 = Numero2 + Numero1
están los adaptadores dinámicos, conocidos Catch ex As Exception
MessageBox.Show(“Numero1 no puede ser Nothing”)
como “Dynamic interfaces” o “duck typing” y End Try
ios Identificadores dinámicos o “Dynamic Try
Identifiers”. Si hablamos de los Interfaces, la ‘ Numero2 no acepta nulos
Numero2 = Numero1 + Numero2
idea principal se fundamenta en situaciones Catch ex As Exception
MessageBox.Show(“Numero2 no puede ser Nothing”)
donde es necesario acceder a miembros End Try
cuyos tipos son desconocidos en tiempo de
ejecución. Con la opción ‘Strict off’ Visual entendedores, así que los más interesados  Object initializers
Basic permite el acceso a miembros con deberemos conformarnos profundizando  Local type inference
enlace retardado en destinos del tipo ‘Object’. con el ejemplo de http://blogs.msdn.com/  Lambda Expressions
Esta característica es potente y extremada- bethmassi/archive/2007/07/18/making-our-  Extension methods
mente flexible. Sin embargo, renunciamos al code-more-dynamic.aspx.  Expression trees
beneficio de la “Intellisense”, la inferencia y No podemos cerrar esta introducción sin  Anonymous types
la verificación de errores en compilación. una lista completa (al menos eso creo) que  Ternary Operator
Similar al anterior en los identificadores nos sirva de guía para profundizar en las  Relaxed Delegates
dinámicos, el enlace posterior permite a los nuevas características que por proximidad a  Partial Methods
programadores la llamada a métodos en nuestro ámbito sean más interesantes…
objetos cuyos tipos son desconocidos pre- Espero no las olvidéis y despierten vuestra Conclusiones
viamente a la compilación. curiosidad.
En este apartado la naturaleza del tema y el  Query expressions Se acaba el artículo y solo he podido mostrar
objetivo del artículo que intenta cubrir los  XML literals pinceladas. Lo relevante de todo es mostrar
aspectos más relevantes de “lo nuevo” esca-  XML axis properties un punto de inicio para que posteriormente
pa a la posibilidad de profundizar con ejem-  XML IntelliSense podáis profundizar lo necesario dentro de
plos suficientemente claros, escuetos y  Nullable types cada contexto. Happy POgraming!!

LISTADO 11 Firmas

‘Con la firma tradicional
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show(“Hey!!”)
End Sub

‘Relajado
Private Sub Relajado() Handles Button1.Click
MessageBox.Show(“Hey!!”)
End Sub

‘Ademas ...
Dim MiEventHandler As EventHandler = AddressOf Relajado
‘o
Dim TuEventHandler As New EventHandler(AddressOf Button1_Click)

SOLO PROGRAMADORES nº 158 10 www.revistasprofesionales.com


opinion 21/2/08 12:48 Página 11

OPINIÓN

La singularidad empaquetada
NICOLÁS VELÁSQUEZ ESPINEL PCs con Vista como con otros sistemas ope-
rativos. Y es que según estimaciones de
Un punto de inflexión marca un Microsoft, en algunos casos con la nueva
actualización el rendimiento se ha incremen-
antes y un después, una tado hasta en un 50%.
singularidad que sirve para En el apartado de discos se añade soporte
definir un hecho determinado sin para exFAT, un sistema de ficheros pensado
el cual no dejaría de ser más que para ser usado en portátiles con discos flash. Windows Vista tras la instalación del
También se soporta EFI (Extensible Firmware Service Pack.
un acto intrascendente. Así Interface) en sustitución de la BIOS, en clara últimos años. La contagiosa corriente que
ocurrió con el Big Bang, el grito vía de extinción, y de Secure Digital DMA. En prefiere condenarlo antes de escucharlo es
de Eureka de Arquímedes, el día cuanto a la seguridad se presentan mejoras cuanto menos cuestionable. El criterio perso-
en el que se conocieron Paul en BitLocker, que permite el cifrado de los nal debería cocinarse de forma única y perso-
datos, con el soporte de BitLocker en múlti- nal y sólo ser sazonado con la opinión popu-
McCartney y John Lennon o el ples discos y en discos USB, además de pro- lar, nunca al contrario, como ocurre en
mítico gag de la empanadilla de tección para las APIs en modo 64 bits. muchos casos en los que sólo con oír la pala-
Martes y Trece. Sucesos que Si nos ceñimos a las notas de prensa enviadas bra Microsoft algunos se santiguan intentan-
indudablemente han alcanzado por la empresa con base en Redmond y las do ahuyentar los malos espíritus sin saber
noticias aparecidas sobre este tema, las mejo- realmente por qué. Cierto es que no se trata
un lugar destacado en el Olimpo ras resultantes pueden generar un margen de de una ONG si no de toda una multinacional
de los momentos ilustres. confianza del que hasta ahora ha adolecido el que se mueve al son del repiquetear del vil
sistema, y suponer de este modo el espalda- metal pero, ¿qué empresa que forme parte del
Muchos son los que dicen que estamos a razo definitivo para que Vista empiece a fun- mercado de la oferta y la demanda no lo
punto de vivir otro de esos acontecimientos, cionar de la forma en la que tiene que hacer- hace? De hecho, algunos ya vaticinan que la
aunque, eso sí, a una escala mucho menor, lo (aunque hay que advertir que el pack sólo molona Google está condenada a seguir sus
delimitada por el ámbito tecnológico de incluye mejoras y actualizaciones, nada de pasos. Por lo pronto sus empleados “cool” que
nuestros tiempos. La versión final del Service nuevas aplicaciones por lo que a primera vista antes podían llevar mascotas e ir en calceti-
Pack 1 de Windows Vista está a punto de salir, todo seguirá igual). nes por sus oficinas ya han empezado a
o ya lo ha hecho para cuando estés leyendo Sin embargo tras algún tiempo en el sector, sé encorbatarse. Todo un síntoma.
estas líneas, y se espera que su instalación que los adjetivos con los que se adornan los Evaluar la importancia de un punto de infle-
solucione todos los problemas que ha ido comunicados y los números que rematan xión antes de que este se produzca no es una
arrastrando el nuevo sistema operativo de estadísticas y porcentajes tienen “validez” si tarea baladí ya que sólo la perspectiva que
Microsoft desde que saliera hace ya un año. Y te encuentras del mismo lado del espejo (el de proporciona el tiempo inexorable tiene la pre-
es que pese a que aún es muy pronto para Lewis Carrol). Con esto sólo quiero decir que rrogativa de acreditarla. ¿Acaso conseguirá
poder valorarlo, desde la multinacional norte- conviene recibir con cautela cualquier infor- Microsoft dar un golpe de autoridad dando a
americana se anuncia que este paquete de me por un sencillo motivo: aún no he proba- sus usuarios lo que ha venido prometiéndoles
actualizaciones permitirá que Vista pueda por do la versión definitiva y mientras no lo haga, o tendremos que sufrir inútilmente la instala-
fin ser lo que ha venido prometiéndose desde yo, que estoy en todo mi derecho, me haré de ción de un extenso paquete de actualizacio-
hace tiempo: un sistema operativo estable, la hermandad de Santo Tomás, el incrédulo. nes que a buen seguro llevará varias horas?
seguro y de alto rendimiento. El momento de Pero de la misma forma deshagámonos de los Yo prefiero creer que si Microsoft consigue
la verdad ha llegado. prejuicios y del popularismo demonizador que su Service Pack haga la mitad de lo que
La actualización permitirá a los usuarios que ha perseguido a Microsoft durante los promete para Vista, será algo positivo (mea
experimentar mejoras en la compatibilidad de culpa, siempre veré la botella medio llena) ya
las aplicaciones, dispositivos, en la fiabilidad, que en todo caso creo que esto tendrá como
en el rendimiento, en la seguridad y en la vida consecuencia directa un incentivo para el
de la batería del equipo, con el consiguiente mercado, y estimularlo siempre es bueno
aumento en el rendimiento del sistema. Se para nosotros, los usuarios de a pie. Eso sig-
asegura que Windows Vista SP1 soportará nifica que otros se pondrán las pilas para no
diez veces el número de aplicaciones para quedarse rezagados, crearán nuevos produc-
pequeñas empresas y consumidores que la tos, más potentes y versátiles, y que seremos
primera versión de Vista y reducirá el tiempo nosotros los que nos beneficiaremos directa-
empleado en la copia de archivos dentro del Google puede acabar sufriendo el
mente. Y al final y al cabo, eso es lo único que
propio PC o en equipos en red, tanto entre síndrome Microsoft. importa, ¿no?

www.revistasprofesionales.com 11 SOLO PROGRAMADORES nº 158


ACTUALIDAD(entr) 21/2/08 12:50 Página 12

ACTUALIDAD

Entrevista a Antonio Gómez


Pavón, de Microsoft
NICOLÁS VELÁSQUEZ ESPINEL
Se trata de un entorno unificado de desarrollo que
permite a los profesionales de este área usar un
Microsoft lanzó, el pasado 15 de modelo consistente de programación para crear
enero, Visual Studio 2008 en español, aplicaciones a través de un amplio espectro de
una nueva generación de aplicaciones plataformas, incluyendo la Web, Windows Vista,
Microsoft Office System 2007, SQL Server 2008 y
con una experiencia de usuario Windows Server 2008, entre otros.
renovada, ya que proporciona toda la Con el objeto de resolver algunas dudas sobre las
potencia de la plataforma Windows novedades de esta nueva plataforma, hemos
hablado con Antonio Gómez Pavón, Product
Presentation Foundation, con la Manager de Herramientas de Desarrollo y Diseño
productividad del IDE (Integrated de Microsoft desde hace un año, aunque con una
dilatada experiencia previa entre la que podemos
Development Environment), y una encontrar sus 7 años en Oracle donde llegó a ser
integración con las herramientas de Coordinador de Marketing y Comunicación, así
diseño, Microsoft Expression, que como los 3 que estuvo en Borland como Director
de Marketing.
Antonio Gómez Pavón, permiten una estrecha colaboración Nicolás Velásquez: Hola Antonio. Visual
Product Manager de
Herramientas de Desarrollo y entre desarrollador y diseñador. Studio 2008 está destinado a construir apli-
Diseño de Microsoft. caciones que aprovechen todas las posibilida-
des que ofrece Windows Vista (apoyándose en
los servicios de la plataforma .NET 3.0) y pro-
yectos relacionados con la web (AJAX, com-
ponentes y complementos para Microsoft
Office o programas para dispositivos móviles).
¿Cómo definirías en 5 o 6 palabras el nuevo
Visual Studio 2008?
Antonio Gómez Pavón: Pues me lo pones difícil,
pero resumiendo mucho, yo diría que es la herra-
mienta que hará posible la nueva generación de
aplicaciones.
NV: Y a grandes rasgos, ¿qué aporta funda-
mentalmente con respecto a su predecesor
Visual Studio 2005?
AGP: Por un lado una nueva experiencia de usua-
rio, tanto para el desarrollador como para el usua-
rio final de las aplicaciones. Interfaces más ricos
que hacen que las aplicaciones requieran una curva
de aprendizaje menor por parte del usuario, y a su
vez mejora la productividad del desarrollador,
pudiendo desarrollar aplicaciones de mayor calidad
en menor tiempo. Integración con las últimas tec-
nologías y mejoras considerables a la hora de mejo-
rar la colaboración entre los equipos de desarrollo,
optimizado el ciclo de vida de las aplicaciones.
NV: ¿En qué medida apuesta por la integra-
ción con las tecnologías emergentes?
AGP: Antes me has puesto en un aprieto al defi-
nir Visual Studio 2008 en 5 o 6 palabras. A mí

SOLO PROGRAMADORES nº 158 12 www.revistasprofesionales.com


ACTUALIDAD(entr) 21/2/08 12:50 Página 13

ACTUALIDAD
Entrevista a Antonio Gómez Pavón de Microsoft

también me gusta decir que es la herra-


mienta o el IDE de la integración. Han sido
muchas las tecnologías que desde
Microsoft hemos lanzado el año pasado,
Windows Vista, Office 2007, etc... También
.NET 3.0, y en el 2008, Windows Server, SQL
Server 2008, etc. Y teníamos que lanzar un
producto que desarrollara para todas estas
versiones, y también para las anteriores, no
dejando de soportar y posibilitando aplica-
ciones para .NET 2.0, por ejemplo.
Utilizar tecnologías como AJAX, para crear
nuevas experiencias web, con ASP.NET
AJAX, o proyectos Silverlight ahora es posi-
ble con esta nueva versión. Y si hablamos
del desarrollo de aplicaciones sobre dispo-
sitivos móviles…. El soporte e integración
con las ultimas plataformas de Microsoft
Mobile, es total.
NV: En lo que respecta a las herramien- El sitio de MSN sobre las elecciones americanas ha sido desarrollado en Silverlight.
tas Visual Studio Tools for Office (VSTO)
que posibilitan su integración con la diseñar, modificar y optimizar controles de programa de licencias compartidas para
suite ofimática Microsoft Office, ¿qué Office, hacer pruebas y mejorar el rendimien- socios de primer nivel dentro del progra-
aplicaciones prácticas nos ofrece? to en aplicaciones basadas en Office. Miles de ma VSIP (Visual Studio Industry Partner)
AGP: Como he comentado antes la integra- compañías utilizan Excel u Outlook, como que les proporcionará la capacidad de
ción del desarrollo sobre Office, es completa. parte fundamental a la hora de visualizar la visualizar el código de Fuentes Visual
En la versión anterior VSTO, era un paquete información, y la facilidad del desarrollo ace- Studio IDE con objetivos de depuración,
independiente que se compraba como lerará su rápida implementación. simplificando el proceso de integración
ampliación a las funcionalidades de Visual NV: En el último Microsoft TechEd de sus productos con Visual Studio 2008.
Studio. Ahora, de una forma visual podemos Developers se anunció la creación de un ¿Hasta qué punto se hará esto efectivo y
en qué términos?
AGP: VSIP, que es una colección de varios
SDK, es una plataforma y un conjunto de
herramientas para el programador que pro-
porciona a los colaboradores de VSIP un
control más preciso y extenso del entorno
al facilitar el acceso a más interfaces y la
integración completa de la Ayuda de Visual
Studio .NET. Con VSIP, los colaboradores
pueden ofrecer una mayor funcionalidad
en el entorno de diseño de los usuarios.
Microsoft será consecuente con su pro-
puesta y evolucionará la manera de com-
partir y visualizar el código fuente con sus
partners.
NV: Vamos con una de las grandes nove-
dades aparecidas con Visual Studio
2008: LINQ, el nuevo paso evolutivo del
lenguaje orientado a consultas y, segura-
mente, una de las características más
interesantes de esta nueva versión. De
hecho hace algunos meses (Sólo
Programadores 152) Amanda Silver, que
ha trabajado activamente en el desarro-
llo de Visual Basic 9.0, nos confirmaba
que LINQ iba a estar soportado por los
Visual Studio Express es la popular versión gratuita de Visual Studio, ideal para
estudiantes y aficionados. dispositivos móviles ¿Qué puedes decir-

www.revistasprofesionales.com 13 SOLO PROGRAMADORES nº 158


ACTUALIDAD(entr) 21/2/08 12:50 Página 14

ACTUALIDAD

LINQ es el nuevo enfoque de Microsoft hacia las consultas a bases de datos.

nos de cómo ha recibido la comunidad paga, sobre todo en tiempo, y en aplica- AGP: Dar soluciones a los equipos de desarro-
esta nueva tecnología? ciones complejas, más. llo es una de las características principales de
AGP: Es una de las novedades más valora- NV: Asimismo, me llama poderosamente la nueva versión de Visual Studio Team
das por los más de 3.000 usuarios que en la atención la tecnología que aparece en System. Cada vez es más habitual que haya
España ya han probado Visual Studio 2008, Visual Studio 2008 bautizada como distintos roles involucrados en todo el proce-
sobre todo por su productividad, ya que per- Astoria y que incluye de momento un so que creación de software, y desde estas
mite consultas entre distintos tipos de datos pequeño conjunto de interfaces que nuevas versiones mejoramos e incrementa-
(XML, Relacionales, Objetos), algo que podría soportan LINQ sobre HTTP, lo que algu- mos nuevas funcionalidades para el arquitec-
considerarse básico, pero que ahorra tiempo nos se atreven a calificar que podría to, desarrollador, diseñador, profesional de
a la hora de desarrollar. suponer un primer paso en dirección a la base de datos y testers.
NV: ¿Qué hay de cierto en algunas noti- web 3.0 o web semántica. ¿Qué puedes A la hora de gestionar proyectos hay tam-
cias que apuntan a que si no se desarro- decirnos de ella? bién otros roles involucrados en el proceso
lla correctamente el código LINQ, se AGP: Astoria permite a los desarrolladores de desarrollo: jefes de proyectos, analistas,
pueden generar accesos redundantes a la crear y consumir servicios de datos para la directores de desarrollo, CIOs, que gracias a
base de datos y, por ende, disminuir el Web, estos servicios acceden a información Team Foundation Server pueden no solo
rendimiento del sistema? con una simple interfaz HTTP que pueden ser tener un repositorio de código o control de
AGP: El truco es desarrollar correctamen- consumidos por webs basados en AJAX y versiones, sino que pueden tener el control
te ;-) Hay tutoriales y documentación en webs que cuentan con aplicaciones interac- de los proyectos, gestión de tiempos, auto-
nuestro portal MSDN para orientar a los tivas. matizar compilaciones, control de tiempos,
desarrolladores a optimizar su código NV: Cambiando un poco el tercio, ¿qué etc. Asimismo cabe destacar su integración
LINQ. También contamos con partners que puedes decirnos de la importancia que con Project y Project Server.
hoy son especialistas en LINQ y ofrecen vais dando a las versiones Team de Visual NV: En lo que respecta a la nueva tecno-
formación. Seguro que el mal código se Studio? logía Silverlight, desde el punto de vista

SOLO PROGRAMADORES nº 158 14 www.revistasprofesionales.com


ACTUALIDAD(entr) 21/2/08 12:50 Página 15

ACTUALIDAD
Entrevista a Antonio Gómez Pavón de Microsoft

de un usuario de a pie que ya accede a


contenidos mediante Flash, ¿qué puede
ésta ofrecer que no tenga ya?
AGP: Por un lado dar la posibilidad de uti-
lizar una plataforma alternativa al 99% de
Adobe en este mercado. Y también, y más
importante, Microsoft ofrece una solución
que enlaza desarrollo y diseño, y diseño con
el desarrollo. Todos los desarrolladores de
Visual Studio y entornos .NET tienen la
posibilidad de crear nuevas experiencias de
usuario e interfaces atractivos utilizando la
familia de productos de diseño Microsoft
Expression y Silverlight, sin depender de
integraciones con Flash.
NV: Veo que la apuesta es clara. De ahí
que a lo largo de este año, muchos con-
tenidos importantes se vayan a presen-
tar de la mano de Silverlight. Se habla
de una cobertura web especial a las
Olimpiadas de Beijing así como el
aumento sustancial de áreas en el sitio Las herramientas Expression aún necesitan madurar pero la apuesta es clara.
de Microsoft. En este aspecto, ¿qué
medidas se tomarán desde Microsoft popularización por parte de los desarro- ¿cómo puede calificarse su expansión en
para impulsar esta tecnología en un lladores, ¿verdad? ¿Hay previsto algún estos últimos meses?
terreno donde Flash es, hoy por hoy, el “plan de acción” especial, alguna estra- AGP: Sabemos que necesitamos que nues-
estándar a batir? tegia clara para llegar a este sector en tras herramientas de diseño maduren, pero
AGP: Está claro que lo más fácil es empezar concreto? Actividades, seminarios, con- en menos de un año vamos a sacar dos ver-
por nuestras webs que tienen contenidos cursos… siones de Expression.
proporcionados por Silverlight y que ahora AGP: Los desarrolladores son los primeros Todo usuario de Visual Studio con suscrip-
reciben millones de visitas. También plata- que nos demandan información, eventos, ción MSDN Premium, así como miles de
formas como MSN o comunidades como formaciones, etc. a la hora de ofrecer a sus usuarios en España, han podido utilizar la
Xbox, por citar algunas, pueden ser buenos clientes mejores aplicaciones. primera versión de Expression Web y
ejemplos, sin contar con muchos de nues- Ahora mismo todos nuestros seminarios de Blend. De la misma forma ahora
tros clientes y top webs de Estados Unidos, desarrollo incluyen una parte de UX Expression Media se incluye para clientes
que también hacen uso de la tecnología que (Experiencia de Usuario) para que se vaya de Office para Mac.
brinda Silverlight. Es mejor verlo :-) viendo nuestra evolución en esta área. Cada vez el desarrollador que utiliza Visual
http://silverlight.net/Showcase/ Ahora al RoadShow de lanzamiento de Studio es consciente que el diseño es
La prueba es que webs como la NBA, Globos Visual Studio 2008 por 6 ciudades, asistirán imprescindible, y Microsoft Expression es
de Oro, Premios EMMY, TerraTV, Olimpiadas más de 2.000 desarrolladores, y comunica- una realidad.
de Beijing que has citado, etc., ya lo han remos estas novedades a casi 30.000. NV: Ya para terminar, ¿podrías comen-
adoptado. Y tenemos más de 16 Clubs de Usuarios tarnos qué cambios en versiones y pre-
Microsoft tiene miles de clientes y esta solu- .NET que divulgan todas nuestras tecnolo- cios nos vamos a encontrar con esta
ción ha formado parte de nuestra oferta. gías de una forma totalmente altruista. nueva versión?
NV: ¿Y en particular para España? Una de ellas tiene en marcha un concurso AGP: No hay ningún cambio en las versio-
AGP: Llevamos más de un año anunciando para premiar con un viaje al MIX de Las nes de Visual Studio 2008. Mantenemos la
la aparición de estos productos/tecnologías Vegas, a la mejor aplicación Silverlight versión Express, gratuita para todas las per-
en todos nuestros eventos y comunicacio- presentada. sonas que quieran empezar a desarrollar,
nes. Nuestro público era 100% del mundo NV: En este aspecto las herramientas que junto a la plataforma .NET, ahora en su
de desarrollo y estamos llegando cada vez a Expression tienen mucho que decir versión 3.5, también de descarga gratuita,
más profesionales del diseño. Este año puesto que Microsoft las ha presentado da muchas posibilidades a quien desarrolla
repetiremos el REMIX, evento que replica el como el medio ideal para integrar el por hobby, estudiantes, etc..
MIX que se celebra en Las Vegas en marzo. proceso de diseño y desarrollo con sus Para los profesionales tanto las versiones
Cada vez tenemos más partners que cono- nuevas tecnologías. Sabiendo que ya hay Estándar, Profesional como versiones
cen e implementan proyectos Silverlight. algunas herramientas para el desarrollo Team, mantenemos los mismos precios de
NV: La aceptación de Silverlight en los web o el diseño vectorial, por ejemplo, la versión 2005.
hogares tiene que ir de la mano con su bastante asentadas en el mercado Y disponible desde principios de febrero.

www.revistasprofesionales.com 15 SOLO PROGRAMADORES nº 158


DVDROM 21/2/08 12:51 Página 16

DVD

Visual Studio 2008


Microsoft Visual Studio 2008
cumple con la visión de
Microsoft sobre aplicaciones
inteligentes, al permitir que
los desarrolladores creen
rápidamente aplicaciones
conectadas con la más alta
calidad y con atractivas
experiencias de usuario. Por
gentileza de Microsoft, la
edición en papel de este
número viene acompañada por
un DVD con las ediciones
Express de Visual Studio
2008. Ahora, el lector tiene en
su mano la posibilidad de
iniciarse en la creación de
aplicaciones de última
generación.
Para quienes no conozcan la herramienta, o decisiones de negocio más efectivas. Gracias a
Introducción para quienes aún no tengan claras las nuevas Visual Studio 2008, las organizaciones de todo
prestaciones ofrecidas, a continuación expo- tamaño podrán crear rápidamente aplicacio-
A lo largo de esta temporada, ya desde el nemos, en palabras de Microsoft, aquellos nes más seguras, confiables y administrables,
mes de septiembre, en Sólo Programadores puntos más significativos del producto. capaces de aprovechar mejor las característi-
hemos venido cubriendo las principales cas de Windows Vista y de Office 2007.
novedades incorporadas a la última versión Visual Studio 2008 Visual Studio 2008 ofrece avances clave
de Visual Studio. Asimismo, desde septiem- para desarrolladores en función de los
bre hemos venido publicando entrevistas y Con Visual Studio 2008, las organizaciones siguientes tres pilares:
artículos técnicos relacionados con esta encontrarán que ahora es más fácil capturar y  Desarrollo rápido de aplicaciones.
herramienta de desarrollo. analizar información, y por lo tanto tomar  Colaboración eficiente entre equipos.
 Innovación en experiencias de usuario.
Visual Studio 2008 ofrece herramientas de
desarrollo avanzadas, funciones de debug-
ging, funciones para bases de datos y fun-
ciones innovadoras que permiten crear
rápidamente aplicaciones futuras para dis-
tintas plataformas. Visual Studio 2008
incluye mejoras como diseñadores visuales
para un desarrollo más rápido con .NET
Framework 3.5, mejoras sustanciales en las
herramientas de desarrollo Web y mejoras
de programación que aceleran el desarrollo
a partir de todo tipo de datos.

SOLO PROGRAMADORES nº 158 16 www.revistasprofesionales.com


DVDROM 21/2/08 12:51 Página 17

DVD
Visual Studio 2008

las últimas plataformas, incluidas la Web, Windows


Vista, Office 2007, SQL Server 2008 y Windows
Server 2008. Para la Web, ASP.NET AJAX y otras nue-
vas tecnologías permitirán que los desarrolladores
Visual Studio 2008 ofrece todo el soporte reque- creen rápidamente una nueva generación de expe-
rido para marcos y herramientas, y necesario para riencias más eficientes, interactivas y personalizadas.
crear aplicaciones AJAX para Web, completas y Visual Studio 2008 propone ofertas expandidas y
expresivas. Los desarrolladores podrán aprove- mejoradas que ayudan a mejorar la colaboración entre
char estos marcos con una faceta para clientes y equipos de desarrollo, incluidas herramientas que cola-
otra faceta para servidores, marcos que permiten boran con la integración entre profesionales especiali-
construir fácilmente aplicaciones Web concen- zados en bases de datos y diseñadores gráficos.
tradas en los clientes, que se integran con cual- .NET Framework permite la construcción rápida de
quier proveedor de datos de back-end, que se eje- aplicaciones conectadas que ofrecen experiencias
cutan dentro de cualquier explorador moderno, y de usuario increíbles, ya que ofrecen bloques de
que tienen acceso total a los servicios de aplica- construcción (software pre-fabricado) que resuel-
ciones ASP.NET y de la plataforma Microsoft. ven las tareas de programación más frecuentes.
Para que los desarrolladores puedan crear rápida- Las aplicaciones conectadas construidas sobre los
mente software moderno, Visual Studio 2008 ofre- modelos de negocio de .NET Framework procesan
ce funciones de programación y de datos mejora- de manera efectiva y facilitan la integración de sis-
das, como LINQ (Language Integrated Query), que temas en entornos heterogéneos.
facilita el armado de soluciones capaces de analizar Juntos, Visual Studio y .NET Framework reducen la
información y de actuar en consecuencia. necesidad de código en común, disminuyen los
Visual Studio 2008 también brinda la posibilidad tiempos de desarrollo, y permiten que los desarro-
de apuntar a distintas versiones de .NET lladores se concentren en resolver problemas
Framework desde el mismo entorno de desarro- comerciales.
llo. Por lo tanto, los desarrolladores podrán cons- .NET Framework 3.5 construye más que .NET
truir aplicaciones que apunten a .NET Framework Framework 3.0. Las mejoras fueron aplicadas a áreas
2.0, 3.0 o 3.5, y así podrán admitir una amplia fundamentales como la biblioteca básica de clases,
variedad de proyectos en un mismo entorno. Windows Workflow Foundation, Windows
Visual Studio 2008 ofrece nuevas herramientas que Communication Foundation, Windows Presentation
aceleran la creación de aplicaciones conectadas con Foundation y Windows CardSpace.

www.revistasprofesionales.com 17 SOLO PROGRAMADORES nº 158


DISPMOVILES(android) 21/2/08 12:53 Página 18

DISPOSITIVOS MÓVILES

Primeros pasos con Android (II)


AITOR ALMEIDA ESCONDRILLAS Y DAVID SAINZ GONZALEZ dos elementos de formulario, al comienzo no
contendrá nada, pero quizá en algún evento
En el artículo anterior de esta serie interese rellenarlo con algo (una imagen, por
vimos una introducción a Android ejemplo). De esa forma controlamos dónde
exactamente queremos colocar elementos
y los primeros pasos para realizar nuevos, ya que es posible anidar Layouts.
un proyecto. En este artículo  LinearLayout: Sitúa elementos en una sola

profundizaremos algo más en los dirección: bien horizontal o bien en vertical. El


layout horizontal irá colocando los elementos
tipos de aplicaciones que pueden uno tras otro en la misma línea, mientras que
hacerse y las APIs disponibles. el vertical lo colocará uno debajo del otro. Este
Layout respeta no obstante los márgenes de
cada parte de cada control, de forma que no
Una aplicación simple nos tenemos que preocupar de separar unos
controles de otros. Asimismo, se respetan las
En la primera parte de esta serie vimos unas pin- propiedades de alineación horizontal y vertical
celadas de los tipos de bloques que podían hacer- de los controles. Si utilizamos alineación verti-
se en aplicaciones Android (recordemos: cal, el layout colocará los controles respetando
Activities, Intent Receivers y Services). Vamos a su preferencia de alinearse a la izquierda, dere-
verlas un poco más en detalle, comenzando por cha o centro.
un bloque Activity. Ya vimos que representaba  TableLayout: Este layout coloca elementos
básicamente una pantalla en la aplicación y que dentro de una tabla. Se divide la pantalla en
era el bloque más comúnmente utilizado. filas y columnas, sin dibujar el borde de la
Comencemos a profundizar viendo cómo crear tabla, y se van colocando elementos en ella. La
interfaces básicas. forma de colocar es dentro de objetos
“TableRow”, que representan las filas de la
La interfaz gráfica tabla. Cada fila contiene a su vez un número de
La mejor forma de crear una interfaz de usuario es columnas.
de forma declarativa, en un archivo XML dentro  AbsoluteLayout: Con este layout podemos
de la carpeta “res/layout”. Antes de comenzar a colocar un elemento justo donde deseemos,
poner elementos en una pantalla, debemos tener dando a cada uno unos valores de posición X e Y.
en cuenta que se trata de pantallas muy limitadas  RelativeLayout: Utilizando este layout podemos
en tamaño y no es usual tratar el reparto de ele- referirnos a la posición de un elemento relativa a
mentos de formulario de la misma forma en la la posición de otro. Para poder referirnos al obje-
que se hace para pantallas de ordenadores de to en el que basarnos, utilizamos su ID.
sobremesa. Más aún, no sólo este reducido tama- Existen además otros valores típicos que se aña-
ño constituye un problema, sino que está la difi- den a los objetos de pantalla.
cultad añadida de la multitud de tamaños de pan-  ID: Nombre único del elemento. Representado
talla que los dispositivos móviles pueden tener. por el atributo “id”.
Para paliar este problema, Android utiliza el con-  Altura y anchura: Se representan más común-
cepto de “Layout” o dicho de otra forma, la forma mente con las propiedades “layout_width” y
en la que los controles de formulario se van “layout_height”. El prefijo layout significa que
situando en la pantalla según se declaran. son propiedades que pertenecen al layout más
Por defecto, aparecen los siguientes tipos: que al objeto. Los valores más comunes son
“wrap_content” para que se ajuste al contenido
 FrameLayout: Es el más simple de todos. Se que tiene dentro y “fill_parent” para que ocupe
trata de un espacio en blanco donde se coloca todo el contenedor.
un solo elemento. Si se colocan más, se irán  Texto: Representado por la propiedad “text”,
superponiendo uno encima de otro. No resulta es el texto que contienen los controles.
útil para grupos de elementos, pero sí que lo es  Gravedad: Concepto que usa Android para
para reservar espacios en blanco. Puesto entre referirse a la alineación del elemento. A través

SOLO PROGRAMADORES nº 158 18 www.revistasprofesionales.com


DISPMOVILES(android) 21/2/08 12:53 Página 19

DISPOSITIVOS MÓVILES
Primeros pasos con Android (II)

de la propiedad “gravity” se le pueden


asignar valores como “center”.
 Peso: Los layouts ofrecen una manera,
gracias al atributo “weight” de dar una
prioridad a unos controles sobre otros
sobre quién ocupará más parte de la pan-
talla. Para evitar situaciones como la de
una lista con numerosos elementos rele-
gada a una esquina de la pantalla, se
ofrece una forma de dar un poso más a
unos elementos que a otros. Por defecto
esta propiedad es cero, pero si se da valor,
los elementos de más peso tienen que lle-
nar el hueco sobrante de pantalla y ocu-
par más parte de ella.
Teniendo en cuenta todo lo anterior, debemos
pensar en cómo colocar y ordenar todo den-
tro del archivo XML. Si queremos colocar sola-
mente un elemento, podemos incluso prescin-
dir de layouts. Sin embargo, en cuanto más de
un objeto entre en escena, será muy conve- Figura 1. Diferentes layouts.
niente usarlos. Estos elementos layout enton-
ces, serán los primeros que colocaremos en el LISTADO 1 Ejemplo de interfaz en XML
archivo. Los objetos reales y otros Layouts
podrán ir colocados de forma anidada a estas <?xml version=”1.0” encoding=”utf-8”?>
<TableLayout xmlns:android=”http://schemas.android.com/apk/res/android”
etiquetas layout. ¿Qué elementos de formula- android:orientation=”vertical” android:layout_width=”fill_parent”
rios podemos colocar entonces dentro de los android:layout_height=”fill_parent”>
<TableRow>
layouts? Aquí hay algunos ejemplos: <LinearLayout android:orientation=”horizontal”
 TextView: Este elemento básico lo ojea- android:layout_width=”fill_parent”
mos de manera rápida en el artículo ante- android:layout_height=”wrap_content”>
<TextView android:layout_width=”wrap_content”
rior, representa texto. android:layout_height=”wrap_content”
 EditText: Se trata de la simple y común android:text=”@string/titulo”
/>
caja para editar texto. <EditText id=”@+id/titulo”
 Button: Añade un botón al formulario. android:layout_width=”wrap_content”
Más adelante veremos cómo adjuntar android:layout_height=”wrap_content”
android:layout_weight=”1”
eventos. />
 ListView: Muestra una lista de elemen- </LinearLayout>
</TableRow>
tos con scroll. <TableRow>
 Gallery: Un listado de imágenes horizontal. <Button id=”@+id/ok”
Podremos colocar cualquiera de estos obje- android:text=”@string/ok”
android:layout_width=”wrap_content”
tos (y más) anidados dentro de los layouts, android:layout_height=”wrap_content”
añadiendo propiedades como las que acaba- />
</TableRow>
mos de ver. Un ejemplo lo tenemos en el lis- </TableLayout>
tado 1, donde vemos varios elementos como
cajas de edición y botones. Una vez tenemos una interfaz de usuario, do objetos y asignándoles un lugar en la pan-
Ahora, cargaremos la interfaz de este archi- veamos cómo añadir eventos a la misma y talla, no habría problema al acceder a los ele-
vo XML en tiempo de ejecución. Se trata del así poder realizar acciones. mentos para añadirles eventos. Sin embargo, al
mismo sistema del artículo anterior: usar en hacer una interfaz de forma declarativa con el
el método “SetContentView” pasándole Los eventos XML vamos a necesitar un paso intermedio.
nuestro archivo XML, accediendo a él a tra- Una interfaz que no es capaz de recibir even- Este paso no es otro que diferenciar el elemen-
vés de la clase de recursos: tos es inservible desde el punto de vista de to que queremos a través de su ID y extraerlo
public void onCreate(Bundle icicle) una aplicación. Por tanto, hacer que la inter- en forma de objeto para manejarlo en código
faz los reciba es tan importante como crearla de programación. Para ello, utilizamos el méto-
{
y hacerla visualmente atractiva y manejable. do “findViewById”. A este método se le pasa un
super.onCreate(icicle); Adjuntar un evento a un elemento de interfaz parámetro que será el ID del elemento desea-
setContentView(R.layout.mi_interfaz); se hace de manera programática. Si creáramos do y nos devolverá un objeto tipo View (al que
} la interfaz de la misma manera, es decir, crean- habrá que hacerle un casting). Una vez obteni-

www.revistasprofesionales.com 19 SOLO PROGRAMADORES nº 158


DISPMOVILES(android) 21/2/08 12:53 Página 20

DISPOSITIVOS MÓVILES

Figura 2. Ciclo de vida de una actividad en Android.

SOLO PROGRAMADORES nº 158 20 www.revistasprofesionales.com


DISPMOVILES(android) 21/2/08 12:53 Página 21

DISPOSITIVOS MÓVILES
Primeros pasos con Android (II)

LISTADO 2 Añadiendo código de eventos el momento de hacer el almacenamiento a


memoria secundaria de los datos en memo-
protected void onCreate(Bundle icicle)
{ ria, ya que el sistema puede terminar esta
super.onCreate(icicle); actividad pausada si se ve bajo de recursos.
Button boton = (Button) findViewById(R.id.ok); Si se reactiva pasa al estado “onResume”.
boton.setOnClickListener(
new View.OnClickListener() {  onStop: La actividad deja de ser visible, por-
que otra actividad comienza o se reactiva y
public void onClick(View arg0)
{ queda por encima de ésta. Pasa a segundo
//Código de evento.... plano y, al igual que la anterior, la actividad
} queda en estado candidato a ser destruido
}
); en caso de falta de memoria. Si pasa a pri-
} mer plano entra en estado “onRestart”.
 onDestroy: La aplicación acaba y se des-
do el objeto se pueden añadir eventos a él. Los etc. Quizá para nuestro programa sea necesa- truye, bien porque acaba ella mima o el
eventos más típicos a añadir son: rio guardar ciertos datos que tengamos entre sistema la termina.
 Teclado: A través del método manos o hacer ciertas notificaciones, iniciali- El ciclo de vida de una aplicación siempre
“setKeyListener” se le añade un callback zaciones o destrucciones. parece un tema a tratar una vez se ha inicia-
que se llamará cada vez que se pulse una Para ello, estas clases contienen unos métodos do la materia y se quieren saber conceptos
tecla. Este callback será de la clase que han de sobrescribirse para colocar acciones más avanzados. Sin embargo, es importante
“OnKeyListener”. La forma más típica es específicas que necesitemos en cada uno de tener claros estos conceptos desde el princi-
crear una clase anónima de este tipo y estos cambios de estado. Por ejemplo, cuando pio, para evitar así problemas de comporta-
colocar en ella una implementación del un usuario ejecuta una aplicación y de pronto mientos no deseados. Conocer estos eventos
callback que recibe la tecla. En el ejemplo decide ejecutar otra, la aplicación que estaba y su ciclo desde el principio puede evitar
del listado 2 hay más detalles. ejecutando se para y queda en segundo plano. muchos problemas en el futuro.
 Pulsación en pantalla: Es un clic en la Para enterarnos de este suceso disponemos de El sistema intenta mantener en memoria las acti-
pantalla. El callback se añade con el un método específico en la clase Activity al que vidades el mayor tiempo posible. Sin embargo, si
método “setClickListener” y, de forma se llamará a modo de evento cuando se proce- esto no puede ser así (recordemos que al tratar-
similar al teclado, a través de la clase da a la parada. En ese momento podremos se de dispositivos móviles tenemos memoria
“OnClickListener”. hacer todo lo que necesitemos, si es que nece- muy limitada y a veces los recursos escasean)
 Foco: El evento se recibe al cambiar el foco. sitamos tomar alguna acción específica. hay un orden de prioridades que se usa para
El método para asignar el callback es En general, describiendo un ciclo de vida com- decidir qué actividades destruir primero.
“setOnFocusChangeListener” y a clase del pleto de una actividad, su primer momento es Las actividades más prioritarias son las que
callback es del tipo “OnFocusChangeListener”. la “creación”, donde se crea el entorno y los están actualmente corriendo y ejecutando en
Implementando las clases anónimas como recursos. Más adelante la aplicación “comien- primer plano. Están atendiendo a las interac-
en el ejemplo del listado 2, podemos dar za” y entra en estado de ejecución. Durante ciones con el usuario y son las más importan-
código y comportamiento a la interfaz. esa ejecución puede ocurrir que otra actividad tes para mantener la experiencia de usuario.
tenga que ejecutarse, lo cual hace que la acti- En segundo lugar están las actividades pau-
El ciclo de vida de una actividad vidad actual se “congele” y quede en “pausa”. sadas, que quedan visibles pero tras otros ele-
Mientras está en pausa puede reactivarse, o mentos como cajas de diálogo. También son
Las diferentes actividades a lo largo de su vida dejar de ser “visible” y “destruirse”. Un diagra- consideradas muy importantes puesto que
(es decir, el tiempo en que se están ejecutan- ma explicativo muestra en la figura 2 el ciclo siguen a la vista. En tercer lugar están las apli-
do) sufren cambios de estado. Estos cambios de vida de una manera más visual. caciones en segundo plano, paradas y ocultas
de estado quizá son muy acusados en bloques Para gestionar este ciclo de vida tenemos los a la vista. Si el sistema tiene unas necesidades
de este tipo Activity, ya que al representar la siguientes métodos: muy fuertes de memoria puede decidir des-
pantalla de usuario y depender de la interac-  onCreate: Ocurre cuando la aplicación se truirlas (a fin de cuentas deberíamos encar-
ción con el mismo, han de tener en cuenta crea. Es típico hacer inicializaciones y, garnos de guardar todo lo necesario una vez
ciertos aspectos de manejo de usuario, es como ya hemos visto, crear la interfaz. entremos en pausa). Por último, los menos
decir, ha de tener en cuenta que el usuario (o  onStart: Una vez creada o reactivada, la prioritarios son los procesos que no contienen
el sistema) puede pasar a otra aplicación, aplicación comienza. ninguna actividad u otro componente. El sis-
dejar a esta en segundo plano, recuperarla  onRestart: La aplicación se ha parado y tema los elimina rápidamente en cuanto
tras haberla pausado etc. Estos cambios de comienza de nuevo. queda sin memoria suficiente.
estado han de hacerse de forma controlada, y  onResume: La actividad comienza bien
es necesario que nuestra aplicación se entere por primera vez, o tras haberse pausado. Paso de una actividad a otra:
de los mismos, ya que debe ser consciente en  onFreeze: La aplicación está a punto de actions e intent-filter
todo momento de cuándo se está procesando pausarse.
y en activo, de cuándo está a punto de pau-  onPause: La aplicación se ha pausado. Y Ya hemos hablado que una actividad repre-
sarse la aplicación y pasar a segundo plano, deja de recibir interacción con el usuario. Es senta, más que una aplicación de ventanas,

www.revistasprofesionales.com 21 SOLO PROGRAMADORES nº 158


DISPMOVILES(android) 21/2/08 12:53 Página 22

DISPOSITIVOS MÓVILES

LISTADO 3 Actions e intent-filter declarativa en el manifiesto de la aplicación,


sin necesidad de recompilar el código. Así,
<?xml version=”1.0” encoding=”utf-8”?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android” logramos un sistema parecido al que tienen
package=”com.solop.ejemplo”> los sistemas operativos para elegir el progra-
<application android:icon=”@drawable/icon”> ma más adecuado cuando “hago doble clic
<activity class=”.Prueba” android:label=”@string/app_name”>
<intent-filter> sobre un vídeo”. Si cambio el programa por
<action android:value=”android.intent.action.MAIN” /> defecto para ver vídeos, todo doble clic sobre
<category android:value=”android.intent.category.LAUNCHER” />
</intent-filter> archivos de video comienza a usar la nueva
</activity> aplicación por defecto. Veamos cómo hacer
<activity class=”.NuevoDocumento” android:label=”@string/nuevo”> esto en Android. Una vez creada la actividad,
<intent-filter>
<action android:value=”android.intent.action.EDIT” /> hay que añadirla al manifiesto. En el anterior
<action android:value=”android.intent.action.INSERT” /> artículo vimos ya algo el manifiesto, y en
<category android:value=”android.intent.category.DEFAULT” />
</intent-filter> concreto la acción MAIN (actividad que se
</activity> ejecuta cuando se quiere comenzar a utilizar
</application>
</manifest>
la aplicación). El resto de acciones funcionan
de forma parecida. Para colocar una inten-
ción (intent) en el manifiesto está la etiqueta
LISTADO 4 Callbacks y paso de datos entre actividades
“intent-filter”. Dentro de ella se colocan ani-
private void crearNota() dadas las etiquetas “action” que representan
{
Intent i = new Intent(Intent.INSERT_ACTION); las acciones que realiza la actividad. Acciones
i.putExtra(DATA_ID, 22); pueden ser “android.intent.action.EDIT” para
this.startSubActivity(i, ACTIVITY_CREATE); editar, “android.intent.action.INSERT” para
}
@Override crear o insertar, etc. En el listado 3 tenemos
protected void onActivityResult(int requestCode, int resultCode, String data, Bundle extras) un ejemplo de varias actividades con varias
{
super.onActivityResult(requestCode, resultCode, data, extras); acciones. Además de acciones se pueden
definir otras etiquetas que aporten más
if (requestCode == ACTIVITY_CREATE)
{
datos a la actividad, como el tipo de datos
//Código a ejecutar cuando la actividad asociada a ACTIVITY_CREATE acabe que maneja (y así decir que lo que edita son
} notas) y la categoría a la que pertenece la
}
acción, entre otros.
una única pantalla, de forma general. Aunque intenciones activan esa actividad. Para todo Declarado en el manifiesto qué acciones se
su apariencia pueda cambiar asignándole otra esto entra el juego el manifiesto de la apli- realizan en las actividades, llega el momento
interfaz, lo normal es que para cambiar a otro cación. Este manifiesto, para no romper la de pasar a ejecutar otra actividad y ver su
formulario se cambie a otra actividad distinta. tónica general, es un archivo XML que defi- pantalla, es decir, crear los “intents”. De
Para ello necesitamos saber el proceso que se ne las actividades que contiene la aplicación forma programática, se crea una clase
sigue al realizar el cambio de ventanas. (y que luego serán clases que heredan de “Intent” y se pasa como parámetro la acción
Según el esquema de Android, normalmente Activity). Como información extra, se le que se tiene intención de ejecutar. Más tarde
se cambia de ventana para realizar una añaden las intenciones (intents) y acciones se llama bien al método “startActivity” o
acción nueva. Por poner algunos ejemplos, (actions) que dicen cómo disparar la activi- “startSubActivity”, depende del nivel de
acciones pueden ser crear una nueva nota, dad. De esta manera se muestran las panta- jerarquía que deseemos tener. A esos méto-
editar un contacto, borrar un mensaje, coger llas. No se “crean” y se “ponen visibles” dos se le pasa el Intent que hemos creado,
información de un elemento de una lista, directamente, sino que se crea la intención de esta manera:
etc. Lo que hace que realicemos nuestras de hacer una acción y eso hace que la acti- Ejecución de una sub-actividad
acciones es la intención de realizarlas. Esto vidad se ponga en marcha, sacando su res-
Intent i = new Intent(Intent.INSERT_ACTION);
que parece tan obvio es la base para el fun- pectiva pantalla.
cionamiento de los bloques en el esquema Es un concepto quizá algo nuevo y bastante this.startSubActivity(i);
Android. Por decirlo de una manera, una diferente al mecanismo al que estamos acos- Esta es la manera más sencilla. El sistema se
actividad se crea para realizar una acción, y tumbrados de “crear ventana” y “poner ven- encarga de buscar la actividad que por
esa actividad se dispara al tener la intención tana visible”, pero nos daremos pronto cuen- defecto realiza esa acción y ejecutarla.
de realizar la acción. Al pulsar un botón ta de la enorme flexibilidad de esto. En mi Nuestra actividad quedará pausada por
demuestro mi intención de realizar una aplicación no tengo por qué mandar a una debajo de la pantalla de la nueva actividad.
acción de crear una nota, esa intención de actividad concreta activarse, sólo decir que Sin embargo, este método tiene una gran
realizar la acción es la que dispara la activi- “quiero crear una nota”. Si el día de mañana limitación, y es que no tenemos ningún con-
dad de crear notas. decido cambiar la actividad por defecto que trol sobre cuándo retornamos de la otra acti-
Dicho esto, dentro de este contexto necesi- quiero utilizar para “crear una nota”, mi acti- vidad ni tampoco enviamos ni recibimos los
tamos una forma de definir una actividad, vidad no tiene por qué enterarse. Lo mejor es datos que queremos comunicar entre activi-
decir qué acciones realiza y declarar qué que incluso esto puede hacerse de forma dades. Para el primer problema crearemos un

SOLO PROGRAMADORES nº 158 22 www.revistasprofesionales.com


DISPMOVILES(android) 21/2/08 12:53 Página 23

DISPOSITIVOS MÓVILES
Primeros pasos con Android (II)

callback y para el segundo, vamos a ver una sus métodos “onCreate”, “onStart” etc. Se les tos eventos que ocurran en el teléfono,
forma de pasar datos extra a las actividades. llama de la misma forma que a una activi- como que se reciba una llamada, llegue un
Esto se ve claramente en el listado 4. dad: a través de un Intent, con lo que ten- SMS o llegue una cierta hora. En lugar de
Como se ve en el listado, crear el callback es drán que estar también descritos en el mani- hacer un código que continuamente com-
sencillo, ya que sólo hay que sobrescribir el fiesto a través de la etiqueta “service” y sus pruebe si el evento se ha producido, se deja
método “onActivityResult” que viene en toda correspondientes acciones. Entran en ejecu- el código “almacenado” y se activa cuando
clase “Activity”. Este es el punto de entrada ción de la siguiente manera: el evento de interés se produzca. No tienen
de toda actividad que termina, y la diferen- Intent i = new Intent(Intent.INSERT_ interfaz de usuario asociada, pero al igual
ciaremos gracias al parámetro ACTION); que los servicios, pueden utilizar el
“requestCode”. El parámetro “resultCode” y el startService(i);
NotificationManager.
parámetro “data” nos los pasa la actividad Aunque pueden registrarse de forma pro-
que ha finalizado (a través del método El método “stopService(Intent)” lo para (o gramática (usando métodos como
“setResult(int code, string data)”). El paráme- “stopSelf” si estamos dentro del código del pro- “Context.registerReceiver”), lo ideal es
tro “extras” sirve para recoger datos extra. pio service) y para conseguir una referencia al registrarlos en el manifiesto. Se registran
En el momento de llamar a la actividad, al servicio en ejecución utilizaremos el método de la forma usual: con un intent-filter y
método “startSubActvity” se le pasa un pará- “bindService(Intent)”. Este último método crea unas acciones, esta vez dentro de una eti-
metro extra que actúa de identificador, y que una conexión entre el servicio y el que llama a la queta “receiver”. La clase que ejecute el
luego se retornará en el callback en forma función. El servicio se mantendrá activo mien- código heredará de “IntentReceiver”. Esta
del parámetro requestCode. Para añadir tras se haya empezado su ejecución o mientras clase tiene un método que ha de sobrescri-
datos extra, se utiliza el método “putExtra” existan conexiones a él. Si una actividad está en birse:
de la clase “Intent”, donde se añade un iden- estado visible y con máxima prioridad y además @Override
tificador del extra y el dato en sí. tiene una conexión a un servicio, el servicio pasa
public void onReceiveIntent (Context
Por último, es posible forzar la ejecución de a su vez a tener una prioridad alta.
c, Intent i)
una actividad concreta que deseemos en
{
lugar de dejar al sistema que busque la acti- Notificaciones
vidad por defecto. Se hace de la siguiente Los servicios que no están ligados a una inter- Super.onReceiveIntent(c, i);
manera: faz de usuario tienen su forma de notificar a //…
Intent i = new Intent(Intent.INSERT_ la propia interfaz del sistema de eventos que
}
ACTION, ActividadConcreta.class); ocurran en ellos. Para ello utilizan las notifica-
this.startSubActivity(i);
ciones, que son mensajes que salen de forma Ahí es donde podremos colocar el código
flotante para notificar mensajes y tras un deseado. Es importante señalar que este
Servicios tiempo desaparecen, todo ello de forma asín- código tiene que ser síncrono y no puede
crona mientras la interacción ocurre en otra recibir callbacks. También es importante
En numerosas ocasiones es necesario ejecutar parte. Tienen varias formas de aparecer: señalar que hay que tener especial cuidado
un código que no está de ninguna manera  Un objeto “View” que se muestra de si se registran Intent Receivers en los méto-
ligado a una interfaz de usuario. Por ello, no forma temporal, el más común y más dos de pausa de una actividad. Si se regis-
tiene ningún sentido crear una actividad, sólo parecido a las notificaciones de Windows tra en el método “onPause()” debe desregis-
sería necesario el propio código. Un opción o Linux. trarse en el “onResume()”. No es aconsejable
incorrecta en la que suele pensar es arrancar  Un icono que se muestra en la barra de desregistrar un Intent Receiver en el méto-
un Thread aparte una vez comienza la activi- tareas esperando a que se pulse para do “onFreeze()”.
dad (por ejemplo en el método “onCreate”). mostrar el mensaje. Es posible también provocar un Intent con-
Esto es incorrecto y da lugar a que el thread  Pilotos luminosos que se encienden en el creto desde la propia aplicación para arran-
finalice de forma repentina en cuanto la acti- dispositivo. car el Intent Receiver deseado, a través del
vidad acaba. Recordemos que al ver el ciclo de  Alertas en forma de pitidos, vibraciones o método “Context.broadcastIntent(Intent)”.
vida de una actividad, había momentos en los luz de la pantalla.
que el sistema podía decidir destruirla por Para mostrarse se utiliza la clase Conclusión
necesidades urgentes, o simplemente porque “NotificaitionManager” y sus métodos
la actividad acababa por su cuenta. En esos “notifyWithView” o “notifyWithText”. Se le En este artículo hemos visto algo más en
momentos se destruye tanto la actividad pasan parámetros como un identificador detalle cómo crear interfaces gráficas,
como los Threads que haya arrancado. Un hilo único de notificación, elemento View a mos- eventos y varios tipos de bloques. Hemos
de ejecución no tiene suficiente entidad por él trar o mensaje de texto que debe aparecer, descubierto un paradigma novedoso en
mismo como para seguir con vida una vez duración o gravedad del mensaje, entre otros. cuanto a cambio de ventanas y uso de
finaliza la actividad que lo arrancó. Para estas formularios para tareas específicas en
situaciones Android y su esquema de bloques Intent Receivers lugar de sólo para una aplicación.
tienen un elemento especial llamado servicio. Android es muy novedoso en muchos
Los servicios heredan de la clase “Service” y Los Intent Receivers son códigos que que- aspectos, veremos más aún en el siguien-
tienen de la misma forma que una actividad remos que ejecuten como respuesta a cier- te artículo.

www.revistasprofesionales.com 23 SOLO PROGRAMADORES nº 158


DISPMOVILES(py) 21/2/08 12:57 Página 24

DISPOSITIVOS MÓVILES

Desarrollo de aplicaciones
con pyS60
PEDRO PLEGUEZUELOS LEDESMA que las aplicaciones para las dos versiones ante-
riores y la tercera son incompatibles. Es decir, una
PyS60 es una versión de Python aplicación desarrollada para la plataforma S60v2
ideada para dispositivos móviles no funcionará en un dispositivo con plataforma
S60v3. Esto es debido a que S60v3 trabaja sobre
con sistema operativo Symbian y una nueva versión de Symbian (v9.1).
de tipo Serie 60. Este lenguaje nos El objetivo de este artículo será presentar un
ofrece grandes posibilidades a la camino para desarrollar aplicaciones sobre dispo-
sitivos móviles con plataforma S60v3. Para ello
hora de desarrollar aplicaciones usaremos una versión del lenguaje Python adap-
bajo esa plataforma. Con muy tada a este tipo de plataformas llamada pyS60.
pocas líneas de código es posible
crear aplicaciones realmente
funcionales accediendo a todos los
servicios que el dispositivo móvil
ofrece.

Introducción
Por todos es sabido que un sistema operativo es la
capa de software que envuelve y oculta las pecu- Figura 1. Diagrama de capas.
liaridades del funcionamiento del hardware.
Gracias a esta capa de software no es necesario Python para Serie 60
saber con exactitud la arquitectura de la máquina
que estamos programando. Sería realmente Python es un lenguaje de programación interpre-
tedioso programar una aplicación para una tado de propósito general y multiparadigma. Esto
máquina sin sistema operativo. significa que puede usarse para crear programas
Algunos terminales móviles de última generación siguiendo múltiples filosofías: orientados a objetos
ya disponen de sistema operativo incorporado. Por o estructurados, entre otros. Fue creado por Guido
ejemplo, tenemos Windows Mobile, Palm OS o Van Rossum, científico de computación holandés.
Symbian OS, nacido este último para competir con Su objetivo era crear un lenguaje sobre todo de
los dos anteriores. Symbian soporta actualmente fácil lectura y uso. En el argot, suele decirse que un
cuatro tipos de dispositivos móviles: Serie 60, Serie código es “Pythonico” si sigue esos ideales.
80, Serie 90 y UIQ. La más usada es la plataforma De ahora en adelante supondremos que el lector
Serie 60, principalmente por la marca finlandesa está familiarizado con el lenguaje Python y nos
Nokia. Estas plataformas consisten en un conjunto centraremos en las particularidades de Python
de librerías destinadas a facilitar el acceso a las sobre la plataforma S60. En el sitio oficial de
diversas funcionalidades del dispositivo como por Python el lector podrá encontrar un interesante
ejemplo funciones propias de telefonía, herramien- tutorial para iniciarse en este lenguaje:
tas de gestión personal o reproductores multime- http://docs.python.org/tut/.
dia. Una de las principales características de los ter- Python para la plataforma S60 (pyS60) es una
Material adicional minales S60 es que pueden soportar aplicaciones versión modificada de la versión 2.2.2. de Python
El material complementario puede Java MIDP 2.0, Symbian, C++, Flash o Python. adaptada para su uso en dispositivos móviles. A
ser descargado desde nuestra web Actualmente la plataforma S60 se encuentra en fecha de edición de este artículo, la última versión
www.revistasprofesionales.com su tercera edición (S60v3). Es importante señalar de pyS60 es la 1.4.1 Final.

SOLO PROGRAMADORES nº 158 24 www.revistasprofesionales.com


DISPMOVILES(py) 21/2/08 12:57 Página 25

DISPOSITIVOS MÓVILES
Desarrollo de aplicaciones con pyS60

LISTADO 1 Programa básico: una calculadora


import e32
import appuifw

class calculadora(object):

#Constructor
def __init__(self):

#Creamos un objeto activo


self.__lock = e32.Ao_lock()
#Especificamos el tamaño de la pantalla
Figura 2. Sitio oficial de Python. appuifw.app.screen=’normal’
#Título
Instalación de pyS60 appuifw.app.title = u’Calculadora básica’
#Cuerpo
en el dispositivo móvil appuifw.app.body = appuifw.Text(u’Programa básico’)
El desarrollo y las pruebas relativas a este self.__cuerpo_principal = appuifw.app.body
#Botón izquierdo
artículo han sido realizadas usando un dis- appuifw.app.menu = [(u’Sumar’, lambda:self.__sumar()),
positivo móvil de marca Nokia, modelo 5500. (u’Restar’, lambda:self.__restar()),
Veamos a continuación qué necesitamos (u’Multiplicar’, lambda:self.__multiplicar()),
(u’Dividir’, lambda:self.__dividir()),
para instalar PyS60 en un dispositivo móvil (u’Salir’, lambda:self.__lock.signal)]
con plataforma S60v3: self.__menu_principal = appuifw.app.menu
#Botón derecho
 En primer lugar, el intérprete de Python, las appuifw.app.exit_key_handler = lambda:self.__lock.signal()
librerías necesarias y la interfaz con la pla- #El objeto activo espera que se produzca un evento
taforma S60. Todo esto está englobado en self.__lock.wait()
el fichero “PythonForS60_1_4_1_3rdEd.sis”. def __sumar(self):
Es importante decir que cuando se instala a = appuifw.query(u’Valor de A:’,’number’)
b = appuifw.query(u’Valor de B:’,’number’)
esta aplicación no aparece en el menú de appuifw.note(u”Resultado: “ + unicode(int(a + b)))
aplicaciones como un icono.
 Por último, la aplicación para ejecutar los pro- def __restar(self):
a = appuifw.query(u’Valor de A:’,’number’)
gramas. Esto lo obtendremos al instalar el b = appuifw.query(u’Valor de B:’,’number’)
fichero “PythonScriptShell_1_4_1_3rdEd.sis”. appuifw.note(u”Resultado: “ + unicode(int(a - b)))
Una vez instalado ya aparecerá en el menú def __multiplicar(self):
correspondiente de nuestro dispositivo móvil a = appuifw.query(u’Valor de A:’,’number’)
b = appuifw.query(u’Valor de B:’,’number’)
la aplicación intérprete de Python. appuifw.note(u”Resultado: “ + unicode(int(a * b)))
Estos ficheros pueden ser descargados desde
la página del proyecto pyS60 alojado en el def __dividir(self):
a = appuifw.query(u’Valor de A:’,’number’)
sitio http://sourceforge.net/projects/pys60 b = appuifw.query(u’Valor de B:’,’number’)
Para instalar estos ficheros bastará con appuifw.note(u”Resultado: “ + unicode(int(a / b)))
conectar el dispositivo móvil a un PC con la
aplicación Nokia PC Suite instalada o simi- if __name__ == ‘__main__’:
lar, dependiendo del dispositivo.
calculadora()

Interfaz de usuario de un programa pyS60


Si estamos acostumbrados a usar un teléfono
móvil sabremos que por lo general una aplica-
ción tiene un título en la parte superior de la
pantalla y dos opciones disponibles cada una
encima de los botones derecho e izquierdo.
Estamos hablando de lo que se llama interfaz
de usuario. PyS60 proporciona un módulo lla-
mado appuiwf destinado a la programación
de la interfaz. Así, podemos establecer un títu-
lo a la aplicación, un cuerpo y una funcionali-
dad para cada uno de los dos botones, llama-
dos softkeys. El contenido del cuerpo puede
ser un objeto de la clase “Text”, de la clase
“Listbox” o de la clase “Canvas”. Dependiendo
de la naturaleza de nuestra aplicación elegire-
mos el cuerpo más conveniente.
Figura 3. Áreas programables de la pantalla.

www.revistasprofesionales.com 25 SOLO PROGRAMADORES nº 158


DISPMOVILES(py) 21/2/08 12:57 Página 26

DISPOSITIVOS MÓVILES

TABLA 1: Algunos módulos de PyS60 te un emulador en el PC o directamente


e32 Utilidades relacionadas con el SO Symbian copiando el fichero fuente al dispositivo
sysinfo Acceso a la información del sistema: batería, imei, versión, etc. móvil y ejecutándolo desde la aplicación
appuifw Funciones para la creación de la interfaz de usuario. Python. En el desarrollo de este artículo se
graphics Funciones gráficas: líneas, puntos, colores, etc. ha usado la segunda opción.
camera Acceso a la video cámara del dispositivo: fotos y video.
keycapture Control de las teclas del dispositivo. Cómo crear una aplicación standalone
sensor Acceso al acelerómetro (depende del dispositivo).
audio Reproducción y grabación de sonidos.
Hasta ahora para ejecutar nuestros progra-
telephone Realización de llamadas, colgar, descolgar, etc.
messaging Envío y recepción de SMS y MMS. mas pyS60 necesitábamos entrar en la apli-
location Información GSM: celda, red, operador, etc. cación Python de nuestro dispositivo móvil,
contacts Acceso a los contactos almacenados en la memoria. que previamente tendríamos que haber ins-
calendar Acceso al calendario. talado, seleccionar la opción “Run Script” y a
e32db Creación y uso de bases de datos y acceso mediante SQL. continuación el programa fuente deseado.
Esto puede llegar a ser engorroso si frecuen-
Para el diálogo con el usuario, appuiwf pro- f = file(‘E:\\Sounds\\Digital\\sonido temente utilizamos ese programa.
porciona varias funciones: note, para mostrar .wav’, ‘r’) Hay una manera de solucionar este inconve-
brevemente un mensaje en la pantalla; query, mysound = f.read() niente: crear una aplicación standalone.
para solicitar al usuario la entrada de alguna f.close() ¿Qué significa esto? Significa que para acce-
información; multi_query, similar a la anterior der a nuestra aplicación bastaría con entrar
función, pero con más de una solicitud; selec- Programa que realiza una fotografía: en el escritorio (o lugar donde estén alojadas
tion_list, para solicitar al usuario la elección de import camera las aplicaciones en nuestro dispositivo
una opción entre una lista de ellas; etc ... móvil), seleccionar la aplicación y ejecutarla.
foto = camera.take_photo()
Los softkeys son los dos botones, izquierdo y Para crear una aplicación standalone, a
derecho que un dispositivo móvil tiene bajo foto.save(“E:\\Images\\captura.jpg”) partir de un código fuente pyS60, tenemos
la pantalla. El izquierdo se usa para aceptar Programa que lee (literalmente) un texto varias posibilidades. En este artículo vere-
(OK) o para seleccionar una opción de un introducido: mos una manera bastante sencilla. Para ello
menú. El de la derecha para salir (Exit). El import appuifw, audio usaremos un programa realizado en Python
módulo appuiwf nos permite establecer el llamado Ensymble. Veamos en primer lugar
texto = appuifw.query(u”Escribe una
menú que se mostrará al presionar el botón qué necesitamos y posteriormente cómo
palabra:”, “text”)
izquierdo y la función a ejecutar para cada crear un paquete de instalación Symbian
audio.say(texto)
una de las opciones. Por otra parte también (SIS):
nos permite programar el evento del botón Programa que envía un mensaje:  Es necesario instalar Python en el PC.
derecho o de salida, definiendo para ello el import messaging Para la realización de este artículo se ha
atributo “exit_key_handler”. usado la versión 2.5. Se puede obtener
numero = u’652111000’
desde la siguiente dirección: http://
Posibilidades de pyS60: mensaje = u’Hola mundo’ www.python.org/download/
algunos ejemplos útiles messaging.sms_send(numero, mensaje)  A continuación necesitamos el programa
Como ya hemos venido diciendo, pyS60 nos Ensymble. Lo podemos descargar desde la
proporciona un camino sencillo para acceder Pinta un rectángulo negro en la pantalla: URL: http://www.nbl.fi/~nbl928/ens-
a casi todas las funcionalidades de nuestro import appuifw ymble.html. Esta aplicación se trata de un
dispositivo móvil: interfaz de usuario, cáma- fichero .py, el cual será ejecutado median-
import e32
ra, envío de mensajes, reproductor de soni- te Python, instalado en el paso anterior.
do, etc. import graphics  Por último, y como requerimiento de
Veamos a continuación algunos trozos de c = appuifw.Canvas() Ensymble necesitaremos una aplicación
código que evidencian el gran poder y facili- appuifw.app.body=c OpenSSL junto con unas DLL específicas.
dad de este lenguaje. Estos ficheros se encuentran en el mate-
draw = graphics.Draw(c)
Programa que pregunta una palabra y la rial complementario que acompaña a la
imprime: c.rectangle((0,0,176,208), fill = 0x000000) edición en papel de la revista.
import appuifw Para más información recomiendo al lector Una vez que tenemos estos elementos insta-
leer la documentación de PyS60. Esta puede lados en el PC deberán seguirse los siguien-
def pregunta():
ser obtenida desde la página del proyecto tes pasos:
palabra = appuifw.query(u”Escribe una pyS60.  Copiar la aplicación OpenSSL y las DLL en
palabra”, “text”) appuifw.note(u”La una carpeta, la cual añadiremos a la
palabra escrita fue: “ + str(palabra))
Cómo probar un programa pyS60 variable PATH del sistema.
pregunta() Existen varias maneras de probar un progra-  Llevar a la carpeta donde está instalado
Programa que reproduce un sonido: ma pyS60. Las dos más usuales son median- Python el archivo ensymble, el programa

SOLO PROGRAMADORES nº 158 26 www.revistasprofesionales.com


DISPMOVILES(py) 21/2/08 12:57 Página 27

DISPOSITIVOS MÓVILES
Desarrollo de aplicaciones con pyS60

Figura 5. Aspecto de la aplicación


pyTareas.
Figura 4. Creación del paquete instalable Symbian.
Si lo que queremos son programas realiza-
que queremos procesar y opcionalmente Por último está la fase de Organización y dos en pyS60 la siguiente dirección es de
un icono en formato svg el cual aparece- Realización. Esta consiste en ir revisando obligada visita: http://wiki.opensource.nokia.
rá en el escritorio del dispositivo móvil cada uno de los contenedores secundarios, com/projects/PyS60_applications.
junto al nombre de nuestra aplicación. moviendo tareas de unos a otros, o elimi- Centenares de aplicaciones nos esperan.
 Por último, ejecutar el siguiente comando nando tareas si ya están realizadas. Desde el archiconocido Tetris hasta un pro-
desde la ubicación anterior: La aplicación proporcionada con este artícu- grama para controlar el PC vía Bluetooth,
python.exe ensymble.py py2sis —uid= lo (pyTareas) está basada en esta filosofía pasando por un algoritmo para calcular los
0xe6bef15f —icon=icono.svg —appname= aunque en una versión más simplificada. dígitos del número Pi. Y todos con el código
”pyTareas” —shortcaption= ”pyTareas” Dejo en manos del lector su perfecciona- fuente a la vista, como buen lenguaje inter-
—caption=”pyTareas” —version= 1.0.0 miento así como el desarrollo de nuevas pretado que es Python.
—verbose pyTareas.py funcionalidades. Por ejemplo, una buena Por último el sitio oficial de la plataforma
Ensymble tiene varios comandos, entre ellos práctica sería añadir una nueva opción en el S60: http://www.s60.com Esta página web
el que hemos usado, py2sis, para empaque- menú principal para filtrar tareas según su nos ofrece información de los dispositivos
tar programas pyS60 y sus ficheros auxilia- contexto (Trabajo, Ocio, Casa, etc..). móviles que llevan la plataforma además de
res en un paquete de instalación Symbian. Se proporcionan tanto el archivo fuente .py, aplicaciones tanto freeware como sharewa-
ejecutable desde la aplicación Python del re para ella.
Un ejemplo completo: pyTareas dispositivo móvil, así como el instalable .sis,
generado con Ensymble como ya se explicó Conclusiones
El sistema o filosofía GTD (Getting Things en el apartado anterior. Decir que es nece-
Done) tiene como objetivo principal sacar sario instalar el paquete SIS en la memoria En este artículo hemos aprendido una
todas las tareas pendientes de nuestra interna del dispositivo, no en una tarjeta manera de realizar aplicaciones para dispo-
cabeza y centralizarlas en lo que denomina externa. sitivos móviles con sistema operativo
cubo o contenedor inicial. A este proceso, el Symbian y plataforma Serie 60. Gracias a
sistema GTD lo llama Recolección de ideas. Referencias en la web una versión adaptada de Python es posible
¿Por qué hacer esto? En teoría, de esta conseguirlo. Con un lenguaje de fácil lectu-
manera no viviríamos tensionados debido a En Internet, como casi de cualquier tema ra y a su vez con unas librerías que nos pro-
las tareas que tenemos pendientes hacer, al imaginable, es posible encontrar multitud de porcionan acceso a casi todas las funciona-
despreocuparnos por tenerlas apuntadas, y información sobre pyS60. Basta con “google- lidades del teléfono podemos crear fácil y
así poder alcanzar un mayor grado de rela- ar” un poco. Sin duda alguna, uno de los rápidamente aplicaciones funcionales y úti-
jación. En definitiva, el sistema GTD de tutoriales más completos lo podemos encon- les. Hemos visto los principales módulos
David Allen busca liberarnos un poco más trar en el sitio http://www.mobilenin.com/ que conforman pyS60 así como la estructu-
del estrés. pys60/menu.htm de Jürgen Scheible. Allí ra básica de sus programas. Por último
La siguiente fase se denomina Procesamiento podemos obtener un sin fin de ejemplos hemos aprendido a crear paquetes instala-
de tareas. Consiste en ir clasificando las tare- comentados, tocando cada una de las fun- bles de Symbian (SIS) para así distribuir más
as del contenedor inicial e irlas encauzando cionalidades accesibles con pyS60. fácilmente nuestras aplicaciones. Un ejem-
en los correspondientes contenedores, en También podemos encontrar muchos trozos plo completo ha sido proporcionado junto
función de la urgencia que precisen. Por de código, o también llamados “snippets” en con el artículo. Se trata de pyTareas, un ges-
ejemplo, podemos tener el contenedor la dirección http://snippets.dzone.com/ tor de tareas basado en la filosofía GTD de
“Próximas tareas”, “Algún día/Quizá”, tag/pys60. Serán de gran utilidad para no David Allen, al que invito al lector a perfec-
“Delegadas”, “Tareas completadas”. tener que reinventar la rueda. cionarlo con nuevas funcionalidades.

www.revistasprofesionales.com 27 SOLO PROGRAMADORES nº 158


MIDDLEWARE(linq) 21/2/08 13:07 Página 28

MIDDLEWARE

LINQ para SQL (y II)


ERICH BÜHLER Justamente la semana pasada discutía con un
colega sobre el rumbo que Microsoft está
LINQ para SQL es el tercer integrante tomando en sus productos y tecnologías; él me
de las tecnologías LINQ. Los otros decía que no pensaba usarlas pese a que ellas
dos, LINQ para Objetos y LINQ para brindasen un beneficio real a sus clientes, ya que
eran propiedad exclusiva de la “gran empresa”.
XML, fueron tratados en entregas En realidad, quiero hacer una pequeña reflexión
anteriores. LINQ para SQL ofrece la al respecto sobre el valor de un profesional.
Como norma general, siempre debemos estar
infraestructura necesaria para realizar dispuestos a ofrecer soluciones, sin tener en
consultas a bases de datos cuenta la parte emocional, la cual puede jugar-
relacionales, permitiéndonos ver estas nos una muy mala pasada.
No obstante, debes tener claro que utilizar un
bases de datos como si fuesen parte de nuevo paradigma puede traer como consecuencia
la jerarquía de objetos de nuestra nuevos problemas; algo que los desarrolladores
aplicación. En esta segunda y última experimentados tienen siempre en mente.
Es por eso que a la hora de aplicar Microsoft LINQ
entrega, nos sumergiremos de lleno en o alguna de sus variantes, te recomiendo que eva-
las características más avanzadas de la lúes sus beneficios, pero también el impacto a tus
aplicaciones.
tecnología. Sin nada más que decir, quiero recapitular lo que se
ha incluido en los últimos meses, algo que te reco-
Introducción miendo que leas si es que tienes acceso a ediciones
previas de la revista, ya sea en papel o digital:
Si hay algo que debo admitir es que soy totalmen-  LINQ a Objetos (diciembre 2007, número 155)
te culpable de haber escrito una serie de artículos  LINQ a XML (enero 2008, número 156)
sobre las tecnologías LINQ. Y lo enfatizo de esta  LINQ a Datos, parte I (febrero 2008, número 157)
forma porque sé que una vez que las descubras no LINQ provee entonces la capacidad de ejecutar de
existirá para ti una vuelta atrás, es decir, especifi- forma nativa consultas sobre objetos, mientras que
caciones que antes te resultaban muy complejas LINQ para XML hace lo mismo con elementos con-
ahora serán mucho más sencillas. Adicionalmente, tenidos por documentos XML, y LINQ para SQL con
y como todo proceso evolutivo, el hacer que algo datos de una base de datos. Una gran ventaja es
sea más fácil trae consigo que se encuentren nue- que las distintas tecnologías funcionan de manera
vas soluciones a problemas. muy parecida, lo que hace sencilla la migración de

Material adicional
El material complementario puede
ser descargado desde nuestra web
www.revistasprofesionales.com Figura 1: Archivo DBML y modelo relacional de datos.

SOLO PROGRAMADORES nº 158 28 www.revistasprofesionales.com


MIDDLEWARE(linq) 21/2/08 13:07 Página 29

MIDDLEWARE
LINQ para SQL (y II)

TABLA 1: LINQ para Objetos vs. LINQ para SQL importante es que puedes incluir directa-
Ejemplo de LINQ a Objetos Ejemplo de LINQ a SQL mente en el código una consulta:
var socios = from soc in clubDeportivo.
int[] números = new int[] {0,4,2,8,6}; var facturas =
Socios
var resultado = from n in números from fac in clubDep.Facturas
where soc.Nombre == “Susana”
where n < 5 where fac.Socio.Nombre==”Carlos” select soc;
orderby n select fac;
La variable “socios” almacena la definición de
select n; la consulta, que retornará todos los miem-
bros del club deportivo con el nombre
“Susana”. Para ejecutarla, basta solamente
con acceder a alguna de sus filas, empleando
por ejemplo, la estructura foreach siguiente:
foreach (var soc in socios) {
Console.Write (“Socio = “ + soc.Nombre
+ “, Apellido = “ + soc.Apellido);
}

Es importante que tengas en mente que


ninguna consulta es enviada a la base de
datos hasta que no se trate de leer su con-
tenido. A este comportamiento se le deno-
mina ejecución tardía, y es un concepto
importantísimo a tener en cuenta. En el
anterior código la expresión es transferida y
ejecutada a la base de datos cuando se
llega al comienzo de la cláusula foreach. El
Figura 2. Toda consulta LINQ es traducida a Transact-SQL antes de ser enviada a SQL Server. resultado será una colección de objetos,
donde cada elemento contendrá una fila de
conocimientos de una a otra variante. Fíjate objetos y relación con los tipos enumerados la tabla.
en la tabla 1 y en el siguiente código: es algo que te podrá aportar una base mucho Por otra parte, cuando una consulta es envia-
foreach(int i in resultado) más sólida. No me explayaré nuevamente da a la base de datos, esta es traducida a
Console.WriteLine(i); sobre ello ya que me encargué de explicar Transact-SQL antes de ser ejecutada en SQL
todo esto en el número 155, correspondien- server. De acuerdo a Microsoft, los resultados
El resultado en LINQ a objetos es “0,2,4,6,8”, te al pasado mes de diciembre. finales son tan óptimos que a un desarrolla-
mientras que en LINQ para datos consta de dor le costaría escribir algo con la misma
todas las facturas del socio “Carlos”. Observa ¿Qué es LINQ para SQL? calidad (ver figura 2).
la figura 1, la cual contiene el modelo relacio- Si eres curioso, encontrarás en el artículo
nal que podrás encontrar en los ejemplos del LINQ para SQL es una tecnología que se anterior una lista con algunos ejemplos LINQ y
material complementario. Este representa las encuentra dentro del espacio de nombres su respectiva representación de Transact-SQL.
estructuras de tablas y relaciones necesarias “System.Data.Linq”, y que hace posible que
para gestionar un club deportivo. los elementos miembros de una base de De tablas y filas a objetos y métodos
Es decir, hay diferentes versiones de LINQ, y datos puedan ser vistos como clases del
cada una será útil dependiendo de lo que proyecto. Por ejemplo, si cuentas con 2 Visual Studio 2008 ofrece un nuevo tipo de
desees hacer. No obstante, lo más importan- tablas (“Socios” y “Facturas”), entonces ellas archivo, con extensión dbml (ver figura 3),
te es que los lenguajes se han tenido que se mostrarán como miembros de tu aplica- donde las tablas de la base de datos pueden
adaptar, para que todo esto funcione, ción, lo que implícitamente incluirá méto- ser arrastradas, lo que implícitamente crea
mediante la adición de las siguientes 3 fun- dos y propiedades: una clase por tabla.
cionalidades: //Adiciona una factura. Al arrastrar y soltar las tablas, Visual Studio
 Tipos anónimos Socios.Facturas.Add(Factura); lleva adelante las siguientes 3 tareas:
 Extensión de clases 1. Crear un documento XML que describe
 Funciones Lamda Aquí, “Socios” y “Facturas” son objetos que todos los tipos de datos y relaciones entre
Sin ellas, este nuevo mundo sería más una contienen información de tablas del modelo las tablas (clubDeportivo.dbml.layout) y
utopía que una realidad, y digo esto porque relacional. En cambio, “Factura” es un ele- agregar las referencias a LINQ.
la implementación de todas las ediciones de mento que almacena información sobre una 2. Crear una clase por cada tabla, así como
LINQ usan ampliamente estas características. única fila, la que será agregada al momento también clases que representarán la
Por su parte, que comprendas su jerarquía de de invocar el método “Add”. Otra ventaja conexión (clubDeportivo.designer.cs).

www.revistasprofesionales.com 29 SOLO PROGRAMADORES nº 158


MIDDLEWARE(linq) 21/2/08 13:07 Página 30

MIDDLEWARE

Figura 3. El nuevo tipo de archivo ofrecido por Visual Studio 2008 tiene extensión dbml.

3. Almacenar las relaciones entre las dife-


LISTADO 1 Código de la clase socio rentes tablas.
Ten en cuenta que la información de la cone-
using System.Linq;
using System.Data.Linq; xión (servidor, base de datos, etc.) es guardada
using System.Data.Linq.Mapping; en el archivo de configuración del proyecto, y
[Table(Name = “dbo.Socios”)]
se empleará de forma predeterminada la que
public partial class socio tengas en el momento de arrastrar las tablas.
{ Como es de costumbre en mis artículos, iré
private int _Id;
private string _Nombre; más allá mostrándote qué es lo que contie-
private string _Apellido; ne internamente un documento de este
//ETC. (Removí los demás miembros
para que ocupe menos espacio,
tipo, así como la vía que se usa para rela-
pero están incluidos en el fuente) cionar clases y tablas.
[Column(Storage = “_Id”, AutoSync = AutoSync.OnInsert,
DbType = “Int NOT NULL IDENTITY”, Asociación entre clases y datos
IsPrimaryKey = true, IsDbGenerated = true)]
public int Id
{ LINQ a SQL proporciona la infraestructura
get necesaria para gestionar información rela-
{ cional mediante objetos. Aunque podrías
return this._Id;
} usar la técnica detallada anteriormente,
} deseo explicarte más sobre las nuevas
[Column(Storage = “_Nombre”, DbType = “NChar(30) NOT NULL”, estructuras, con el fin de que conozcas lo que
CanBeNull = false)] pasa por detrás. Imagínate que tienes la clase
public string Nombre siguiente, la cual te gustaría que representa-
{
get se información de la tabla “Socios”:
{
partial class socio
return this._Nombre;
} {
}
//ETC. (Removí los demás miembros public int Id;
para que ocupe menos espacio, public string Nombre;
pero están incluidos en el fuente)

SOLO PROGRAMADORES nº 158 30 www.revistasprofesionales.com


MIDDLEWARE(linq) 21/2/08 13:07 Página 31

MIDDLEWARE
LINQ para SQL (y II)

TABLA 2: Algunos parámetros de las etiquetas Table y Column


Nombre de Nombre Descripción Hay varios constructores que aceptan diferen-
la etiqueta del atributo tes parámetros y pueden ser usados para esta-
Table Name Nombre de la tabla en la base de datos. blecer la conexión de distinta forma (en el pró-
CanBeNull Indica si se aceptan valores conteniendo nulos. ximo ejemplo te mostraré cómo emplear uno
DbType Tipo de datos en la base de datos. de ellos). La variable que guarda la tabla se
Especifica si el valor será generado automáticamente declara como un miembro de acceso público
IsDbGenerated por la base de datos (por ejemplo, un valor incremental). de tipo “Table” que representa una colección
IsPrimaryKey Indica si es la clave principal de la tabla. de una o más tablas y sus respectivas filas.
Column Nombre de la propiedad interna donde el valor Ya puedes entonces acceder a los valores cre-
Storage del campo de la base de datos será almacenado.
ando una instancia de la clase que creaste, o
Esta propiedad se emplea para detectar conflictos.
Básicamente se configura mediante un enumerado lo que es mejor aún, escribiendo una consul-
UpdateCheck que hace posible que se genere un error si el valor ta que obtenga un conjunto datos basado en
del campo ha cambiando en la base de datos un criterio personalizado:
mientras el usuario está editando su versión local. clubDb sd = new clubDb(“Data Source=
MI-LAPTOP\\SQLEXPRESS;Initial Catalog=

LISTADO 2 Definición de las tablas a utilizar


ClubDeportivo;Integrated Security=
True;”); var socios = from s in sd.
public class clubDb : DataContext { Socios where s.Nombre==”Susana” select s;
public SampleDb(IDbConnection connection) : base(connection) { }
public SampleDb(string fileOrServerConnection) : base(fileOrServerConnection) { } //Muestra los resultados...
public SampleDb(IDbConnection connection, MappingSource mapping) : base(connection,mapping) { }
foreach (var soc in socios) {
public Table<socio> Socios; Console.WriteLine(soc);
}
}
public string Apellido; dato importante, todas ellas residen en el espa- No está de más decir que para el caso que
public string Teléfono; cio de nombres “System.Data.Linq.Mapping”. tengas más tablas, ellas tendrán que ser
public int IdTipodeMensualidad; La etiqueta “Table” indica el nombre de la declaradas dentro de “DataContext”, lo cual
public DateTime FechaNacimiento; estructura en la base de datos; una aproxima- te permitirá posteriormente accederlas
ción similar se emplea para identificar la mediante expresiones de consulta.
public string Notas;
columna, aunque aquí más datos son reque-
}
ridos. Si prestas atención verás que el tipo de Definición de las relaciones
Aquí los miembros contienen los mismos datos se indica mediante “dbType”, “Storage”
nombres que las columnas de la tabla y sus por su parte establece el nombre de la varia- Como puedes ver en la figura 1, las estructu-
tipos de dato. Por supuesto que estos últi- ble donde guardar la información, ras están vinculadas mediante relaciones
mos son los respectivos a la infraestructu- “isPrimaryKey” configura si el miembro repre- comúnmente llamadas de 1 a N (o muchos)
ra .NET y no los definidos en SQL Server. Ello senta una clave primaria, “isDbGenerated” si o de N (muchos) a 1. Una ventaja de LINQ es
implícitamente quiere decir que por cada su valor es automáticamente generado por la que puede almacenar estas asociaciones, lo
elemento deberás buscar el tipo de datos base de datos, etc. La tabla 2 muestra algunas cual te hará la vida más fácil cuando escribas
más apropiado. de las etiquetas y su uso. las expresiones de consulta.
Hasta aquí no hay nada extraño, más allá de Tomemos por ejemplo la tabla de “Socios” de la
que he definido la clase como parcial, lo que El paso final... establecer la conexión base de datos, que está asociada a
será importante si en el futuro quieres adi- “TiposdeMensualidad” en una relación de N
cionar nuevos miembros sin necesidad de Una vez que declaraste los miembros de la (muchos) por el lado de “Socios” a una fila única
modificar la estructura original. Presta ahora clase y las etiquetas, es necesario un segun- por el lado de “TipodeMensualidad” (usando el
atención al listado 1. do paso, el que configure la conexión y campo clave “IdTipodeMensualidad”).
He cambiado el acceso de los miembros obtenga finalmente los datos de la tabla. Para Es en este momento cuando entra en escena
públicos a privados, para que sean necesaria- ello, tendremos que usar un nuevo integran- el nuevo integrante de LINQ llamado
mente accedidos mediante sus propiedades. te llamado “DataContext”, quien en definitiva “EntityRef”, que permite almacenar la defini-
Esto tiene una explicación importante, que almacena información sobre la conexión y ción de la relación:
radica en que sería posible escribir código alternativamente las tablas disponibles. private EntityRef<TiposdeMensualidad>
personalizado a ser ejecutado cuando se lean Existen varias aproximaciones para llevar _TiposdeMensualidad;
o escriban las mismas. adelante la tarea, pero la más fácil consiste [Association(Storage = “_IdTipodeMensualidad”,
Me imagino que te llamará la atención la utili- en crear una nueva clase que extienda a ThisKey = “IdTipodeMensualidad”,
zación de las etiquetas “Table” y “Column”, que “DataContext”, y que a su vez defina como IsForeignKey = true)]
en realidad le dice al compilador que existe una elementos públicos las distintas tablas a uti-
public TiposdeMensualidad
relación entre los miembros de la clase y una lizar (las cuales fueron previamente defini-
tipoDeMensualidad {
tabla o columna de la base de datos. Como das). Observa el listado 2.

www.revistasprofesionales.com 31 SOLO PROGRAMADORES nº 158


MIDDLEWARE(linq) 21/2/08 13:07 Página 32

MIDDLEWARE

TABLA 3: Clases que representan relaciones en LINQ a Datos


Atributo Uso Hay dos cosas interesantes que quiero desta-
car del código anterior; la primera es que el
Se utiliza cuando se desea establecer una relación de N (muchos) a 1. identificador de socio en la factura es dedu-
Por ejemplo, de “Socios” a “TiposdeMensualidad” (varios socios pertenecen cido automáticamente debido a que existe
EntityRef a un tipo de mensualidad). una relación entre ambas tablas, que LINQ
Otro ejemplo se puede encontrar en la asociación de “ProblemasdeSaludPorSocio” conoce y emplea. La segunda es la utilización
del método “SubmitChanges”, que envía a la
hacia “ProblemasdeSalud”, en “Facturas” hacia “Socios”, etc. base de datos todos los cambios realizados.
Se emplea cuando se desea establecer una relación de 1 a N (1 a Como puedes ver, he obtenido el tipo de
muchos). Por ejemplo, en “TiposdeMensualidad” habrá una relación de mensualidad y precio del socio para poste-
EntitySet este tipo hacia “Socios” (un tipo de mensualidad es utilizada por varios socios). riormente rellenar de forma consistente la
información de la factura. Como característi-
Otro ejemplo se puede encontrar en la asociación de “ProblemasdeSalud” ca adicional, todos los cambios son engloba-
hacia “ProblemasdeSaludPorSocio”, en “Socios” hacia “Facturas”, etc. dos por una transacción, por lo que cualquier
fallo hará que la totalidad de las modificacio-
get { return this._TiposdeMensualidad. Es importante que sepas que para que las nes sean anuladas.
Entity; } clases que escribimos anteriormente pue-
} dan ser de lectura/escritura, es obligatorio Emplear validaciones y lógica de negocio
El código anterior debe ser escrito dentro de realizar algunos cambios, tales como adicio-
la clase “Socios”, y es quien se encarga de nar las interfaces “InotifyPropertyChanging” ¿Qué ocurre si necesitas escribir algunas vali-
mantener la relación y ofrecerla de forma y “INotifyPropertyChanged”, y posterior- daciones que verifiquen la consistencia de la
pública a través de la propiedad mente emplearlas para notificar a LINQ que información ingresada? Cuando digo esto, no
“tipodeMensualidad”. Por su parte, la informa- la información ha cambiado. Debido a que estoy hablando del tipo de datos, sino que
ción de la asociación es configurada por los explicar esto podría llevarme algún tiempo y voy un poco más allá y me refiero a la lógica
parámetros de la etiqueta “Association”, que a espacio de artículo, emplearé el archivo de negocio en sí.
mi parecer no necesita de mayor explicación. DBML previamente generado por Visual Por ejemplo, podríamos escribir una regla
La ventaja de esto se muestra a continuación, Studio, el cual contiene todas las definicio- que especificase que en la factura, el campo
donde automáticamente se obtiene el tipo de nes necesarias. “MesPago” fuese válido solamente si su valor
mensualidad para el socio en cuestión, sin Imagínate que quieres adicionar una nueva estuviese entre 1 y 12:
necesidad de escribir una consulta compleja: factura para un socio. Entonces lo primero public partial class Factura {
var socios = from s in sd.Socio where que debes escribir es la parte que seleccio- partial void OnMesPagoChanging(int
s.Nombre == “Francisco” select new { na el elemento deseado. Una vez hecho value) {
s.tipoDeMensualidad }; esto, tendrás que crear la estructura de tipo
if (value < 1 || value > 12) {
//Retorna toda la información del tipo
cliente, para por último adicionarla al socio
throw new Exception(“El mes pago debe
de mensualidad asociado a este miembro
deseado:
ser un valor comprendido entre 1 y 12”);
del club deportivo. //Obtiene al socio deseado
}}}
foreach (var soc in socios) { var Carlos = cd.Socios.Single(s =>
s.Nombre == “Carlos”);
Debido a que todas las clases del archivo
Console.WriteLine(soc); DBML (generado automáticamente por
//Crea la estructura de factura y
} Visual Studio) son definidas como parciales,
rellena sus datos
También se cuenta con una contrapartida lla-
mada “EntitySet”, que establece una relación Factura f = new Factura();
de 1 a N (1 a muchos). La tabla 3 ofrece una // IdSocio es rellenado automáticamente
descripción más detallada. f.Fecha = DateTime.Now;
f.MesPago = 10;
Modificar y actualizar f.TipodeMensualidad = Carlos.
TiposdeMensualidad.IdTipodeMensualidad;
Modificar información es algo que no es
f.Total = Carlos.TiposdeMensualidad
demasiado complejo pero que tiene algunos
.Precio;
puntos un tanto engañosos, especialmente
los relacionados con conflictos entre versio- // Agrega la factura el cliente (en
nes de información, esto es, cuando dos o memoria)
más usuarios modifican la misma columna al Carlos.Facturas.Add(f);
mismo tiempo. No obstante dejaré temporal- // Envía los cambios a la base de datos
mente este problema para centrarme en Figura 4. LINQ a Datos tiene una
cd.SubmitChanges();
solución más elegante para la solución de
cómo actualizar una fila. conflictos.

SOLO PROGRAMADORES nº 158 32 www.revistasprofesionales.com


MIDDLEWARE(linq) 21/2/08 13:07 Página 33

MIDDLEWARE
LINQ para SQL (y II)

LISTADO 3 Administración de errores resultantes de un conflicto


puede darse si un usuario trabaja con copia o
//Obtiene la fila del socio Juan.
var Juan = cd.Socios.Single(s => s.Nombre == "Juan"); caché privada conteniendo filas, que al
momento de sincronizar con la base de datos
Juan.Apellido = "González"; se descubren como no válidas porque parte
Juan.Notas = "Casado";
de ellas han sido modificadas por otro u
// Envía los cambios a la base de datos otros usuarios.
try
{ La solución no es mágica, y por supuesto que
cd.SubmitChanges(ConflictMode.ContinueOnConflict); dictaminar quién tiene la copia “oficial” no se
} hace mediante el resultado de un partido de
catch (ChangeConflictException)
{ fútbol o una pelea de boxeo con el otro usua-
//Aquí escribiremos el código que maneja la excepción rio, sino que se ofrece a través de alguna de
}
las siguientes 3 opciones:
//Se envian los cambios nuevamente, luego de haber resuelto el conflicto. 1. Anular los cambios del usuario que pro-
cd.SubmitChanges();.
dujo el conflicto y dejar intacta la infor-
mación que está en la base de datos.
es entonces posible extenderlas de forma Yo modifico, tu modificas, 2. Sobrescribir los cambios de la base de
muy sencilla. El código anterior nos muestra todos modificamos datos con la información del usuario que
cómo escribir código para el evento produjo el conflicto.
“OnMesPagoChanging” de “Factura”, que se El conflicto de datos o de concurrencia es 3. Efectuar una mezcla entre los datos en la
ejecutará cada vez que la información sea uno de los problemas de los que quizá se base de datos y los del usuario que produ-
modificada, pero antes de que sea enviada a haya empleado más tinta y papel en los últi- jo el conflicto.
la base de datos. El resultado final será una mos años. Éste se produce cuando dos usua- Cuando se produce un conflicto, la infraes-
excepción para el caso de que el valor no se rios intentan modificar la misma información tructura nos comunicará que esto ha suce-
encuentre en el rango indicado. al mismo tiempo. No obstante, también dido mediante el inicio de una excepción,

TABLA 4: Alternativas del enumerado RefreshMode


Opción del enumerado Descripción Efecto final
Se aprontarán para enviar a la base de datos los
KeepCurrentValues ¡No me importa el resto del mundo!, soy egoísta
cambios del usuario que generó el conflicto,
(alias “El egoista”) y mis datos son los que valen.
sobrescribiendo los valores realizados por otros usuarios.
Soy una persona insegura, y ahora no sé si mis
OverwriteCurrentValues Se anulan los cambios de la copia o búfer privado, y se
datos son los correctos. Dejemos mejor los
(más conocido por “El inseguro”) sobrescriben con los valores actuales de la base de datos.
cambios de los demás usuarios.
Se aprontarán para enviar a la base de datos una mezcla
KeepChanges entre los datos de la base de datos y los cambios del Soy un Hippie, ¡paz y amor en el universo!
(alias “El Hippie”) usuario que generó el conflicto. En caso de que se haya Tus cambios y los míos pueden convivir en una
modificado la misma columna por los dos usuarios, perfecta armonía.
el de este usuario prevalecerá.

LISTADO 4 Resolución del conflicto


//ChangeConclicts contiene una colección con las filas donde se dio un problema de concurrencia
foreach (var conflictos in cd.ChangeConflicts)
{
//En este contexto se tienen los conflictos para una única fila.
Console.WriteLine("Identificador de la fila con conflicto ={0}", ((Socio)conflictos.Object).Id);

//Se recorren todos los conflictos detectados en esta fila; cada entrada del bucle contiene un problema.
foreach (var conflictosPorFila in conflictos.MemberConflicts)
{

//OriginalValue es el valor antes de que se cambiase por los usuarios.


//DatabaseValue es el valor actual en la base de datos.
//CurrentValue es el valor con la moficación realizada por este usuario.
Console.WriteLine("{0}: {1}-{2}-{3}", conflictosPorFila.Member.Name, _
conflictosPorFila.OriginalValue, conflictosPorFila.DatabaseValue, _
conflictosPorFila.CurrentValue);

conflictosPorFila.Resolve(RefreshMode.KeepCurrentValues);
}

www.revistasprofesionales.com 33 SOLO PROGRAMADORES nº 158


MIDDLEWARE(linq) 21/2/08 13:07 Página 34

MIDDLEWARE

Cambios usando KeepCurrentValues Nombre Apellido Notas


Valor original en la base de datos Juan Perez
Cambios a realizar por el usuario 1 Juano Soltero
Cambios que realizó el usuario 2 González Casado

Resultado final Juano Perez Soltero


Prevalecen los cambios del usuario que generó el conflicto.

Cambios usando OverwriteCurrentValues Nombre Apellido Notas


Valor original en la base de datos Juan Perez
Cambios a realizar por el usuario 1 Juano Soltero
Cambios que realizó el usuario 2 González Casado

Resultado final Juan Perez Soltero


Prevalecen los datos existentes en la base de datos.

Cambios usando KeepChanges Nombre Apellido Notas


Valor original en la base de datos Juan Perez
Cambios a realizar por el usuario 1 Juano Soltero
Cambios que realizó el usuario 2 González Casado

Resultado final Juano González Soltero


Se realiza la mezcla entre el usuario 1, usuario 2, y la base de datos.

Figura 5. Un ejemplo para cada caso.

en este caso de tipo “ChangeConflict cionado. Veamos entonces, en el listado 4, lo Para las tablas de la figura 5 consideré un
Exception”. Esta siempre es producida en el que necesitamos para resolver el conflicto. usuario 1 y otro 2, el segundo siempre guar-
momento de sincronizar la copia privada, o La propiedad “ChangeConflicts” del objeto da su copia, mientras que el primero es quien
lo que es igual, cuando se invoca al méto- “cd” (clubDeportivoDataContext) retorna una descubre el conflicto cuando intenta sincro-
do “SubmitChanges”. colección de errores por fila. La segunda nizar sus modificaciones. Como ves, con
Una forma fácil de comprobar alguno de estructura foreach obtiene por cada fila la estas tres opciones puedes resolver todos los
estos escenarios es teniendo más de una ins- lista de conflictos de concurrencia. Si por escenarios, y brindar una solución definitiva
tancia de la aplicación a la vez que conserven ejemplo el usuario 1 modifica el nombre y el al problema de concurrencia.
una variable con una copia local de las filas. apellido del socio y lo mismo hizo el usuario
Presta atención ahora al listado 3, el cual 2, entonces habrán 2 conflictos a resolver Conclusiones
muestra el esqueleto de código LINQ que (“MemberConlicts” retornará 2 elementos).
administra los errores resultantes de un He agregado a su vez algunos comentarios La verdad es que en esta ocasión, una vez
conflicto. en el código para que puedas analizarlo paso más, me he quedado sin espacio para seguir
Como puedes apreciar, el método a paso. La última línea que se encuentra explicándote los secretos de LINQ para SQL.
“SubmitChanges” especifica como parámetro resaltada indica qué hacer. En ella, podemos Tenía en mente mostrarte cómo utilizar pro-
un valor del enumerado “ConflictMode”, que indicar una de las tres alternativas mostradas cedimientos almacenados, lo que brinda una
le dice a LINQ que continúe enviando los en la tabla 4. flexibilidad mayor. No obstante, hay otras
cambios de las filas pese a que se produzcan Se debe llamar a “SubmitChanges” una vez tecnologías que tratar y creo haber cubierto
errores de concurrencia. Esto te permitirá que el método “Resolve” es invocado en las los aspectos más importantes, así como
posteriormente obtener en una colección filas con problemas, ya que es este quien algunos de los avanzados, lo que sin lugar a
toda la lista de problemas. He adicionado un finalmente se encarga de enviar los cambios dudas te dará la posibilidad de seguir reco-
bloque de captura de excepciones en donde a la base de datos. rriendo por tí mismo el mundo LINQ.
escribiré el código para la gestión del conflic- Me imagino que estarás un poco confundido, Como siempre, me despido dejándote un abra-
to. La última línea por su parte reenvía las por lo que en la figura 5 te muestro los cam- zo, recibiendo tus comentarios a través de tus-
modificaciones cuando el asunto se ha solu- bios y resultados para cada caso. [email protected].

SOLO PROGRAMADORES nº 158 34 www.revistasprofesionales.com


49 Suscripcion Digital Solop 21/2/08 13:28 Página 1

Sólo Programadores
en Formato
Digital
Por menos dinero
Llegará antes a su ordenador que a los quioscos
Entre en www.revistasprofesionales.com
Suscripción anual a Sólo Programadores (12 números) por sólo 27 euros
BBDD(4d) 21/2/08 13:12 Página 36

BASES DE DATOS

Caso práctico
con 4D v11 SQL (y III)
desarrolladores, consideramos que cierta funcio-
PABLO OLMOS
nalidad de nuestra base de datos puede ser útil
En la primera entrega de esta serie nos para otros desarrollos, podemos “convertirla” en
componente, y reaprovecharla desde otras bases
centramos en explicar, paso a paso, de datos, integrándola en ellas mediante arras-
cómo crear una base de datos así como trar y soltar.
sus formularios de creación, consulta, En realidad, con el modelo de componentes de
4D v11 SQL, se nos está ofreciendo una potente
modificación y eliminación de datos. herramienta para lleva hasta el límite el concep-
En la segunda entrega entramos de to de desarrollo modular y reutilización de códi-
go, dos conceptos estratégicos en la programa-
lleno en la programación de ción ágil.
funcionalidades mediante escritura A continuación, demostraremos cómo integrar,
directa de código, lo cual nos permitió en nuestra base de datos de ejemplo, un compo-
nente ya desarrollado y probado que permite
comprobar la potencia del lenguaje de gestionar productos. Este componente se llama
4D v11 SQL. En esta última entrega “4D Product Management.4dbase”, y se encuen-
nos centraremos en otros aspectos no tra junto con el material complementario que
acompaña a este artículo.
menos importantes, como puedan ser
la creación y gestión de componentes, Instalación del componente
Para instalar el componente, haremos lo siguiente:
así como la publicación de nuestras  Si tenemos el entorno 4D v11 SQL abierto, lo
bases de datos en la web, o la creación cerraremos.
y consumo de servicios web.  En el sistema de ficheros de nuestro sistema
operativo, si “buceamos” por la estructura de
Componentes: el desarrollo modular de 4D directorios de nuestra base de datos, encontra-
remos un directorio llamado “Components”.
Los lectores que tuvieron la ocasión de tener en Como el lector supondrá, todo componente
sus manos el número 155, correspondiente al integrado en nuestra base de datos tendrá que
pasado mes de diciembre, pudieron leer un com- ubicarse aquí. Entonces, lo que haremos será
pleto artículo dedicado a la creación y gestión de
componentes en 4D v11 SQL. En aquella ocasión,
hicimos hincapié en la instalación de componen-
tes creados por terceros, y además dimos unas
pinceladas de lo necesario para crear nuestros
propios componentes. Sin embargo, si el lector
no tuvo la ocasión de leer dicho artículo, a con-
tinuación haremos un breve repaso, ahora desde
un punto de vista totalmente práctico.
Para quienes no hayan oído nunca hablar de los
componentes de 4D, decir que un componente
Material adicional es una librería de códigos y formularios que
El material complementario puede puede ser incorporada a cualquier base de datos
ser descargado desde nuestra web 4D mediante una sencilla operación de arrastrar Figura 1. El Explorador muestra el
www.revistasprofesionales.com y soltar. Dicho de otra manera: si nosotros, como componente instalado.

SOLO PROGRAMADORES nº 158 36 www.revistasprofesionales.com


BBDD(4d) 21/2/08 13:12 Página 37

BASES DE DATOS
Caso práctico con 4D v11 SQL (y III)

copiar el directorio “4D Product


Management.4dbase” en nuestro directo-
rio “Components”.
 Ahora, abriremos nuestra base de datos
con el entorno 4D v11 SQL.
 Si todo ha ido bien, en la sección “Métodos”
del Explorador, deberíamos ver el compo-
nente instalado (véase la figura 1).
A continuación, crearemos un nuevo método
de proyecto. Recordemos que para crear un
método de proyecto hay que pulsar sobre el
botón en forma de cruz verde que hay en la
parte inferior del Explorador. Este nuevo
método se llamará “PROD_Ini”, y el código
que escribiremos en él será la siguiente invo-
cación a uno de los métodos del nuevo com-
ponente instalado:
Product_Init

Este método, del componente “4D Product Figura 2. Nuestro componente en ejecución.
Management.4dbase”, creará las tablas nece-
sarias mediante SQL.
LISTADO 1 planilla.shtml
<html>
Importación de datos <head>
En el material complementario se han <title>Productos</title>
incluido también dos ficheros de texto: <link rel=”stylesheet” href=”/css/emx_nav_left.css” type=”text/css” />
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”><style type=”text/css”>
“productos.txt” y “categorías.txt”. Si abrimos <!—
estos dos ficheros, observaremos que con- body {
background-image: url(logo.png);
tienen datos susceptibles de ser importados background-repeat: no-repeat;
(a partir de la segunda línea, claro está). A background-color: #FFFFFF;
partir de aquí, será nuestra labor importar }
—>
estos datos, tendiendo en cuenta que: </style></head>
 Los datos del fichero “productos.txt” los <body>
<div align=”center”>
importaremos en la tabla “Prod”. <h1>Título acá</h1>
 Los datos del fichero “categorías.txt” los <table width=”70%” border=”1”>
importaremos en la tabla “Cat”. <!—CUERPO DE LA PÁGINA —>
Para importar estos datos, elegiremos la
opción “Archivo -> “Importar” -> “Desde un </table>
</div>
archivo”. Elegiremos el fichero TXT y, a conti- </body>
nuación, se nos mostrará la ventana de </html>
importación. Esta ventana, nos ofrece una
vista previa o previsualización de cómo los “Products” de la lista desplegable al ele- como búsquedas, adición y modificación de
datos contenidos en el fichero de texto serán mento de menú creado. Este método es un registros (véase la figura 2).
asignados a cada uno de los campos de la método de componente que no podemos
tabla. A continuación, solo tendremos que modificar, sin embargo lo tenemos a nues- Desarrollo web
pulsar en “Importar” para luego pulsar en el tra disposición para usarlo. Por último,
botón “Sí a todo” de la ventana de diálogo marcaremos la opción “Iniciar en nuevo Afortunadamente, el entorno 4D v11 SQL
que nos aparecerá. proceso”. cuenta con un servidor web incorporado, el
cual nos permitirá publicar en la web los
Creación del menú Probando el componente datos de nuestra base de datos, de manera
Ahora, nuestro objetivo será crear un Desde el menú “Ejecutar”, pulsaremos sobre dinámica. La figura 3 nos muestra el cuadro
menú con objeto de listar los productos de “Probar aplicación”. A continuación, iremos de preferencias del servidor web que nos
nuestra base de datos. Para ello, desde el a “Productos” -> “Lista de productos”. Como ofrece 4D.
Editor de Menús, crearemos uno nuevo veremos, se nos mostrará una lista de pro- Veamos ahora cómo publicar el contenido
cuyo nombre será “Productos”. Le añadire- ductos mostrada en un formulario de pro- de nuestra base de datos, concretamente,
mos un elemento llamado “Lista de pro- yecto del componente, en el que podremos nuestra lista de productos. El primer paso
ductos”. Ahora asociaremos el método utilizar funcionalidades preprogramadas consistirá en arrancar el servidor web.

www.revistasprofesionales.com 37 SOLO PROGRAMADORES nº 158


BBDD(4d) 21/2/08 13:12 Página 38

BASES DE DATOS

Figura 3. Preferencias del servidor web de 4D v11 SQL.

Con la etiqueta 4DLOOP haremos un bucle permiten invocar a los métodos de 4D indi-
sobre la tabla “Prod” de la siguiente manera: cados después de “4DACTION/”.
Para ello, haremos clic en “Ejecutar” -> <!—4dloop [Prod]—><tr> En este momento, y después de todos estos
“Arrancar servidor web”. <td><a href=”/4daction/detalles_prod? cambios, nuestro fichero prods.shtml, que
A continuación crearemos un nuevo método id=<!—4dvar [Prod]ProdID—>”><!—4dvar
originalmente era igual que el listado 1,
de proyecto llamado “web_Lista_de_Prods”, [Prod]ProdID—></a></td>
ahora debería ser como el listado 2. Ahora, ya
y en sus propiedades estableceremos solo nos queda comprobar que todo va bien.
<td><!—4dvar [Prod]Name—></td>
“Disponible vía 4DACTION, 4DMETHOD y Para eso, invocaremos a la siguiente URL
4DSCRIPT”. El código que introduciremos en <td><!—4dvar [Prod]Des—></td> desde nuestro navegador web:
este método será el siguiente: <td align=”right”><!—4dvar String([ http://localhost/prods.shtml
ALL RECORDS([Productos]) Prod]Prix;”$ #########,00”)—></td>
</tr> Si todo ha ido como es de esperar, lo que
Hecho esto, es momento ahora de crear el <!—4dendloop—> veremos será algo parecido a la figura 4.
documento HTML que mostrará nuestra Si el lector estudia el contenido del listado 2
lista de productos. Para ello, abriremos el Sobre este ultimo código, solo dos comenta- atentamente, observará que, en el campo
documento “plantilla.shtml” ubicado en el rios. Por un lado, aclarar que la etiqueta identificador de la tabla de productos, hemos
directorio “Carpeta Web” del material com- “4DVAR” sirve para invocar el valor de una escrito el siguiente código:
plementario, y lo guardaremos con otro variable o campo de 4D. Por otro lado, decir <a href=”/4daction/detalles_prod?id=
nombre: “prods.shtml” (véase el listado 1). que los enlaces tipo: <!—4dvar [Prod]ProdID—>”>
Sobre este fichero, haremos los siguientes <a href=”/4DACTION/Metodo_de_proyecto”> <!—4dvar [Prod]ProdID—></a>
cambios.
El título del documento lo pondremos en la
etiqueta “H1”, y será “Productos”.
Con la etiqueta “4DSCRIPT” invocaremos
nuestro método de proyecto recién creado
“web_Lista_de_Prods”:
<!—4dscript/web_Lista_de_Prods—>

Crearemos el encabezado de la lista así


<tr>
<th>ID</th>
<th>Producto</th>
<th>C&oacute;digo</th>
<th>Precio (USD) </th>
</tr> Figura 4. Visualización de nuestros productos desde Firefox.

SOLO PROGRAMADORES nº 158 38 www.revistasprofesionales.com


BBDD(4d) 21/2/08 13:12 Página 39

BASES DE DATOS
Caso práctico con 4D v11 SQL (y III)

LISTADO 2 prods.shtml que tendrá por objeto mostrar los detalles del
<html> producto, para que puedan ser modificados y
<head> enviados al motor de 4D. El listado 3 recoge el
<title>Productos</title>
<link rel=”stylesheet” href=”/css/emx_nav_left.css” type=”text/css” /> contenido íntegro del fichero “edit_prod.shtml”.
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”><style type=”text/css”> Y por fin, crearemos el método de proyecto
<!—
body { “detalles_prod”, estableciendo en sus propie-
background-image: url(logo.png); dades que se aun método “Disponible vía
background-repeat: no-repeat;
background-color: #FFFFFF; 4DACTION, 4DMETHOD y 4DSCRIPT”, y escri-
} biendo en él este código:
—>
</style></head> C_LONGINT(id)
<body>
<div align=”center”> QUERY([Prod];[Prod]ProdID=id)
<h1>Productos</h1> SEND HTML FILE(“edit_prod.shtml”)
<table width=”70%” border=”1”>
<!—4dscript/web_Lista_de_Prods—>
<tr> Llegados a este punto, solo nos queda crear
<th>ID</th> el método de proyecto “edit_producto”.
<th>Producto</th>
<th>C&oacute;digo</th> Como se desprende del estudio del listado 3,
<th>Precio (USD) </th> este método recibirá los datos enviados por
</tr>
<!—4dloop [Prod]—> el formulario y, en base a ellos, tendrá que
<tr> actualizar la información de la tabla “Prods”.
<td><a href=”/4daction/detalles_prod?id=
<!—4dvar [Prod]ProdID—>”> Para conseguir este propósito, marcaremos el
<!—4dvar [Prod]ProdID—></a></td> método como “Disponible vía 4DACTION,
<td><!—4dvar [Prod]Name—></td>
<td><!—4dvar [Prod]Des—></td> 4DMETHOD y 4DSCRIPT”, escribiendo en él
<td align=”right”> este código:
<!—4dvar String([Prod]Prix;”$ #########,00”)—></td>
</tr> QUERY([Prod];[Prod]ProdID=vID)
<!—4dendloop—>
</table> If (Records in selection([Prod])=1)
</div> [Prod]Name:=vProducto
</body>
</html> [Prod]Prix:=vPrecio

Es por ello que en la figura 4 el identificador Ahora, basándonos en el contenido del listado [Prod]Des:=vCodigo
del producto (campo “ID”) aparece de color 1, o lo que es lo mismo, en el contenido del SAVE RECORD([Prod])
azul, como enlace HTML. Ahora, la pregunta fichero “plantilla.shtml”, crearemos el fichero End if SEND HTTP REDIRECT(“/prods.
es: ¿hacia dónde apunta este enlace? Como “edit_prod.shtml” añadiéndole un formulario shtml?r”+String(Random))
hemos comentado antes, la etiqueta “4DAC-
TION” permite invocar un método de 4D. Por
lo tanto, lo que estamos diciendo con el códi-
go anterior es que cuando el usuario haga
clic sobre el valor del campo “ID”, estará invo-
cando al método “detalles_prod”, pasándole
como parámetro el identificador del propio
producto. El objetivo de este método no será
otro que recibir la petición del usuario y mos-
trar una página HTML con los detalles del
producto, para que el propio usuario pueda
visualizarlos y modificarlos. Veamos cómo
conseguir esto.
Como es de suponer, necesitamos poder reci-
bir esta petición desde 4D para poder proce-
sarla. Con objeto de poder manipular las Figura 5. Pantalla de edición de producto.
variables e invocaciones que nos llegan
desde el servidor web, es necesario crear el
método de proyecto “COMPILER_WEB”, con
el siguiente código:
C_LONGINT(id)
C_LONGINT(vID)
C_TEXT(vProducto;vCodigo)
C_REAL(vPrecio)
Figura 6. Iniciando el “Asistente de Servicios Web”.

www.revistasprofesionales.com 39 SOLO PROGRAMADORES nº 158


BBDD(4d) 21/2/08 13:12 Página 40

BASES DE DATOS

LISTADO 3 edit_prods.shtme
Con esto, hemos cerrado ya el círculo. <html>
Ahora, tenemos una página web que mues- <head>
<title>Productos</title>
tra el contenido de nuestra tabla “Prods”. <link rel=”stylesheet” href=”/css/emx_nav_left.css” type=”text/css” />
Además, permite al usuario entrar en los <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”><style type=”text/css”>
<!—
detalles de un producto, modificar sus body {
datos y actualizar así la tabla “Prods”. Con background-image: url(/https/es.scribd.com/logo.png);
background-repeat: no-repeat;
este ejemplo sencillo hemos visto lo fácil background-color: #FFFFFF;
que es hacer un desarrollo web con 4D v11 }
—>
SQL. Evidentemente que lo visto hasta </style></head>
ahora no es más que la punta del iceberg, <body>
<div align=”center”>
ya que 4D v11 SQL es una tecnología pen- <h1>&nbsp;</h1>
sada para ofrecer funcionalidades mucho <h1>Editar producto</h1>
<p>&nbsp;</p>
más ricas y avanzadas, haciendo uso exten- <form action=”/4daction/edit_producto” method=”post”>
sivo de AJAX. <table width=”70%” border=”1”>
<tr>
<td>Producto</td>
4D como cliente de servicios web <td><textarea name=”vProducto” id=”vProducto”>
<!—4dvar [Prod]Name—></textarea>
<input name=”vID” id=”vID” type=”hidden”
En las próximas líneas vamos a comprobar value=”<!—4dvar [Prod]ProdID—>”></td>
</tr>
lo sencillo que puede ser consumir un ser- <tr>
vicio web desde nuestra aplicación 4D. <td>C&oacute;digo</td>
<td><input name=”vCodigo” type=”text” id=”vCodigo”
Concretamente, la funcionalidad que value=”<!—4dvar [Prod]Des—>”></td>
vamos a incorporar a nuestro desarrollo, </tr>
<tr>
vía servicio web, será la de un conversor de <td>Precio</td>
monedas cuyo fichero de descripción de <td><input name=”vPrecio” id=”vPrecio” type=”text”
value=”<!—4dvar [Prod]Prix—>”></td>
servicio se encuentra en: </tr>
<tr>
http://www.webservicex.net/Currency <td>&nbsp;</td>
Convertor.asmx?wsdl <td><input name=”Enviar” type=”submit” id=”Enviar” value=”Enviar”></td>
</tr>
</table>
Lo primero que haremos será abrir el </form>
“Asistente de Servicios Web” que encontra- </div>
</body>
remos en el Explorador, en la sección </html>

“Métodos”. La figura 6 muestra cómo llegar


hasta él. Una vez iniciado dicho asistente,
veremos una ventana similar a la figura 7,
en la que tendremos que indicar que que-
remos descubrir los servicios web publica-
dos en:
http://www.webservicex.net/Currency
Convertor.asmx?wsdl

Además, en el campo “Nombre del método”


introduciremos “proxy_ConvesionMonedas”
y pulsaremos sobre “Crear” para luego hacer
clic en el botón “Cerrar”.
Estando en la sección “Métodos” del
Explorador, comprobaremos que se ha crea-
do automáticamente un método llamado
“proxy_ConversionMonedas”, con un código
idéntico al de la figura 8.
Ahora, para probar nuestro cliente de servicio
web recién generado, crearemos un nuevo
formulario de proyecto, añadiendo en él los
controles necesarios para que tenga el
aspecto de la figura 9. El código que asocia-
Figura 7. Ventana del “Asistente de Servicios Web”. remos a nuestro botón será el siguiente:

SOLO PROGRAMADORES nº 158 40 www.revistasprofesionales.com


BBDD(4d) 21/2/08 13:12 Página 41

WiFiSLAX es una distribución basada principalmente en SLAX (a su vez derivada


de la distribución Slackware Linux), la cual puede ejecutarse como un live CD o
bien transferirse a una llave USB. La característica distintiva de WiFiSLAX es la
gran disponibilidad de drivers y de capacidad de trabajo con la gran mayoría de
los dispositivos WiFi utilizados en la actualidad, de ahí su nombre. Nos ofrece una
gran facilidad de arrancar en un Linux con los drivers y herramientas
correspondientes para llevar a cabo una tarea de auditoría sobre redes WiFi.

Las principales características de


WiFiSLAX 3.1 son:
• Está diseñada y pensada para
facilitar las tareas relacionadas con
la auditoría de redes inalámbricas.
• Provee un entorno de trabajo con
accesos a todas las herramientas de
hacking habituales de los
delincuentes cibernéticos.
• Facilita un live CD e instalaciones en
llaves USB, lo cual, simplifica la
portabilidad de la distribución.
• Provee herramientas para monitorear
y verificar el nivel de facilidad para
espiar e interceptar el tráfico en
redes inalámbricas (sniffing).
• Se distribuye con una gran cantidad
de drivers para la mayoría de las
tarjetas y dispositivos destinados a
la conectividad con redes
inalámbricas. Este punto es
fundamental y es uno de los que más
ha popularizado a WiFiSLAX. Pues,
muchas veces, en algunas
distribuciones de Linux nos
encontramos con la dificultad de la
obtención de los drivers para
determinadas placas o dispositivos,
por parte de los fabricantes, que
parece que todavía no comprenden
que existen millones de usuarios de
un sistema operativo cuyo icono es
un Pingüino y que simplemente
quieren tener la libertad de poder
utilizar sus dispositivos en Linux.
• Puede correr virtualizado, por
ejemplo, en VMWare.
• ¡Está en idioma español!
Por citar algunos ejemplos, incluye los
drivers de las siguientes tarjetas y
dispositivos, muchos de los cuales se
conectan a los buses de expansión PCI
y PCI Express 1x, así como a USB 2.0.
• Chipsets ACX.
• Chipsets RALINK.
• Chipsets RT61.
• IPW2200.
• IPW3945.
• MADWiFi-NG.
• Realtek.
• RT73.
• RTL8187.
• ZYDAS ZD1211RW.
BBDD(4d) 21/2/08 13:12 Página 42

BASES DE DATOS

método seguiremos los pasos habituales.


Desde la sección “Métodos” del
Explorador de 4D v11 SQL crearemos uno
nuevo, cuyo nombre será “WS_Producto_
Precio”, y escribiremos en él este código:
C_TEXT($1;$vCodigoProducto)
C_REAL($0)
$vCodigoProducto:=$1
QUERY([Prod];[Prod]Des=$vCodigoProducto)
If (Records in selection([Prod])=1)
$0:=[Prod]Prix
End if

Figura 8. Código del método “proxy_ConversionMonedas”. Figura 10. Botón ejecutar.


entrada el código de un producto, y devol-
verá su precio.
Como paso previo, nos aseguraremos de
que al arrancar el servidor web propio de
4D v11 SQL, la casilla “Permitir solicitudes
de Servicios Web” esté marcada. Podemos
encontrar esta casilla en la sección
“Servicios Web” de las preferencias del
servidor web (véase la figura 12).
Como el lector supondrá, lo que tendre-
Figura 9. Formulario creado para mos que hacer ahora es crear el método
consumir el servicio web. que implementará el servicio web, es
vTasa:=proxy_ConversionMonedas(vMon1;vMon2) decir, aquél método que atenderá las
Figura 11. Formulario consumiendo el
vUnidad:=vMon2+” / “+vMon1 peticiones entrantes. Para la creación del servicio web.
Para lanzar la ejecución del formulario, solo
tendremos que pulsar sobre el botón ejecu-
tar, simbolizado con una flecha verde, y ubi-
cado en la parte superior izquierda (véase
este botón en la figura 10).
Los códigos de monedas que podemos usar
son los siguientes:
 USD
 EUR
 MXN
 COP
 ARS
 VEB
La figura 11 nos muestra nuestro formulario
en ejecución, consumiendo el servicio web
para obtener el resultado.

4D como servidor de servicios web


Imaginemos ahora que queremos ofrecer a
nuestros clientes un servicio web que les
permita consultar el precio de nuestros
productos. Para ello, publicaremos un servi-
cio web que recibirá como parámetro de Figura 12. Ventana de configuración de los servicios web.

SOLO PROGRAMADORES nº 158 42 www.revistasprofesionales.com


BBDD(4d) 21/2/08 13:12 Página 43

BASES DE DATOS
Caso práctico con 4D v11 SQL (y III)

Figura 13. Ventana de propiedades del método “WS_Producto_Precio”. Figura 14. El fichero WSDL de nuestro servicio web.

Figura 15. El botón


“Compilador”.

Ahora, en las propiedades del método,


marcaremos las opciones “Ofrecido como
Servicio Web” y “Publicado en WSDL”. La
figura 13 muestra cómo debe de quedar la
ventana de propiedades del método.
Llegados a este punto, nuestro servicio
web está creado y listo para ser consumido
por cualquier cliente de servicios web. Si
queremos probar el funcionamiento del
servicio, solo tenemos que crear un cliente
siguiendo los pasos indicados en el punto
anterior.
Por último, indicar que el fichero WSDL de Figura 16. Ventana del compilador de 4D v11 SQL.
nuestro servicio web se encuentra en:
http://localhost/4dwsdl ble con objeto de distribuirla a nuestros
clientes y/o usuarios.
La figura 14 muestra el aspecto de este Como veremos a continuación, antes de
fichero. A modo de conclusión, queremos generar el ejecutable es necesario tanto
destacar que lo visto hasta ahora es solo verificar la sintaxis del código como compi-
una breve pincelada de cómo crear y lar la propia aplicación. Veamos cómo.
publicar un sencillo servicio web. Sin En la barra de herramientas de 4D v11 SQL
embargo, las posibilidades de 4D v11 SQL pulsaremos sobre el botón “Compilador”
en esta materia son mucho más extensas, (véase la figura 15), lo cual nos abrirá la Figura 17. Generando la aplicación.
permitiendo incluso la creación de com- ventana del compilador, que no es otra que
plejos servicios web en los que se envíen y la que se muestra en la figura 16. mos sobre la opción “Generar aplicación”,
reciban múltiples parámetros, de tipos Desde esta ventana, pulsaremos en el botón como se aprecia en la figura 17. Esto pro-
diversos. “Verificar sintaxis”, lo cual nos indicará si vocará la aparición de la ventana de la
hay errores sintácticos en nuestro código. figura 18. En esta ventana podremos espe-
Compilar y crear una aplicación En caso de que así sea, habrá que corregir- cificar todas las características de nuestra
ejecutable los. Si por el contrario no los hay, podremos aplicación. Como vemos en la figura 18,
proceder con el siguiente paso, la compila- tendremos que introducir el nombre de
Por último, y para finalizar no solo este ción. Para ello, pulsaremos como es lógico nuestra aplicación así como la carpeta de
artículo sino la esta serie práctica dedicada en el botón “Compilar”. destino. Por defecto, la primera pestaña
a la nueva versión 4D v11 SQL, explicare- Cuando la aplicación esté compilada, des- que se nos muestra abierta es la
mos cómo generar una aplicación ejecuta- plegaremos el menú “Diseño”, y pulsare- “Estructura compilada”. En esta pestaña

www.revistasprofesionales.com 43 SOLO PROGRAMADORES nº 158


BBDD(4d) 21/2/08 13:12 Página 44

BASES DE DATOS

Figura 20. Aplicación ejecutable


generada por 4D v11 SQL.

Conclusiones
Con estas palabras finalizamos aquí una
serie de tres entregas, con un enfoque
totalmente práctico, y dedicada a la nueva
versión del entorno de desarrollo con base
de datos integrada de 4D: 4D v11 SQL. En
esta serie hemos aprendido a crear una
base de datos desde cero, diseñando su
modelo de datos con el editor de estructu-
ra visual de 4D v11 SQL, hemos creado las
tablas para implementar este modelo de
datos, hemos aprendido también todo lo
Figura 18. Ventana de construcción de la aplicación, pestaña “Estructura compilada”. necesario para crear formularios de con-
sulta, inserción, modificación y eliminación
podremos indicar cuestiones como gene- guntando por la “Ubicación de 4D Volume de datos en nuestras tablas. Además,
rar un componente o bien generar una Desktop”, en realidad lo que se nos está hemos visto cómo enriquecer nuestra base
estructura compilada. pidiendo es el directorio que contiene de datos mediante la programación de
Sin embargo, si abrimos la pestaña todos los archivos necesarios para la procesos y triggers. Además, hemos visto
“Aplicación” (véase esta pestaña en la generación del ejecutable. Si hacemos clic las capacidades de 4D v11 SQL en materia
figura 19), encontraremos los menús y en el botón “Construir”, crearemos por fin de desarrollo modular con la creación y
opciones necesarias para generar una nuestra aplicación ejecutable, que tendrá gestión de componentes. Por último,
aplicación ejecutable. A destacar que, un aspecto como el que se muestra en la hemos comprobado lo fácil que es publicar
cuando en esta ventana se nos está pre- figura 20. el contenido de nuestra base de datos en la
web, así como la creación y consumo de
servicios web. Y como conclusión de la
serie, hemos mostrado cómo empaquetar
nuestra aplicación en un ejecutable.
Esperamos que lo visto hasta ahora haya
resultado de interés y, sobre todo, haya
servido como punto de partida para que el
lector inicie su descubrimiento de la tecno-
logía 4D v11 SQL.

Referencias
Este artículo está completamente basado en
el material creado por 4D Hispano, y pre-
sentado en las sesiones de laboratorio del
evento Software Guru, a finales de 2007. La
información presentada en este artículo
puede ampliarse consultando los siguientes
enlaces:
http://www.4d.com/docs/CMU/CMU02008.HTM
http://www.4d.com/docs/CMU/CMU02070.HTM
http://www.4d.com/docs/V6U/V6U00063.HTM
Figura 19. Ventana de construcción de la aplicación, pestaña “Aplicación”. http://www.4d.com/docs/V6U/V6U00064.HTM

SOLO PROGRAMADORES nº 158 44 www.revistasprofesionales.com


61 atii.qxd 21/2/08 13:30 Página 66
REDES(ajax) 21/2/08 13:16 Página 46

REDES

Slideshow de imágenes con


AJAX, XML y DOM (y III)
ADOLFO ALADRO GARCÍA Los métodos updateTitleLst y updateImgLst
La funcionalidad relativa a la actualización de la
En las entregas anteriores se han lista de títulos de las imágenes, así como la de las
sentado las bases. Ahora es el propias imágenes, se ha encapsulado en dos
métodos del objeto “Slideshow”. El primero se
momento de unir todas las piezas denomina “updateTitleLst” y se encarga de gene-
para dar lugar a una pequeña rar la lista de títulos de las imágenes partiendo del
aplicación web compatible para la objeto JSON recibido desde el servidor.
Primeramente se crea un nuevo array que alma-
mayor parte de los navegadores y cerá los objetos correspondientes a los enlaces.
que está desarrollada utilizando una Después se accede al elemento “<ul>” y se proce-
metodología que facilita su de a borrar los elementos que pudiera contener:
mantenimiento y actualización. var arrLnk = new Array();
var oUl = document.getElementById(“titlelst”);
while(oUl.firstChild) {
Revisión del objeto Slideshow
oUl.removeChild(oUl.firstChild);

Con el fin de completar y mejorar la funcionalidad }


del objeto “Slideshow” es necesario realizar una El siguiente paso consiste en crear un
serie de cambios. El primero de ellos consiste en “DocumentFragment” con la actualización de ele-
modificar el constructor: mentos necesaria. El parámetro o contiene el
function Slideshow(oCon) { objeto JSON devuelto por el servidor. Este objeto
this.oCon = oCon; es un array que debe recorrerse:
this.getImgData(); var doc = document.createDocumentFragment();

this.iSelectedIndex = -1; var iLength = o.length;

}; for(var i=0; i<iLength; i++) {


···
El parámetro que recibe es, como hasta el momen-
to, el objeto correspondiente al elemento HTML res- }
ponsable de la presentación. A diferencia de las ver- En cada iteración del bucle anterior se crea un
siones anteriores ahora el objeto “Slideshow” lanza nuevo enlace cuyo contenido es el título de la
inmediatamente la llamada AJAX que devuelve el imagen. Se prepara la captura del evento clic y
objeto JSON con las imágenes (los títulos, las URL de finalmente se crea el elemento de lista, “<li>”:
las imágenes y sus tamaños). Esta llamada está var oA = document.createElement(“a”);
representada por el método “getImgData”. Por últi- oA.href=”#”;
mo se establece el atributo “iSelectedIndex” indica la
oA.innerHTML = o[i].title;
imagen seleccionada. El valor “-1” se utiliza para
EventUtil.addObjListener(oA, “click”, this,
significar que no hay ninguna imagen seleccionada.
this. clickListener, i);
Cuando la llamada AJAX termina se ejecuta el
método “fire” del objeto “Slideshow”: var oLi = document.createElement(“li”);

fire: function(o) { oLi.appendChild(oA);

this.updateTitleLst(o); doc.appendChild(oLi);

this.updateImgLst(o); arrLnk[arrLnk.length] = oA;

this.selectImg(0);
Obsérvese que en el último paso se añade al array
} el elemento “oA”, es decir, en enlace recién creado.
Material adicional
El material complementario puede Este método realiza tres tareas: actualiza la lista de Luego el valor de “i” es siempre el índice dentro de
ser descargado desde nuestra web imágenes, actualiza las imágenes mismas y final- ese array en el que se encuentra el enlace corres-
www.revistasprofesionales.com mente selecciona la primera imagen de la lista. pondiente a la iteración “i”.

SOLO PROGRAMADORES nº 158 46 www.revistasprofesionales.com


REDES(ajax) 21/2/08 13:16 Página 47

REDES
Slideshow de imágenes con AJAX, XML y DOM (y III)

Cuando la lista se ha generado, en forma de


objeto “DocumentFragment”, se actualiza el
elemento “<ul>” y además dinámicamente se
crea un nuevo atributo en el objeto “Slideshow”,
almacenando el array que se ha ido creando:
oUl.appendChild(doc);
this.arrLnk = arrLnk;

El método “updateImgLst” es muy similar al


método anterior. La diferencia principal es
que se crean imágenes y no enlaces:
var oImg = document.createElement(“img”);
oImg.src = o[i].src;
oImg.width = o[i].width;
oImg.height = o[i].height;
doc.appendChild(oImg);
arrImg[arrImg.length] = oImg;
La lista de imágenes, “arrImg”, queda alma-
cenada en el propio objeto “Slideshow” en
forma de atributo, al igual que ocurría en el
caso anterior con la lista de enlaces: Código HTML de la aplicación.
this.arrImg = arrImg;
que a su vez también tiene posicionamiento El parámetro “e” es el evento en sí. Aunque con
Ajustes en la hoja CSS absoluto, o al menos relativo. “e.target” es posible acceder al objeto que lanzó
para apilar las imágenes Cuando hay varios elementos superponiéndo- el evento, dependiendo del modelo de eventos
El efecto deseado es que una imagen desapa- se, el atributo de CSS que controla cuál está que implemente el navegador, y del contenido
rezca poco a poco originando que la que está encima de cuál se denomina “z-index”, en CSS, de los enlaces (podría ser código HTML y no
detrás, que es la nueva seleccionada, comien- o “zIndex”, en JavaScript. Guarda un valor simplemente texto), “e.target” no tiene porqué
ce a mostrarse. Por lo tanto no es suficiente numérico de modo que si un elemento tiene un ser siempre el enlace, es decir, el objeto “oA”
con que se muestre una imagen y el resto se número mayor que otro significa que se apila empleando en la llamada a “addObjListener”. Lo
oculte, estén como estén realmente coloca- por delante, lógicamente tapando al otro ele- ideal sería que al ejecutar “addObjListener” se
das en la página. Ahora lo que se necesita es mento. Para el slideshow no se va a controlar el pudiera pasar también un parámetro extra, de
que las imágenes estén apiladas, una encima valor de “z-index” desde la hoja de estilos CSS forma que “clickListener” no sólo recibiera el
de otra. Para ello es necesario hacer algunos sino desde el objeto de JavaScript “Slideshow”. objeto correspondiente el evento, el parámetro
retoques en los estilos: “e”, sino además la información adicional; en el
.colright img { Ajustes en el objeto EventUtil caso del objeto “Slideshow”, esta información
position: absolute; El objeto “EventUtil”, construido en las ante- serviría para identificar unívocamente a la ima-
riores entregas, se emplea para capturar gen que el usuario ha seleccionado.
top: 0px;
eventos de una forma ordenada y flexible, La modificación que “EventUtil” requiere es
left: 0px;
siguiendo una metodología orientada a en realidad muy simple, tal y como se mues-
padding: 0px; objetos. Sin embargo todavía puede mejo- tra a continuación:
margin: 0px; rarse sustancialmente para poder trabajar addObjListener: function (oTarget,
display: none; con el con mayor comodidad, tal y como se sEventType, oObj, fnObjMethod, oArgs) {
visibility: hidden; va a ver seguidamente. var oObjImpl = oObj;
}
Para capturar los clics del ratón en los ele-
var fnObjMethodImpl = fnObjMethod;
mentos de la lista de imágenes se hacía:
var oArgsImpl = oArgs;
En CSS cuando se habla de elementos que se EventUtil.addObjListener(oA, “click”,
apilan, colocándose unos justo encima de function HandlerImpl(e) {
this, this.clickListener);
otros, siempre se está hablando de posiciona- fnObjMethodImpl.call(oObjImpl, (window.
miento absoluto (position: absolute). Con el El método “clickListener” del objeto event ? EventUtil.formatEvent(window.
estilo anterior todas las imágenes se sitúan en “Slideshow” se definía de la siguiente forma: event) : e), oArgsImpl);
la posición (0,0) con respecto a su contenedor. clickListener: function(e) { };
Obsérvese que en el posicionamiento absolu- e.preventDefault(); this.addListener(oTarget, sEventType,
to primer contenedor que se considera, den- HandlerImpl);
···
tro de todos los posibles en la jerarquía de
} }
elementos DOM de la página web, es aquel

www.revistasprofesionales.com 47 SOLO PROGRAMADORES nº 158


REDES(ajax) 21/2/08 13:16 Página 48

REDES

Aspecto de la aplicación con una imagen seleccionada. Momento de la transición entre una imagen y otra.

oListener: null,
El método “addObjListener” recibe ahora un Más adelante se comprobará, pero
nuevo parámetro, “oArgs”, que puede ser de addListener: function(oListener) {···}, “OpacityTrans” sólo va a generar un evento
cualquier tipo (un número, una cadena de fadeOff: function(oElement, iMillis) {···}, que es el que marca el final de la transición.
caracteres, un array, otro objeto, etc.). La fun- opacity: function(iOpacity) {···}, El método “opacity” es el que realmente
ción “HandlerImpl” se modifica para que se uti- setOpacity: function(oElementStyle, modifica la opacidad del elemento objeto de
lice este parámetro adicional en la llamada al iOpacity) {···}, la transición, y lo hace de manera que se
método del objeto que hace de “escuchador” fire: function() {···}
garantiza el funcionamiento para la mayor
del evento. parte de los navegadores que hay en la
};
Con el cambio descrito, la llamada captura actualidad:
de los clics quedaría como sigue: El objeto cuenta con tres atributos: opacity: function(iOpacity) {
EventUtil.addObjListener(oA, “click”, “oElement”, “oElementStyle” y “oListener”. El var iOpacityCalc = (iOpacity / 100);
this, this.clickListener, i); primero es el elemento objeto de la transi-
this.oElementStyle.opacity =
ción. El segundo atributo es un acceso direc-
iOpacityCalc;
El parámetro “i” es un valor numérico que se to al valor del atributo “style” de dicho ele-
this.oElementStyle.MozOpacity =
corresponde con el índice de de un array. El mento. Finalmente “oListener” es la función
método “clickListener” queda: que “escucha” los eventos que lanza iOpacityCalc;

clickListener: function(e, i) { “OpacityTrans”. Inicialmente todos los atribu- this.oElementStyle.KhtmlOpacity =

e.preventDefault(); tos almacenan el valor “null”. iOpacityCalc;


En cuanto a los métodos, existen dos rela- this.oElementStyle.filter = “alpha(
this.selectImg(i);
cionados con los eventos que genera opacity=” + iOpacity + “)”;
}
“OpacityTrans”, que son “addListener” y “fire”. },
Es decir, cuando se reciben los clics en los El primero simplemente asigna el atributo
enlaces se usa el parámetro “i” para identificar “oListener”: La opacidad es un valor que en algunos
directa y unívocamente al enlace correspon- addListener: function(oListener) { casos va de 0 a 100, y en otros de 0 a 1,
diente a la imagen que el usuario quiere ver. this.oListener = oListener; usando decimales. En ambos sistemas de
media 0 significa que el objeto es totalmen-
}
Transiciones usando la opacidad te transparente, y 100 o 1, según el sistema
En el fichero “slideshow.js” se ha definido un El segundo es ejecutado por el propio objeto de medición, significa que el elemento es
nuevo objeto denominado “OpacityTrans” que cuando quiere generar un evento. El valor totalmente opaco, que es el estado en el que
es el responsable de hacer la transición entre guardado en el atributo “oListener” es una se encuentran todos los elementos por
imágenes aprovechando la capacidad de los función. En JavaScript, con el método “apply” defecto.
navegadores para controlar la opacidad de un de la función, pasando como parámetro el Si se presta atención a la implementación del
elemento, para este caso en concreto la opa- valor “null”, se ejecuta dicha función: método “opacity” se observa que en realidad
cidad de las imágenes. Seguidamente se fire: function() { no diferencia entre navegadores sino que
muestra el esqueleto de este objeto: if (this.oListener!=null) { directamente se modifica el objeto “style” del
var OpacityTrans = { elemento HTML para todos los casos. Esta es
this.oListener.apply(null);
oElement: null, otra práctica común en el desarrollo de apli-
}
caciones web con DOM y AJAX. Así por ejem-
oElementStyle: null, } plo, si el navegador es Internet Explorer en

SOLO PROGRAMADORES nº 158 48 www.revistasprofesionales.com


REDES(ajax) 21/2/08 13:16 Página 49

REDES
Slideshow de imágenes con AJAX, XML y DOM (y III)

nada va a afectar que se cree el atributo “oElement.style” simplemente para optimi- un único parámetro, “i”, que es el índice que
“MozOpacity” en el objeto “style”. zar los accesos. Seguidamente se crea una identifica a la imagen seleccionada, tanto en
Si el método “opacity” es el responsable de variable, “iSpeed”, que es el resultado de el atributo “arrLnk”, el array de elementos
modificar la opacidad de un elemento una dividir el tiempo, “iMillis”, por 100. La transi- “<a>”, como en el atributo “arrImg”, el array
sola vez, el método “fadeOff” es el respon- ción consiste en modificar la opacidad del de elementos “<img>”:
sable de hacerlo varias veces, modificando elemento 100 veces, desde totalmente opaco selectImg: function(i) {
la opacidad de 100 ó 1 (totalmente opaco) (100 o 1, según el sistema de medición) ···
a 0 (totalmente transparente). En otras hasta totalmente transparente (0), y la varia-
}
palabras, este método es quien realmente ble “iSpeed” lo que viene a calcular es el
realiza la transición. Recibe dos paráme- tiempo que tiene que transcurrir entre El atributo “iSelectedIndex” del objeto
tros, el primero es el elemento cuya opaci- modificaciones de la opacidad. La variable “Slideshow” guarda el índice correspondien-
dad se quiere modificar dinámicamente “iTimer”, que se define a continuación ini- te a la imagen anteriormente seleccionada.
mediante una transición que podría califi- cialmente con el valor 0, también contribuye Su valor puede ser “-1”, lo que indica que no
carse como “suave”: de totalmente opaco a a implementar esa hipotética línea del tiem- existe ninguna imagen seleccionada. Esto
totalmente transparente, poco a poco po controlando cuántas unidades de tiempo ocurre cuando se crea el objeto “Slideshow”.
comprendido en un espacio fijo de tiempo. “iSpeed” han trascurrido. Establecidos los Cuando se da este caso, en realidad no hay
El segundo parámetro es precisamente ese valores de “iSpeed” y “iTimer”, y modificada que hacer transición entre una imagen y
espacio de tiempo: inicialmente la opacidad del elemento para otra sino simplemente mostrar la imagen
run: function(oElement, iMillis) { que sea totalmente opaco, el paso final con- seleccionada:
this.oElement = oElement; siste en hacer un bucle mediante el cuál se if (this.iSelectedIndex!=-1) {
modifica 100 veces la opacidad. Para contro- ···
this.oElementStyle = oElement.style;
lar el tiempo entre modificación y modifica-
var iSpeed = Math.round(iMillis / 100); } else {
ción, la propia modificación se lanza aprove-
var iTimer = 0; this.arrLnk[i].className = “sel”;
chando la función estándar “setTimeout”. El
this.opacity(100); primer parámetro es una llamada a la fun- this.arrImg[i].className = “sel”;
for(var i=100; i>=0; i—) { ción que realmente cambia la opacidad para }
setTimeout(“OpacityTrans.opacity(“ + i esa iteración del bucle. El segundo paráme- La acción de mostrar una imagen consiste
+ “)”, iTimer*iSpeed); tro marca el tiempo. Por último, cuando el simplemente en cambiar el atributo
iTimer++;
bucle termina, se llama al método “fire” para “className” del correspondiente elemento
lanzar el evento que avisa del final de la HTML.
}
transición. Cuando el valor de “iSelectedIndex” es dis-
setTimeout(“OpacityTrans.fire()”, tinto de “-1”, existe una imagen selecciona-
iTimer*iSpeed); La selección de las imágenes da que en ese momento se está mostrando.
} El método que recopila y emplea todas las Primeramente se tiene que deseleccionar el
Las dos primeras líneas simplemente asig- funcionalidades explicadas hasta el momen- elemento de la lista actual modificando la
nan valores a los atributos “oElement” y to es “selectImg”. Cuando el usuario hace clic propiedad “className” del enlace:
“oElementStyle” del elemento. El objeto en uno de los elementos de la lista de títulos this.arrLnk[this.iSelectedIndex]
“style” del elemento se guarda en un atribu- de imágenes, o cuando el objeto “Slideshow” .className = “”;
to en vez de hacer constantemente se inicializa, se ejecuta este método. Recibe

El evento “onload” del objeto “window” determina el momento en Cabeceras HTTP de la llamada AJAX cuando se emplea HTTP
que se crea el objeto “Slideshow” y con ello la llamada AJAX. Compression.

www.revistasprofesionales.com 49 SOLO PROGRAMADORES nº 158


REDES(ajax) 21/2/08 13:16 Página 50

REDES

osw.flush();
Seguidamente se guardan en dos variables cual ajusta el título de la lista y la imagen
la imagen seleccionada hasta el momento y correspondientes a la nueva selección. gzipos.flush();
la nueva selección: El método “addListener” sólo configura la gzipos.finish();
var oCurrImg = this.arrImg[this. función que se ejecuta al concluir la transi- baos.flush();
iSelectedIndex]; ción. Es “fadeOff” el método que realmente data = baos.toByteArray();
var oNextImg = this.arrImg[i];
realiza la transición sobre la imagen actual,
haciéndola desaparecer poco. En el segundo paso se devuelven los datos
Antes de comenzar la transición hay que comprimidos al cliente con las cabeceras
apilar las imágenes convenientemente de Optimización en el lado del servidor HTTP correctamente establecidas:
modo que la correspondiente a la selección res.setContentType(“text/plain; charset=
actual esté encima y justo debajo la imagen El Servlet “SSlideshow” representa el lado del ISO-8859-1”);
correspondiente a la nueva selección. Para servidor de la parte AJAX de la aplicación. En res.addHeader(“Content-Length”, Integer
ello se modifica el valor de los atributos un entorno real este Servlet accedería a una .toString(data.length));
“zIndex” del objeto “style” de las imágenes. base de datos, un repositorio de ficheros o
res.addHeader(“Content-Encoding”, “gzip”);
Además la nueva imagen seleccionada se cualquier otra fuente de datos, para cons-
hace visible. En realidad no va a verse por- truir el objeto JSON que devuelve. Con el os = res.getOutputStream();
que se encuentra justo detrás de la selec- objeto de simplificar el desarrollo de la apli- os.write(data);
cionada hasta el momento, pero tiene que cación y facilitar su entendimiento, en este os.flush();
hacerse visible para que se vea a medida caso “SSlideshow” simplemente devuelve
que la imagen correspondiente a la antigua siempre el mismo objeto JSON, que además ¿Qué diferencia hay entre un método y otro?
selección desaparece: se almacena en una variable estática: Desde el punto de vista del cliente práctica-
oCurrImg.style.zIndex = 10; private final static String STATIC_ mente ninguna ya que hoy en día la casi tota-
oNextImg.style.zIndex = 9; JSON_RES = “[{\”src\”: \”img/ophiopogon- lidad de los navegadores soportan HTTP
japonicus-nigrescens.jpg\”, \”width\”:450, Compression. Cuando el navegador recibe los
oNextImg.className = “sel”;
\”height\”:300, \”title\”: \”Ophiopogon datos procedentes del servidor, si encuentra
Una vez que los elementos que van a pro- <i>japonicus</i> ‘Nigrescens’\”},{···}, un cabecera “Content-Encoding” que indique
tagonizar la selección tienen sus propie- ···,{···}]”; que éstos están comprimidos, los descompri-
dades establecidas correctamente, puede me dinámicamente y de forma transparente.
comenzar la transición. No obstante Con respecto a la forma en la que el ser- La diferencia realmente importa estriba en el
antes debe configurarse la función a la vidor devuelve el objeto JSON cabe seña- tamaño de los datos que van del servidor al
que “OpacityTrans” llamará cuando se lar algo que afecta al rendimiento de la cliente. Al usar compresión el tamaño es sen-
termine la transición. Esta función se propia aplicación. En el código se han cre- siblemente menor y por lo tanto, en aplicacio-
define dinámicamente. La variable “oSelf” ado dos métodos, “serviceNormal” y nes que hacen un uso intensivo de AJAX, las
guarda una referencia al propio objeto “serviceHttpCompression”, que ilustran ventajas son evidentes y se pueden resumir
“Slideshow”: dos formas de servir la cadena de texto de manera coloquial diciendo que tardan
var oSelf = this; correspondiente al objeto JSON. El prime- menos en llegar 10KB que 100KB.
OpacityTrans.addListener ( ro representa el método “normal”, y que
function() {
puede resumirse: Conclusiones
res.setContentType(“text/plain; charset=
oCurrImg.className = “”;
ISO-8859-1”); A lo largo de estos tres artículos se ha que-
OpacityTrans.setOpacity(oCurrImg.style, rido exponer un proyecto sencillo y al
bw = new BufferedWriter(new Output
100); mismo tiempo lo más completo posible de
StreamWriter (res. getOutputStream(),
oSelf.selectImgEnd();
“ISO-8859-1”));
desarrollo de aplicaciones web con DOM y
} AJAX. El resultado y sobretodo las técnicas
bw.write(STATIC_JSON_RES);
); empleadas pueden servir fácilmente de
bw.flush(); punto de partida para realizar cualquier otra
OpacityTrans.fadeOff(oCurrImg, 2000);
El método “serviceHttpCompression” en aplicación. En este tipo de aplicaciones,
La función que se ejecuta al terminar la cambio utiliza HTTP Compression, es decir, relativamente complejas y en las que inter-
transición simplemente hace invisible la mandan el contenido comprimido en dos vienen muchos actores, tanto en el servidor
imagen correspondiente a la antigua selec- pasos. El primero lógicamente consiste en la como en el cliente, es muy importante esta-
ción modificando la propiedad propia compresión: blecer una metodología de trabajo que de
“className” del elemento HTML, y resta- baos = new ByteArrayOutputStream(); lugar a desarrollos robustos y que se pue-
blece su opacidad. Éste último paso es gzipos = new GZIPOutputStream(baos); dan mantener razonablemente bien en el
necesario ya que es posible que dicha ima- tiempo. Aquí la orientación a objetos de
osw = new OutputStreamWriter(gzipos,
gen vuelva a seleccionarse posteriormente. JavaScript no es un capricho o una ortodo-
Charset.forName(“ISO-8859-1”));
Finalmente llama al método xia académica. Es una necesidad que hace
osw.write(STATIC_JSON_RES);
“selectImgEnd” del método “Slideshow”, el posible el desarrollo estructurado.

SOLO PROGRAMADORES nº 158 50 www.revistasprofesionales.com


65 archivadores sp 21/2/08 13:28 Página 1

Archivador de revistas
+ archivador de cd´s
por solo
3E

Consigue por sólo 3 euros un archivador de revistas valorado en 5,41 euros


y un archivador de cd’s valorado en 4,20 euros.
Haz tu pedido llamando al teléfono 91 304 87 64, por fax al 91 327 13 03
o por correo electrónico a [email protected],
indicando tus datos personales y la forma de pago (giro postal, domiciliación bancaria,
tarjeta de crédito o contrareembolso*).

REVISTAS PROFESIONALES - C/ Valentín Beato, 42 - 3ª plta. - 28037 Madrid


*en opción contrareembolso se cobrará un suplemento de 5 euros por gastos de envío
En opción domiciliación bancaria, se ruega aporten los datos completos de la entidad bancaria (nombre, dirección y número de cuenta completo)
DISEÑO(websem) 21/2/08 13:21 Página 52

DISEÑO

Programando en Java la
Web Semántica con Jena (II)
Dr. DIEGO LZ. DE IPIÑA GZ. DE ARTAZA (Profesor del  Razonar sobre ontologías bien a través de
Departamento de Ingeniería del Software de la Facultad
de Ingeniería de la Universidad de Deusto - ESIDE) motores de reglas o razonamiento OWL.
El objeto de esta entrega será aprender las princi-
En esta segunda entrega ponemos en pales interfaces de programación proporcionadas
práctica mediante la framework Jena por Jena para realizar programación de la Web
Semántica. En concreto, vamos a tomar como
las tecnologías semánticas revisadas referencia el vocabulario RDF Relationship, accesi-
en la primera. Aprenderemos cómo ble en http://vocab.org/relationship/, que describe
crear un grafo RDF, serializarlo a un relaciones de parentesco entre personas. Sobre
este vocabulario y con la ayuda de Jena nos dedi-
fichero o base de datos, inferir caremos a aprender a realizar, en las siguientes
nuevas relaciones sobre él con la secciones, las siguientes acciones:
ayuda de OWL y consultar tal  Creación de un grafo RDF definiendo las relacio-
nes de parentesco dentro de una familia. La
modelo mejorado mediante familia ficticia creada puede verse en la figura 2.
SPARQL. Para el final de la entrega  Serialización de tal modelo a disco en forma de

seremos ya capaces de empezar a un fichero o de un conjunto de tablas en una


base de datos relacional sobre MySQL.
desarrollar nuestras primeras  Mejora de ese modelo infiriendo conocimiento
aplicaciones semánticas en Java. implícito en el mismo, es decir, relaciones entre
conceptos no indicadas de manera explícita
Introducción mediante ternas RDF, por medio de predicados
OWL entre las propiedades del vocabulario
Los programadores Java que quieran desarrollar Relationship.
aplicaciones web semánticas tienen un gran  Consulta de tal modelo mejorado mediante
número de herramientas y librerías donde elegir. inferencia OWL (o razonamiento semántico) a
Con todo, la más popular de todas ellas es Jena, través del lenguaje estándar de consultas de
una framework Java, disponible en grafos RDF SPARQL y serialización de resulta-
http://jena.sourceforge.net (ver figura 1) que pro- dos al formato de resultados XML estándar
porciona un entorno de programación para los también definido por SPARQL.
estándares de Web Semántica RDF, RDFS y OWL,
SPARQL e incluye un motor de inferencia basado Instalación de Jena
en reglas. Se trata de un proyecto Open Source Antes de empezar a conocer la API de programa-
derivado del trabajo realizado en el proyecto “Web ción de Jena, procedamos primero a su instalación.
Semántica” de los laboratorios Hewlett Packard en Este proceso es tan sencillo como descargarse la
Bristol, Inglaterra. Actualmente, esta framework se última versión de la distribución (actualmente
encuentra en la versión 2.5.4, siendo sus principa- 2.5.4) en formato .zip (Jena-2.5.4.zip), o el formato
les capacidades: preferido para tu plataforma, desde
 Una API RDF y OWL que permite crear y poblar http://jena.sourceforge.net/downloads.html. Tal
modelos RDF. archivo incluye las librerías compiladas en forma-
 Leer y escribir RDF en formato RDF/XML, N3 y tos .jar (carpeta “lib”), el código fuente (carpeta
N-Triples. “src”), algunos ejemplos (carpeta “src-example”) de
Material adicional  Un motor de persistencia en memoria y disco. su uso y la documentación completa de Jena (car-
 Consultar modelos programáticamente usando peta “doc”).
El material complementario puede
ser descargado desde nuestra web tanto el lenguaje propietario RDQL como Tras instalar Jena será preciso crear la variable de
www.revistasprofesionales.com SPARQL. entorno JENA_HOME en nuestro sistema apun-

SOLO PROGRAMADORES nº 158 52 www.revistasprofesionales.com


DISEÑO(websem) 21/2/08 13:21 Página 53

DISEÑO
Programando en Java la Web Semántica con Jena (II)

bres, http://family/. Las URIs de un vocabula-


rio son reutilizadas frecuentemente en códi-
go Jena por lo que es conveniente definirlas
como constantes Java para evitar errores en
su escritura.
La clase “ModelFactory” de Jena es el meca-
nismo principal para crear diferentes tipos de
modelos. En este caso, vamos a crear un
modelo vacío en memoria mediante el méto-
do “ModelFactory.createDefaultModel()”. Este
método devuelve una instancia de “Model”,
que puede ser utilizada para crear un
“Resource” representando a cada persona en
la familia. Tras la creación de los recursos se
pueden realizar sentencias RDF sobre los
mismos que son luego añadidas al modelo o
grafo RDF.
En Jena, el sujeto de una sentencia RDF es
siempre un “Resource”, el predicado se repre-
senta por una instancia de “Property”, y el
Figura 1. Sitio web de Jena. objeto es bien otro “Resource” o un valor lite-
ral. Los literales se representan en Jena como
tando al directorio de instalación de Jena. En marcadas en rojo serán inferidas y no crea- instancias de la clase “Literal”. Todos estos
mi máquina el valor de esta variable de das directamente. Esa es la razón por la que tipos que conforman sentencias RDF com-
entorno es “C:\Programming\Java\Jena- han sido mostradas en rojo. parten una interfaz común, “RDFNode”. Para
2.5.4”. Esta variable de entorno es utilizada crear las relaciones entre los miembros de la
por el script “setup.bat” provisto junto con el Creación de un modelo sencillo en RDF familia de la figura 2 se utilizarán las 4 dife-
código de esta entrega que inicializa el Las relaciones de parentesco a definir sobre rentes propiedades antes mencionadas, defi-
CLASSPATH correctamente para poder luego los miembros de familia mostrados en la nidas mediante el método “Model.
compilar y ejecutar los programas de ejem- figura 2 serán expresadas mediante las pro- createProperty()”.
plo usando los siguientes comandos respec- piedades “siblingOf”, “spouseOf”, “parentOf”, La manera más sencilla de añadir sentencias
tivamente: y “childOf”, tomadas del vocabulario al modelo es llamando a “Resource.
javac EjemploX.java “Relationship”. Para simplificar, vamos a addProperty()”. Este método crea una senten-
java EjemploX. expresar los miembros de la familia como cia en el modelo con un “Resource” como
URIs generadas a partir del espacio de nom- sujeto. Este método toma dos parámetros,
Programación RDF en Jena
Recordemos de la anterior entrega que la
Framework de Descripción de Recursos (RDF)
es un estándar propuesto por el W3C para
describir recursos, donde un recurso es “algo”
que puede ser identificado unívocamente.
Así, cada uno de nosotros es un recurso,
como lo son nuestras páginas personales,
este artículo, etc. En esta sección vamos a
aprender a programar un modelo RDF sobre
una familia y las relaciones de parentesco
entre sus miembros usando el vocabulario
bien conocido Relationship (http://vocab.org/
relationship/). La familia cuyo modelo RDF
queremos definir puede verse en la figura 2.
Las siguientes sub-secciones ilustran: a) el
proceso de creación de este grafo, b) su con-
sulta mediante la API de Jena y c) su impor-
tación o exportación desde el sistema de
ficheros o una base de datos relacional. Algo
importante a remarcar es que las relaciones Figura 2. Árbol de familia ficticio.

www.revistasprofesionales.com 53 SOLO PROGRAMADORES nº 158


DISEÑO(websem) 21/2/08 13:21 Página 54

DISEÑO

una instancia de “Property” representando el LISTADO 1 Creación de un modelo RDF en Jena


predicado de la sentencia, y el objeto de la // Declaración de espacios de nombres
sentencia. Existen varias versiones sobrecar- static final String familyUri = “http://family/”;
static final String relationshipUri = “http://purl.org/vocab/relationship/”;
gadas de “addProperty()”: una toma un
“RDFNode” como objeto, de modo que tanto // Creación de un modelo vacío Jena que representa la familiga
un “Resource” o “Literal” puede ser utilizado. Model model = ModelFactory.createDefaultModel();
// Creación de las propiedades que expresan parentesco
También hay sobrecargas que toman un lite- Property childOf = model.createProperty(relationshipUri,”childOf”);
ral representado por un dato primitivo en Property parentOf = model.createProperty(relationshipUri,”parentOf”);
...
Java. En el caso que nos ocupa, los objetos de
las sentencias son siempre otros recursos // Creación de los recursos de gente
Resource juan = model.createResource(familyUri+”juan”);
representando miembros de familia. Resource ana = model.createResource(familyUri+”ana”);
Las sentencias pueden también ser creadas ...
llamando a “Model.createStatement()” // Añadir propiedades expresando relaciones de parentesco
juan.addProperty(siblingOf,ana);
pasando como parámetros el sujeto, predica- ...
do y objeto de la tripleta. Ten en cuenta que Statement statement1 = model.createStatement(ana,siblingOf,juan);
..
la creación de una sentencia en este modo // ... añadir al modelo:
no lo añade al modelo. Es preciso invocar al model.add(statement1);
método “Model.add()” pasando como pará-
metro la sentencia creada. bién se muestra cómo añadir conjuntos de cumplen ciertas condiciones. Además
El listado 1 muestra un fragmento del códi- elementos “Statement” a un modelo median- devuelven especializaciones de “java.util.
go necesario para crear la familia de la figu- te el método “model.add()”. Iterator” que contienen métodos para devol-
ra 2 a través de las clases “Model”, “Property”, ver ciertos tipos de objetos. Así en el listado
“Resource” y “Statement” pertenecientes al Interrogando un modelo RDF 3, cuya versión completa es disponible en el
paquete “com.hp.hpl.jena.rdf.model” antes Jena también ofrece una API que nos permi- fichero “Ejemplo2.java”, se muestra cómo a
mencionadas. La serialización RDF/XML del te interrogar modelos RDF. Esto se realiza través del método “listSubjectsWithProperty
modelo creado, resultado de ejecutar el pro- principalmente a través de los métodos (parentOf)”, se obtienen todos los recursos
grama “Ejemplo1.java”, incluido junto al CD “list()” de las interfaces “Model” y “Resource”. que tienen asociada la propiedad “parentOf”.
de la revista, generaría el contenido XML Estos métodos pueden ser utilizados para El iterador devuelto (ResIterator) nos permite
mostrado en el listado 2. En tal ejemplo tam- obtener los sujetos, objetos o sentencias que movernos por cada uno de los recursos a tra-
vés del método “hasNext()”, que pregunta si
LISTADO 2 Serialización RDF/XML del modelo de familia hay más recursos sobre los que iterar, y del
1: <?xml version=”1.0”?> método “nextResource()”, que devuelve el
2: <rdf:RDF recurso actualmente apuntado. Los métodos
3: xmlns:rdf=”http://www.w3.org/1999/02/22-rdf-syntax-ns#”
4: xmlns:j.0=”http://purl.org/vocab/relationship/”> “listObjectsOfProperty()” trabajan de manera
5: <rdf:Description rdf:about=”http://family/eduardo”> similar pero devuelven objetos, que pueden
6: <j.0:siblingOf> ser tanto recursos como literales. Por esa
7: <rdf:Description rdf:about=”http://family/maria”>
8: <j.0:parentOf rdf:resource=”http://family/arantza”/> razón, se retorna un “NodeIterator”, es decir
9: <j.0:spouseOf rdf:resource=”http://family/goyo”/> un iterador de “RDFNode”.
10: </rdf:Description>
11: </j.0:siblingOf> El método más genérico que es el sustento
12: <j.0:childOf> de los métodos mostrados en el listado 3 es:
13: <rdf:Description rdf:about=”http://family/ines”>
14: <j.0:parentOf rdf:resource=”http://family/maria”/> Model.listStatements(Resource s,
15: <j.0:parentOf rdf:resource=”http://family/eduardo”/> Property p, RDFNode o)
16: <j.0:spouseOf>
17: <rdf:Description rdf:about=”http://family/juan”>
18: <j.0:parentOf rdf:resource=”http://family/maria”/> Cualquiera de sus parámetros puede ser
19: <j.0:parentOf rdf:resource=”http://family/eduardo”/> dejado a “null”, actuando en tal caso como
20: <j.0:spouseOf rdf:resource=”http://family/ines”/>
21: <j.0:siblingOf>
recurso de reemplazo, asociándose a cual-
22: <rdf:Description rdf:about=”http://family/ana”> quier concepto. Por ejemplo, el siguiente
23: <j.0:spouseOf> comando serviría para recuperar la sentencia
24: <rdf:Description rdf:about=”http://family/pedro”>
25: <j.0:spouseOf rdf:resource=”http://family/ana”/> que define la relación “Juan es esposo de
26: </rdf:Description> Inés”:
27: </j.0:spouseOf>
28: </rdf:Description> model.listStatements(juan,spouseOf,ines);
29: </j.0:siblingOf>
30: </rdf:Description> En realidad, existe otra versión de este méto-
31: </j.0:spouseOf>
32: </rdf:Description> do aún más genérica e invocada desde la
33: </j.0:childOf> implementación del método anterior que es
34: <j.0:childOf rdf:resource=”http://family/juan”/>
35: </rdf:Description> “listStatements(Selector s)”. Este método
36: </rdf:RDF> devuelve un iterador sobre todas las senten-

SOLO PROGRAMADORES nº 158 54 www.revistasprofesionales.com


DISEÑO(websem) 21/2/08 13:21 Página 55

DISEÑO
Programando en Java la Web Semántica con Jena (II)

LISTADO 3 Consulta del modelo RDF mediante Jena API (“RDF/XML” (opción por defecto), “RDF/XML-
ResIterator parents = model.listSubjectsWithProperty(parentOf); ABBREV”, “N-TRIPLE” e “N3”) y base – la URI
while (parents.hasNext()) { base para nombrar a los conceptos del
Resource person = parents.nextResource();
// Imprime la URI del recurso modelo RDF. Asimismo, para leer un modelo
System.out.println(person.getURI()); del sistema de ficheros se puede utilizar cual-
} quiera de los métodos “Model.read()” provis-
NodeIterator moreParents = model.listObjectsOfProperty(childOf);
... tos, que pueblan el modelo desde un
NodeIterator siblings = model.listObjectsOfProperty(eduardo, siblingOf); “Reader”, un “InputStream” o una URL. Los
...
StmtIterator moreSiblings = eduardo.listProperties(siblingOf); modelos pueden ser parseados desde forma-
to N3, N-Triples o, por defecto, sintaxis
LISTADO 4 Escribiendo y leyendo un modelo RDF de disco
RDF/XML.
Quizás una opción más interesante es repetir
String rdfFileName = “family.rdf”;
try { este mismo proceso sobre un motor de base
FileWriter rdfWriter = new FileWriter(rdfFileName); de datos. Por ejemplo MySQL. Antes de mos-
model.write(rdfWriter);
rdfWriter.close();
trar el código que nos permitiría la escritura
y lectura de modelos RDF hacia y desde un
model.write(System.out, “N-TRIPLE”); motor de bases de datos relacional, es preci-
// read the model from a file so instalar e inicializar la base de datos para
Model model2 = ModelFactory.createDefaultModel(); Jena a través de los siguientes pasos:
InputStream in = FileManager.get().open( rdfFileName );
if (in == null) { 1.- Descargar MySQL Community Server
throw new IllegalArgumentException(“File: “ + rdfFileName + “ not found”); desde http://dev.mysql.com/downloads/
} mysql/5.0.html#downloads. La instala-
model2.read(in, “”);
model2.write(System.out); ción es muy sencilla, tan solo hay que
model.write(System.out, “RDF/XML-ABBREV”); descargarse el instalador para tu sistema
} catch (IOException ioe) {
ioe.printStackTrace(); operativo correspondiente y ejecutarlo.
} En el caso de Windows será necesario
tras la instalación ejecutar “mysqladmin”
cias en el modelo seleccionadas por s, donde previamente existentes. Una desventaja de para arrancar el motor relacional.
el constructor de la única implementación de utilizar un modelo en memoria es obvia- 2.- Instalar el driver JDBC para MySQL que
esta interfaz tiene la siguiente forma mente que el modelo tendrá que repoblar- nos permitirá conectarnos desde Jena
“SimpleSelector(subject, predicate, object)”. se cada vez que la aplicación sea lanzada. mediante JDBC al motor de bases de
Para conseguir un control más refinado Además, cualquier cambio hecho al modelo datos MySQL. Tal driver puede descar-
sobre las sentencias seleccionadas puede será perdido cada vez que la aplicación se garse desde http://dev.mysql.com/down-
crearse una subclase de “SimpleSelector” que cierre. loads/connector/j/5.1.html. Lo importan-
modifique su método “select”. Para ello es Una solución para resolver estos problemas te es extraer del .zip provisto el fichero
muy conveniente el uso de la técnica Java de es utilizar el método “Model.write()” para “mysql-connector-java-5.1.5-bin.jar” y
sobreescritura de un método de manera inli- serializar el modelo al sistema de ficheros y hacerlo disponible en tu CLASSPATH.
ne dentro de la construcción de tal objeto. “Model.read()” para deserializarlo al arranque. 3.- Crear una base de datos donde Jena pueda
Así, el siguiente fragmento muestra cómo Sin embargo, Jena también ofrece modelos exportar e importar modelos. El fichero
seleccionar aquellas sentencias con el predi- persistentes, que son continuamente y de “create_db_and_users_family.sql”, provis-
cado “parentOf” donde la URI del sujeto modo transparente serializados a un reposi- to junto con el código de esta entrega, se
acaba en “Juan”: torio. En concreto, Jena puede persistir los encarga de crear una base de datos de
StmtIterator iter5 = model.listStatements( modelos tanto al sistema de ficheros como a nombre “family” y nombre de usuario/
new SimpleSelector(null, parentOf, una base de datos relacional. Los motores de contraseña “family/family”.
(RDFNode) null) {
bases de datos actualmente soportados son Una vez realizados los pasos de configura-
PostgreSQL, Oracle, MySQL y SqlServer. ción de nuestro entorno seguiremos el
public boolean selects(Statement s)
Para demostrar cómo exportar e importar un siguiente proceso de programación usando
{return s.getSubject().toString()
modelo a un fichero consideremos el listado la API de Jena para exportar nuestro modelo
.endsWith(“juan”); 4, cuya versión completa es disponible en el RDF sobre una familia a MySQL. Este proceso
} fichero “Ejemplo3.java”. Obsérvese cómo el se muestra en el listado 5 y corresponde con
} método “Model.write” serializa un modelo el contenido del fichero “Ejemplo4.java” del
); RDF como un stream de bytes. Este método código de la entrega:
recibe al menos un parámetro de tipo 1.- Instanciar el driver MySQL mediante la
Importando y exportando modelos “java.io.OutputStream”, es decir el stream de sentencia “Class.forName(“com.mysql.
No todas las aplicaciones comenzarán con salida donde serializar los datos, pero puede jdbc.Driver”)”.
un modelo vacío. Más comúnmente, un opcionalmente recibir el parámetro “lang”, 2.- Crear una instancia de la clase
modelo será poblado al comienzo con datos un string indicando el formato de salida “com.hp.hpl.jena.db.DBConnection”. El

www.revistasprofesionales.com 55 SOLO PROGRAMADORES nº 158


DISEÑO(websem) 21/2/08 13:21 Página 56

DISEÑO

constructor de esta clase toma como LISTADO 5 Escribiendo y leyendo datos de una base de datos MySQL
argumentos el “ID” y “password” del String rdfFileName = “family.rdf”;
usuario para logearse en la base de try {
Class.forName(mysqlDriver);
datos, así como una URL que contiene el } catch (ClassNotFoundException e) {
nombre de la base de datos que Jena System.err.println(“MySQL driver class not found”);
habrá de utilizar, en la forma “jdbc: System.exit(-1);
}
mysql://localhost/dbname”. Es importan- IDBConnection connection = new DBConnection(DB_URL, DB_USER, DB_PASSWORD, DB_TYPE);
te reseñar que Jena puede almacenar ModelMaker maker = ModelFactory.createModelRDBMaker(connection);
Model familyModel = maker.createModel(“family”,false);
varios modelos RDF en una sola base de
datos. El último parámetro indica el tipo try {
familyModel.begin();
de base de datos a utilizar que para el InputStream in =
caso de MySQL es “MySQL”. Ejemplo4.class.getClassLoader().getResourceAsStream(rdfFileName);
3.- La instancia de “DBConnection” puede if (in == null) {
throw new FileNotFoundException(“File not found on classpath: “+ rdfFileName);
ahora ser utilizada por la factoría de }
modelos de Jena para crear el modelo a familyModel.read(in,null);
familyModel.commit();
partir del contenido de la base de datos. } catch (FileNotFoundException e) {
Esto se hace mediante la sentencia System.err.println(e.toString());
“Model familyModel = maker.create } finally {
try {
Model(MODEL_NAME,false)”. El flag connection.close();
“false” en este caso significaría que en } catch (java.sql.SQLException e) {}
}
caso de ya existir un modelo con tal connection = new DBConnection(“jdbc:mysql://localhost/family”, “family”, “family”, “family”);
nombre en la base de datos que devuel- ModelRDB modelRDB = ModelRDB.open(connection, “family”);
va una copia del mismo y la cargue en modelRDB.write(System.out, “N3”);
“familyModel”, en vez de crear nuevas
tablas que recojan el modelo RDF. modelo serializado a una base de datos. precursor de SPARQL. La carpeta “doc/ARQ”
4.- A continuación, la instancia de modelo “ModelRDB” es equivalente a “Model” pero incluida en la distribución de Jena incluye
obtenida se utiliza como las instancias de en este caso cada vez que se modifica o lee documentación detallada sobre cómo utilizar
modelo utilizadas en previos ejemplos de del modelo realmente se está operando este módulo. Con todo, a continuación
esta entrega. Por ejemplo, la siguiente sen- sobre la base de datos subyacente. vamos a revisar dos aspectos relativos al uso
tencia leería el contenido de un de este módulo:
“InputStream” en el modelo: “family Consultando Modelos RDF con SPARQL  Ejecución de consultas SPARQL desde
Model.read(in,null)”, donde el segundo línea de comando.
parámetro indica la base a utilizar cuando Jena soporta SPARQL a través del módulo  Ejecución de consultas SPARQL desde la
se convierten URIs relativas a absolutas. ARQ. Este módulo no solamente puede pro- API de Jena.
Por otro lado, la sentencia del listado 5 cesar consultas en SPARQL, sino que también Para probar la ejecución de consultas
“ModelRDB.open(connection,”family”)”, acepta consultas expresadas en RDQL, el pro- SPARQL desde línea de comando tomaremos
muestra cómo cargar de un solo golpe un pio lenguaje de consultas de Jena que fue como referencia el modelo definido en el lis-

Figura 3. Ejemplo de consulta SPARQL ejecutada desde línea de comando.

SOLO PROGRAMADORES nº 158 56 www.revistasprofesionales.com


63 atrasados 21/2/08 13:28 Página 1

NÚMEROS ATRASADOS
157 - Febrero 2008 156 - Enero 2008
Nos sumergimos en el mundo Android, la nueva El iPhone ha irrumpido con fuerza en el mercado. En
plataforma móvil de la Open Handset Alliance, este número desvelamos las principales técnicas para
para analizar las herramientas incluidas en su programar aplicaciones web adaptadas a este innova-
SDK y poder crear nuestra primera aplicación dor dispositivo. Además, entregamos la última parte
Android. Además, continuamos nuestro segui- del curso dedicado a la creación de buscadores con
miento a la tecnología 4D v11 SQL, iniciamos una Lucene, una extensa revisión a la tecnología LINQ para
serie dedicada a LINQ para SQL, continuamos XML, hacemos una primera introducción a Silverlight.
nuestro desarrollo para iPhone, programamos la Además, empezamos una serie avanzada sobre pro-
web semántica con Jena y ofrecemos la segunda gramación AJAX, en la cual crearemos un slideshow de
entrega de nuestro curso AJAX. 1 CD-ROM imágenes. En términos de bases de datos, empezamos
incluido. un tutorial sobre 4D v11 SQL, además de las secciones
habituales. 1 DVD incluido.

155 - Diciembre 2007 154 - Noviembre 2007


LINQ, una de las grandes novedades de la nueva genera- 4D v11 SQL, que ya incorpora el motor SQL integra-
ción de tecnologías de Microsoft, permite al desarrollador do de manera nativa, entra en escena rompiendo
C# o VB realizar consultas de forma nativa sobre cualquier barreras, ofreciendo a los desarrolladores un autén-
colección de datos. Empezaremos aquí un extenso análi- tico producto orientado al desarrollo ágil, con el que
sis de esta tecnología, que nos llevará a cubrir LINQ para pueden alcanzarse altos niveles de productividad.
objetos, XLINQ y DLINQ. Además, finalizamos nuestro Además, en este número también nos iniciamos en
repaso a las novedades de Windows Server 2008, hace- la programación de interfaces con JavaFX, analiza-
mos un resumen de lo mejor del TechEd 2007, entregamos mos las novedades de Windows Server 2008, crea-
la segunda parte del tutorial dedicado a JavaFX, nos aden- mos un buscador propio con Lucene, finalizamos
tramos en el mundo de los buscadores con Lucene, y por nuestro repaso a los Web Service Enhancements
último mostramos las capacidades de desarrollo modular para .NET y creamos nuestro primer videojuego con
que ofrece 4D v11 SQL. 1 CD-ROM incluido. la tecnología LUA. 1 CD-ROM incluido.

153 - Octubre 2007


Revisión técnica del API Google Data, el cual permite Si te falta algún número de la
que nuestras aplicaciones puedan interactuar con los
servicios más populares de Google, como por ejemplo temporada, ahora tienes la
Blogger, Calendar, SpreadSheets, Google Docs, o
YouTube. Además, hacemos una rápida revisión de las
oportunidad de conseguirlo
novedades incluidas en 4D v11 SQL, abordamos técni- Precio Oferta descuento
camente la TDT, continuamos con nuestra revisión a Precio por ejemplar: 6€
Visual Studio 2008 Beta 2, nos sumergimos en el des-
arrollo de aplicaciones de escritorio con Java utilizando 1 a 10 = 10% dto. / 11 a 20 = 20% dto.
SWT y SQLite, programamos nuestra primera aplicación 21 a 30 = 30% dto. / 31 a 40 = 40% dto.
con Ruby on Rails y nos introducimos en los Web
Service Enhancements para .NET. 1 CD-ROM incluido. +40 = 50%

BOLETÍN DE PEDIDO
Rellene o fotocopie el cupón y envielo a REVISTAS PROFESIONALES, S.L.
(Revista SÓLO PROGRAMADORES) C/ Valentín Beato, 42 - 3ª Planta - 28037 MADRID
Tel.: 91 304 87 64 - Fax: 91 327 13 03 - www.revistasprofesionales.com - [email protected]
Deseo me envíen los número/s: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
NOMBRE Y APELLIDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .EDAD . . . . . . . . TELÉFONO . . . . . . . . . . . . . . . .
DOMICILIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .C.P.: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CIUDAD . . . . . . . . . . . . . . . . . .PROVINCIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

FORMAS DE PAGO
 Giro Postal a nombre de REVISTAS PROFESIONALES, S.L.  Talon Bancario a nombre de REVISTAS PROFESIONALES S.L.
 Domiciliación Bancaria  Contra Reembolso (5€ de gastos de envio por paquete)
Banco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Domicilio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Firma:
Numero de cuenta: _ _ _ _/ _ _ _ _/ _ _ / _ _ _ _ _ _ _ _ _ _ _ _
Titular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 Tarjeta de crédito _ _ _ _/ _ _ _ _/ _ _ _ _/ _ _ _ _/ Fecha de caducidad:
Extranjero: Gastos de envio 5€ por paquete. Unica forma de pago tarjeta de crédito (VISA, Mastercard, American Express,...)
DISEÑO(websem) 21/2/08 13:21 Página 58

DISEÑO

tado 1. La consulta SPARQL utilizada, guar- LISTADO 6 Ejecutando una consulta SPARQL desde Jena
dada en el fichero “HijosEduardo.rq”, y el public void printEduardoChildren() {
comando que la ejecuta desde línea de String queryString =
“PREFIX rel: <http://purl.org/vocab/relationship/> “ +
comandos con sus correspondientes resulta- “PREFIX fam: <http://family/> “ +
dos son mostrados en la figura 3. La librería “SELECT ?person2 “ +
“jena.jar” incluida dentro de la carpeta “lib” “WHERE {“ +
“ fam:eduardo rel:childOf ?person2 “ +
del directorio de instalación de Jena incluye “ } “;
una clase “sparql” cuya bloque “main” ejecu- Query query = QueryFactory.create(queryString);
QueryExecution qe = QueryExecutionFactory.create(query, model);
ta consultas pasadas como parámetro desde ResultSet results = qe.execSelect();
línea de comandos, tal como se ha hecho en //ResultSetFormatter.out(System.out, results, query);
ResultSetFormatter.outputAsXML(results);
la figura 3. Para ver los parámetros que acep- // Importante – eliminar recursos utilizados durante la ejecución de la consulta
ta este ejecutable basta con escribir en una qe.close();
ventana de consola el comando “java }
jena.sparql –help”. En la consulta mostrada
en la figura 3 obsérvese que la construcción Aunque la herramienta de línea de comandos model)”, pasando como parámetro la consul-
“FROM <family.rdf>” hace referencia al “sparql” es útil para ejecutar consultas autó- ta (instancia de “Query”) a ejecutar y el
fichero RDF que habíamos generado en el lis- nomas, las aplicaciones Java pueden hacer modelo (instancia de “Model”) sobre el que
tado 4 al serializar el modelo del listado 1 a uso de las capacidades SPARQL de Jena ejecutarla. Dado que los datos sobre los que
un fichero. Entre los símbolos “<” y “>” podrí- directamente. El paquete “com.hp.hpl.jena. se efectúa la consulta son provistos progra-
amos haber indicado igualmente la URL query” contiene clases que permiten la crea- máticamente, la consulta no necesita una
completa de un recurso colgado en la web, ción y ejecución con Jena de consultas. Usar cláusula FROM.
en vez de hacer referencia a un fichero de la factoría “QueryFactory” es el enfoque más Existen varios métodos “execute()” dentro
disco en el mismo directorio donde se ejecu- sencillo. Esta clase tiene varios método “cre- de la clase “QueryExecution”, cada uno de
ta el comando. En ocasiones no se indica ate()” que permiten leer una consulta textual ellos realizando un tipo de consulta dife-
nada en la cláusula FROM, pasándose el de un fichero o de un “String”. Estos métodos rente. Aparte de consultas SELECT, SPARQL
grafo sobre el que ejecuta la consulta sólo en “create()” devuelven un objeto “Query” que también soporta las construcciones CONS-
tiempo de ejecución. Este es de hecho un encapsula la consulta parseada. TRUCT, ASK y DESCRIBE, que fueron descri-
comportamiento común cuando se realizan Tras crearse una instancia de “Query” es pre- tas en la anterior entrega. Para la ejecución
consultas SPARQL dentro de un programa, a ciso crear una instancia de “QueryExecution”, de un simple SELECT, hay que invocar
menudo reutilizando la misma consulta con una clase que representa una ejecución única “execSelect()”, que devuelve una instancia
diferentes grafos. La URL pasada puede ser la de una consulta. Para obtener un de “ResultSet”. El “ResultSet” permite iterar
localización de un fichero o la dirección web “QueryExecution” invoca al método sobre cada “QuerySolution” devuelto, pro-
de un grafo remoto. “QueryExecutionFactory.create(query, veyendo así acceso a cada valor de variable

Figura 4. Serialización de resultados de consulta SPARQL en formato XML.

SOLO PROGRAMADORES nº 158 58 www.revistasprofesionales.com


DISEÑO(websem) 21/2/08 13:21 Página 59

DISEÑO
Programando en Java la Web Semántica con Jena (II)

retornado. Alternativamente, los métodos LISTADO 7 Añadiendo conocimiento mediante OWL


estáticos de la clase “ResultSetFormatter” OntModel familyOntology = ModelFactory.createOntologyModel();
pueden ser utilizadas para producir resulta- familyOntology.add(siblingOf, RDF.type, OWL.SymmetricProperty);
familyOntology.createTransitiveProperty(siblingOf.getURI());
dos de consulta en diferentes formatos.
El listado 6 muestra cómo obtener los hijos de OntProperty childOfProp =
Eduardo mediante una consulta SPARQL apli- familyOntology.createOntProperty(relationshipUri+”childOf”);
OntProperty parentOfProp =
cada al modelo definido en el listado 1 y familyOntology.createOntProperty(relationshipUri+”parentOf”);
correspondiente al árbol de familia de la figura childOfProp.addInverseOf(parentOfProp);
2. Obsérvese que la clase “ResultSetFormatter”
ofrece diferentes mecanismos para mostrar los get()”, “QuerySolution.getResource()” y Infiriendo nuevo conocimiento con OWL
resultados. El método comentado “ResultSet “QuerySolution.getLiteral()” que devuelven el
Formatter” produciría resultados idénticos a “RDFNode”, “Resource” o “Literal” asociado a OWL (Web Ontology Language) es una reco-
los que se mostraron en la figura 3. Sin embar- una variable de una consulta. En el ejemplo mendación del W3C orientada a “represen-
go, el método “ResultSetFormatter. mostrado se está concretamente accediendo a tar de manera explícita el significado de tér-
outputAsXML (results)” imprime los resultados la variable “?child” de la consulta mostrada en minos de vocabularios y sus relaciones con
en el formato de serialización XML de resulta- figura 3: otros términos”. Junto con RDF Schema,
dos definido por SPARQL. Los resultados de for ( ; results.hasNext() ; ) { OWL proporciona un mecanismo para for-
invocar el método “printEduardoChildren()” QuerySolution soln = results. malmente describir el contenido de modelos
definido en el programa “Ejemplo5.java” inclui- nextSolution();
RDF. Aparte de definir las clases jerárquicas
do junto con el código del artículo se muestran a las que los recursos pueden pertenecer,
Resource x = soln.getResource
en la figura 4. OWL permite expresar las características de
(“child”);
Finalmente, el siguiente fragmento de código las propiedades de los recursos. Por ejemplo,
muestra cómo se podría acceder programática- System.out.println(“Hij@ de para el vocabulario Relationship sobre el
mente a los resultados devueltos por una con- Eduardo: “ + x.getURI()); que hemos estado trabajando desde el lista-
sulta, mediante los métodos “QuerySolution. } do 1, OWL podría ser utilizado para expresar
que la propiedad “childOf” es inversa a la
propiedad “parentOf”. De ese modo, si se
indicara que Eduardo es hijo de Juan, se
estaría automáticamente y de manera
implícita diciendo que Juan es padre de
Eduardo. Otro buen ejemplo del potencial de
OWL como mecanismo para producir nuevo
conocimiento usando “razonamiento onto-
lógico”, sería cualificar la propiedad
“chilfOf” con el atributo de transitividad.
Esto significaría que revisando la figura 2 si
supiéramos que Diego es hermano de María
y María hermana de Eduardo, podríamos
automáticamente inferir que Diego es tam-
bién hermano de Eduardo, aunque no lo
hayamos dicho de manera explícita.
En Jena, una ontología es tratada como un
tipo especial de modelo RDF de acuerdo a la
interfaz “OntModel”. Esta interfaz define
métodos para manipular programática-
mente una ontología permitiendo crear
clases o definir restricciones entre propie-
dades. Otra alternativa es tratar la ontolo-
gía como un modelo RDF estándar y sim-
plemente añadir sentencias definiendo sus
reglas semánticas. Ambas técnicas son
demostradas en el listado 7 y en mayor
detalle en “Ejemplo6.java”. Observa además
que es posible añadir sentencias ontológi-
cas a un modelo ya existente, o combinar
un modelo ontológico con otro modelo RDF
Figura 5. Inferencia basada en OWL en Jena. mediante el método “Model.union()”.

www.revistasprofesionales.com 59 SOLO PROGRAMADORES nº 158


DISEÑO(websem) 21/2/08 13:21 Página 60

DISEÑO

Dada una ontología y un modelo, el motor de LISTADO 8 Inferencia ontológica y consulta sobre modelo inferido
inferencia de Jena puede derivar nuevas sen- Reasoner owlReasoner = ReasonerRegistry.getOWLReasoner();
tencias que el modelo no expresa de manera Reasoner familyReasoner = owlReasoner.bindSchema(familyOntology);
InfModel infModel = ModelFactory.createInfModel(familyReasoner, model);
explícita. Jena ofrece varios tipos de String queryString =
“Reasoners” que permiten trabajar con dife- “PREFIX rel: <http://purl.org/vocab/relationship/> “ +
rentes tipos de ontologías. Dado que quere- “PREFIX fam: <http://family/> “ +
“SELECT ?parent “ +
mos usar la ontología OWL definida en el lis- “WHERE {“ +
tado 7 con el modelo RDF del listado 1, tene- “ fam:maria rel:childOf ?parent “ +
“ } ORDER BY ?parent”;
mos que utilizar la interfaz “com.hp.hpl.jena. Query query = QueryFactory.create(queryString);
reasoner.Reasoner”, que es implementada QueryExecution qe = QueryExecutionFactory.create(query, infModel);
ResultSet results = qe.execSelect();
por todos los razonadores soportados por ResultSetFormatter.out(System.out, results, query);
Jena como “BasicForwardRuleReasoner”, qe3.close();
“OWLFBRuleReasoner” u “OWLMicroReasoner”.
El listado 8 muestra un ejemplo sobre cómo ?siblingOf1 rel:siblingOf ?siblingOf2 tar un modelo RDF, bien a través de la API de
aplicar la ontología de familia OWL mostrada FILTER(?siblingOf1 != ?siblingOf2) Jena o utilizando consultas SPARQL.
en el listado 7 al modelo de familia RDF defi- } ORDER BY ?siblingOf1 Finalmente, hemos visto cómo utilizar el
nido en el listado 1 para así crear un modelo motor de inferencia OWL de Jena para reali-
de inferencia. En primer lugar, obtenemos un Por otro lado, la segunda consulta SPARQL zar inferencias sobre un modelo al que se
razonador OWL del registro de razonadores devuelve los nombres de los padres de María. aplica una ontología descrita en OWL.
mediante el método “ReasonerRegistry. Tal consulta es mostrada dentro del listado 8. Esta entrega ha demostrado el potencial de
getOWLReasoner()”. El siguiente paso es aso- La figura 5 muestra los resultados de haber representar datos como modelos RDF y la fle-
ciar el razonador a la ontología de familia ejecutado estas dos consultas sobre un xibilidad del lenguaje de consultas RDF SPARQL
(familyOntology). Esta operación devuelve un modelo normal primero y en segundo lugar para extraer datos de estos modelos. Hemos
razonador listo para aplicársele las reglas de sobre otro sobre el que se ha inferido nuevo observado el potencial de OWL para inferir
la ontología. A continuación, utilizamos el conocimiento a través de OWL. La primera conocimiento implícito a partir de ternas RDF
razonador asociado para crear un modelo vez las consultas son ejecutadas sobre el explícitas. Las técnicas explicadas serán un
mejorado con inferencias definido por la modelo definido en el listado 1. En la segun- punto de comienzo útil para que empecemos a
clase “InfModel” a partir del modelo de fami- da ocasión se repiten ambas consultas sobre utilizar modelos RDF en nuestras aplicaciones
lia original. un “InfModel” generado al aplicar al modelo Java. Se recomienda visitar la web de Jena para
Habiendo creado un modelo de inferencia a original las relaciones OWL expresadas en aprender más sobre lo explicado.
partir de los datos originales y la ontología “familyModel”. Así, aunque en el listado 1 y En la próxima entrega seguiremos apren-
OWL, ahora lo podemos tratar como cual- en su código de ejemplo asociado en la diendo más sobre programación semántica
quier otra instancia de modelo. Por tanto, entrega, “Ejemplo1.java”, no se indica explíci- en Java. Concretamente, nos aproximaremos
como muestra el código del método tamente que Diego es hermano de Eduardo, al concepto de “Web Semántica con minús-
“owlReasoningOverModel()” incluido en el esto puede inferirse aplicando la propiedad culas”, una simplificación realista de la
fichero de la entrega “Ejemplo6.java”, las de simetría del predicado “siblingOf”. Por otro misma que puede fácilmente aplicarse a los
mismas consultas definidas sobre un mode- lado, una vez inferido que Diego es hermano portales Web 2.0 actuales para dotarlos de
lo Jena normal pueden ser reutilizadas y de Eduardo y como se conoce que Eduardo mayor inteligencia.
aplicarse al modelo inferido sin ningún es hermano de María, se puede inferir, dada
cambio. Sobre el modelo inferido se aplican la transitividad de la propiedad “siblingOf” Referencias
dos consultas. La primera tiene como retor- que Diego es también hermano de María.
no los pares de hermanos donde alguien no Finalmente, dado que se conoce del listado 1  Jena – A Semantic Web Framework for
puede ser hermano de sí mismo. que Juan e Inés son padres de María, se Java, http://jena.sourceforge.net
Desafortunadamente, el hecho de haber puede inferir que María es hija de ambos,  Introduction to Jena, Philip McCarthy,
considerado “siblingOf” como transitivo y dado que los predicados “childOf” y http://www.ibm.com/developerworks/xml/
simétrico a la vez, revisar listado 7, lo hace “parentOf” han sido declarados como inver- library/j-jena/
reflexivo, dando lugar a inferencias como sos en la ontología “familyModel”.  An Introduction to RDF and the Jena RDF API,
“Diego es hermano del mismo padre y http://jena.sourceforge.net/tutorial/RDF_API/
madre que Diego”, que aunque semántica- Conclusiones  Search RDF data with SPARQL, Philip
mente cierto suena extraño. La construcción McCarthy, http://www.ibm.com/developer
FILTER de la siguiente consulta se encarga En este artículo se han demostrado algunas works/java/library/j-sparql/
de eliminar esos resultados extraños: de las características más importantes de la  Meet Jena, a Semantic Web Platform for Java,
PREFIX rel: <http://purl.org/vocab/ framework de programación semántica Jena, Ian Dickinson, http://www.devx.com/semantic/
relationship/> con ejemplos ilustrando cómo crear, importar Article/34968/1954?pf=true
y persistir al sistema de ficheros o bases de  Let Semantics Bring Sophistication to Your
SELECT ?siblingOf1 ?siblingOf2
datos relacionales modelos RDF. También Applications, Rod Coffin, http://www.devx.com/
WHERE {
hemos revisado diferentes modos de consul- semantic/Article/34591/1954?pf=true

SOLO PROGRAMADORES nº 158 60 www.revistasprofesionales.com


Suscripcion Solop2005 22/6/07 08:32 Página 1

Suscripción a Sólo Programadores


SUSCRIPCIÓN PARA ESPAÑA FORMAS DE PAGO PARA ESPAÑA
Opción A: Suscripción anual con 25% descuento:  Contrareembolso (10 euros gastos de envío)
54 euros* (3 revistas gratis, 18 euros de ahorro)  Giro Postal a Revistas Profesionales, S.L.
Opción B: Suscripción anual con 15% descuento:  Transferencia al Banco Popular:
61,20 euros* (tapas de regalo, 10,80 euros de ahorro) c.c:0075/1040/43/0600047439
*10 euros de gastos de envío para la opción contrareembolso  Talón Bancario a nombre de Revistas Profesionales
 Domiciliación Bancaria
SUSCRIPCIÓN PARA EXTRANJERO
 Tarjeta de Crédito + fecha de caducidad
Opción C: Suscripción anual con 25% descuento
90 euros (gastos de envío incluidos)
FORMA DE PAGO EXTRANJERO:
 Tarjeta de crédito + fecha de caducidad

Solicitud de suscripciones y más información en el teléfono 91 304 87 64, en el fax 91 327 13 07


y en [email protected]
lecturas 21/2/08 13:25 Página 62

LECTURAS

El libro de Django
En http://the-geek.org/django-book/, las peticiones. En otras palabras, le otorga una
con licencia GNU Free Document, manera de designar qué código se ejecutará
para cada URL. Por ejemplo, se le podría decir
se encuentra la versión beta de la al framework: “Para las URL que se parezcan a
traducción al español del libro /users/joe/, ejecuta el código que muestre el
perfil del usuario con ese nombre de usuario”.
The Django Book, cuyo primer  Facilita mostrar, validar y volver a mostrar for-
capítulo reproducimos a mularios HTML. Los formularios HTML son la
principal manera de obtener datos de entrada
continuación. Django es un de los usuarios web, así que más le vale a un
framework en Python para framework web facilitar la representación de
formularios y el manejo del código tedioso
desarrollo web, y se considera para mostrar y volver a mostrar formularios
una alternativa a Ruby on Rails. (resaltando los errores).
 Convierte la entrada que envía el usuario en
Si se dirige a la página web http://djangoproject.com estructuras de datos que se pueden manipular
utilizando su navegador web o, dependiendo de la cómodamente. Por ejemplo, el framework
década en la que esté leyendo este trabajo litera- podría convertir los datos de un formulario
rio destinado a ser eterno, utilizando su teléfono HTML en tipos de datos nativos al lenguaje de
móvil, agenda electrónica, zapato o cualquier programación que se esté utilizando.
cacharro que suplante a Internet, se encontrará  Ayuda a separar el contenido de la presenta-
con esta explicación: ción mediante un sistema de plantillas, de
“Django es un framework web de alto nivel en manera que se pueda cambiar el aspecto de un
Python que fomenta el desarrollo rápido y el dise- sitio web sin afectar al contenido, y viceversa.
ño limpio y pragmático.”  Se integra cómodamente con las capas de
Eso es un gran bocado, o un gran vistazo, o un almacenamiento (como las bases de datos)
gran puñado de píxeles, dependiendo de si este pero no exije estrictamente el uso de una base
libro se está recitando, leyendo en papel o pro- de datos.
yectándose en un Jumbotrón, respectivamente.  Le permite trabajar más productivamente, a un
Descompongámoslo. nivel de abstracción mayor que si estuviera
programando usando, digamos, HTTP. Pero no
Django es un framework web de alto nivel... le prohíbe ir un nivel de abstracción “hacia
abajo” cuando sea necesario.
Un framework web es un software que alivia el  Se aparta de su camino, evitando llenarle la
sufrimiento derivado de construir páginas web aplicación de manchas sucias, como URL que
dinámicas. Abstrae problemas comunes al desarro- contengan “.aspx” o “.php”.
llo web y proporciona atajos para tareas de progra- Django hace todas estas cosas bien; y presenta
mación frecuentes. una serie de características que elevan el listón de
Para los lectores que han llegado tarde a la fiesta: lo que debería ser un framework web.
un sitio web dinámico es uno en el que las pági- El framework está escrito en Python, un lenguaje de
nas no son simplemente documentos HTML colo- programación bonito, conciso, potente y de alto
cados en algún lugar del sistema de ficheros de nivel. Para desarrollar un sitio utilizando Django hay
un servidor. Por el contrario, en un sitio web diná- que escribir código Python que utiliza las bibliotecas
mico, cada página la genera un programa de de Django. Aunque este libro no incluye un tutorial
computador (una famosa “aplicación web”) que completo de Python, sí llama la atención sobre
usted, el desarrollador web, crea. Por ejemplo, una características y funcionalidades de Python cuando
aplicación web podría obtener registros de una es procedente, especialmente cuando el código no
base de datos o realizar alguna acción basándose tiene sentido de forma inmediata.
en la entrada del usuario.
Un buen framework web resuelve los siguientes ...que promueve el desarrollo rápido...
problemas:
 Proporciona un método para hacer correspon- A pesar de lo potentes que sean sus característi-
der peticiones URL con el código que maneja cas, un framework web carece de valor si no con-

SOLO PROGRAMADORES nº 158 62 www.revistasprofesionales.com


lecturas 21/2/08 13:25 Página 63

LECTURAS
El libro de Django

El Libro de Django está disponible en Internet. El sitio de Django.


sigue ahorrarle tiempo. La filosofía de las mejores prácticas de desarrollo web en Django sigue la arquitectura del “modelo-
Django es hacer todo lo posible por facilitar las aplicaciones que crea. vista-controlador” (MVC). Dicho de forma
el desarrollo hiper rápido. Con Django se Esto significa que, si pensamos que Django es sencilla, esto es una manera de desarrollar
construyen sitios web en cuestión de horas, un coche, sería un elegante coche deportivo, software para que el código para definir y
no días; semanas, no años. capaz no sólo de alcanzar grandes velocidades y acceder a los datos (el modelo) esté separa-
Esto es en gran parte posible gracias al pro- atacar curvas cerradas, sino también de ofrecer do de la lógica de negocio (el controlador),
pio Python. ¡Oh, Python, cuánto te amamos! una excelente autonomía y emisiones limpias. que a su vez está separada de la interfaz de
Contemos tus puntos importantes: Aquí la filosofía es: Django facilita hacer las usuario (la vista).
 Python es un lenguaje interpretado, lo que cosas de la manera “correcta”. El MVC se explica mejor con un ejemplo de lo
quiere decir que no hace falta compilar el Concretamente, Django fomenta el bajo acopla- que no hay que hacer. Por ejemplo, échele un
código. Sólo hay que escribir el programa y miento: la filosofía de programación que dice vistazo al código en PHP que se muestra en
ejecutarlo. En el desarrollo web, esto signi- que las distintas partes de la aplicación deben el listado 1, que obtiene una lista de perso-
fica que se puede desarrollar código y ver ser intercambiables y deben comunicarse unas nas de una base de datos MySQL y devuelve
los resultados inmediatamente dándole a con otras mediante APIs claras y concisas. la lista mediante una sencilla página HTML
“recargar” en el navegador web. Por ejemplo, el sistema de plantillas no sabe (sí, somos conscientes de que es posible que
 Python tiene tipado dinámico, lo que quie- nada sobre el sistema de acceso a bases de los programadores disciplinados escriban
re decir que no hace falta preocuparse de datos, que no sabe nada de la capa de peti- código limpio en PHP; simplemente estamos
declarar los tipos de datos de las variables. ción/respuesta HTTP, que no sabe nada acerca usando el PHP para ilustrar una idea).
 La sintaxis de Python es concisa pero del cacheo. Todas estas capas están diferencia- Aunque el código del listado 1 es concep-
expresiva, lo que quiere decir que hace das y acopladas holgadamente con el resto. En tualmente sencillo para los principiantes,
falta menos código para llevar a cabo una la práctica, esto significa que se pueden mez- porque todo está en un mismo fichero, es un
tarea que en otro lenguajes más verbosos clar y combinar las capas si es necesario. ejemplo de mala práctica, por varias razones:
como Java. Una línea de Python suele
equivaler a 10 líneas de Java. (Esto tiene
un oportuno beneficio colateral: menos LISTADO 1 PHP
líneas de código significan menos bugs.) <html>
 Python ofrece medios poderosos de <head><title>Mis amigos</title></head>
introspección y metaprogramación que <body>
hacen posible inspeccionar y modificar el
<h1>Mis amigos</h1>
comportamiento de los objetos en tiempo
de ejecución. <ul>
Más allá de las ventajas en productividad
<?php
inherentes a Python, el propio Django hace $conexion = @mysql_connect(“localhost”, “mi_usuario”, “mi_contraseña”);
todo lo posible para fomentar el desarrollo mysql_select_db(“mi_basededatos”);
rápido. Todas las partes del framework se $personas = mysql_query(“SELECT nombre, edad FROM amigos”);
diseñaron con la productividad en mente. while ( $persona = mysql_fetch_array($personas, MYSQL_ASSOC) ) {
?>
Veremos ejemplos a lo largo de este libro. <li>
<?php echo $persona[‘nombre’] ?> tiene <?php echo $persona[‘edad’] ?> años.
...y el diseño limpio y pragmático </li>
<?php } ?>
Finalmente, Django mantiene de forma </ul>
rigurosa un diseño limpio en su propio
código, y facilita que el programador siga </body>
</html>

www.revistasprofesionales.com 63 SOLO PROGRAMADORES nº 158


lecturas 21/2/08 13:25 Página 64

LECTURAS

1.- La presentación está vinculada al te el mismo código para las peticiones a Hablando más seriamente, Django todavía no
código. Si un diseñador quisiera editar “/bar/” y “/baz/”? Tendría que configurar invierte los efectos del calentamiento global.
el HTML de esta página, tendría que edi- una serie de “includes” o reglas de rees-
tar este código, porque el el HTML y el critura, algo que rápidamente se hace Porqué se desarrolló Django
PHP están entrelazados. inmanejable.
En contraste, el enfoque MVC de Django En contraste, Django desvincula las URLs Las raíces de Django se encuentran en los pro-
fomenta la separación entre el código y del código que se llama, de manera que blemas y soluciones del Mundo Real. No fue cre-
la presentación, de manera que la pre- siempre se pueden cambiar las URLs que ado para promocionarlo y venderlo a los desa-
sentación está gobernada por plantillas llaman a un cierto trozo de código. rrolladores, ni tampoco fue creado como ejerci-
y la lógica de negocio reside en módu- 4.- Los parámetros de conexión a la base cio académico durante el tiempo libre de alguien.
los de Python. Los programadores se de datos están “hard-coded”. Es sucio Fue construido, desde el primer día, para resol-
ocupan del código y los diseñadores se tener que especificar la información de verle problemas diarios a un equipo de desarro-
ocupan del HTML. conexión, el servidor, el nombre de usua- llo web en la vanguardia de la industria.
2.- El código relativo a bases de datos está rio y la contraseña, dentro de este código, Comenzó en el otoño de 2003, en un perió-
vinculado a la lógica de negocio. Esto es porque es configuración, no lógica de dico de pueblo en Lawrence, Kansas.
un problema de redundancia: si se renom- programación. Además, este ejemplo Por una razón u otra, el periódico Lawrence
bran las tablas o columnas de la base de también tiene “hard-coded” el hecho de Journal-World consiguió atraer a un talentoso
datos, será necesario reescribir el SQL. que el motor de bases de datos es MySQL. grupo de diseñadores y desarrolladores web a
En contraste, el enfoque MVC de Django En contraste, Django sólo tiene un lugar principios de la década 2000. La división web
fomenta el uso de una sola capa de acce- para almacenar la configuración, y la del periódico, World Online, se convirtió rápi-
so a datos abstraída, responsable de todo capa de acceso a bases de datos está damente en una de las divisiones web de un
el acceso a los datos. En el caso de abstraída, de manera que es sencillo periódico más innovadoras del mundo. Sus
Django, la capa de acceso a datos cono- cambiar de servidor de base de datos tres sitios principales, LJWorld.com (noticias),
ce los nombres de las tablas y las colum- (digamos, de MySQL a PostgreSQL). Lawrence.com (entretenimiento/música) y
nas de la base de datos, y permite ejecu- KUsports.com (deporte universitario), empe-
tar sentencias SQL mediante Python en Lo que no hace Django zaron a ganar premio tras premio en la indus-
lugar de escribir SQL directamente. Esto tria del periodismo en línea. Sus innovaciones
significa que si cambia el nombre de las Por supuesto, queremos que este libro sea fueron muchas, incluyendo:
tablas de la base de datos, sólo hace falta justo y equilibrado. Con eso en mente, tene-  La página de entretenimiento local más
cambiarlo en un sitio , en la definición del mos que ser honestos y resumir lo que no exhaustiva del mundo, Lawrence.com, que
modelo de datos, en lugar de tener que hace Django: aúna bases de datos locales de eventos,
cambiar todas las sentencias SQL desper-  Alimentar a su gato. bandas, restaurantes, bebidas especiales,
digadas por el código.  Leer de su mente los requisitos del pro- canciones descargables y noticias en for-
3.- La URL está unida al código. Si este yecto e implementarlos en un tiempo mato tradicional.
fichero PHP reside en “/foo/index.php”, se razonable para engañar a su jefe y hacer-  Una sección veraniega de LJWorld.com
ejecutará con todas las peticiones a esa le creer que en realidad no se ha queda- dedicada a los jugadores de las liguillas loca-
dirección. Pero, ¿y si quiere que se ejecu- do en su casa para ver “El precio justo”. les, que los trataba como si fueran los New
York Yankees, proporcionando una página
para cada equipo y liga, obteniendo datos
meteorológicos para mostrar pronósticos
para los partidos, ofreciendo panoramas de
360 grados de todos los campos de juego de
los alrededores y alertando a los padres de
las cancelaciones de los partidos mediante
mensajes a teléfonos móviles.
 Alertas a teléfonos móviles sobre los par-
tidos de baloncesto y fútbol americano de
la Universidad de Kansas, que permitía a
los aficionados estar al tanto de las pun-
tuaciones y estadísticas clave durante los
partidos, y un segundo sistema que utili-
zaba algoritmos de inteligencia artificial
que permitía a los aficionados enviar
mensajes en inglés al sistema para con-
sultar la base de datos (“cuántos puntos
llevan los giddens” o “pts giddens”).
 Una exhaustiva base de datos con todas
las estadísticas imaginables sobre el fút-
bol americano y el baloncesto universita-
rios, incluyendo un medio para comparar
cualquier grupo de jugadores o equipos
de la NCAA.
LJWorld.com, primer sitio desarrollado con Django.

SOLO PROGRAMADORES nº 158 64 www.revistasprofesionales.com


lecturas 21/2/08 13:25 Página 65

LECTURAS
El libro de Django

 http://www2.kusports.com/stats/
 La página web del Washington Post, was-
hingtonpost.com, utiliza Django para sus
proyectos con bases de datos, y varias
pizcas de funcionalidad por todo el sitio.
Algunos ejemplos:
 La base de datos de los votos del
Congreso de EEUU: http://projects.was-
hingtonpost.com/congress/
 El directorio de personal y la funcionali-
dad que permite a los lectores contactar
con los periodistas, que aparece como un
enlace en la mayoría de los artículos.
 Faces of the Fallen: http://projects.was-
hingtonpost.com/fallen/
 Chicagocrime.org, una base de datos de
libre acceso sobre los crímenes que se
producen en Chicago y una de las prime-
ras aplicaciones externas basadas en
Google Maps, fue desarrollada en Django.
 Tabblo.com, una innovadora web de com-
partición de fotos, utiliza Django. La pági-
na le permite juntar sus fotografías para
El sitio web de The Washington Post también usa Django.
crear álbumes de fotos que cuentan his-
 Proporcionando blogs a los miembros de la en el que ya movía la mayoría de los sitios torias.
comunidad y promocionando de forma pro- de World Online, el equipo de World Online,  Texasgigs.com, un sitio de música local de
minente los contenidos de la comunidad, que ya incluía a Jacob Kaplan-Moss, decidió Dallas, Texas, fue escrito en Django.
antes de que los blogs estuvieran de moda. que sería una buena idea liberar el frame-  Grono.net, una red social polaca, comen-
Muchos expertos del periodismo en el mundo work. De esa manera retribuirían a la comu- zó a sustituir su código en Java por
señaralon a World Online como ejemplo del nidad del software libre, obtendrían mejoras Django. Descubrieron que no solo era
futuro del periodismo. El New York Times gratis de desarrolladores externos, y genera- más rápido de desarrollar (y más diverti-
publicó una noticia sobre la empresa en la rían cierta publicidad para su sistema de do), sino que proporcionaba mayor rendi-
portada de la sección de negocios; la National gestión de contenidos comercial, Ellington miento que Java y requería menos recur-
Public Radio emitió una serie de dos días sobre (http://www.ellingtoncms.com/). Django se sos de hardware.
ella. El director editorial de World Online, Rob liberó en julio de 2005 y rápidamente se  Traincheck.com fue desarrollada en
Curley, dio charlas casi semanalmente en con- hizo popular. Django. Esta web le permite enviar men-
ferencias de periodismo por todo el planeta, Aunque Django es un proyecto de software sajes de texto desde su teléfono móvil
exponiendo las ideas innovadoras y las carac- libre con colaboradores en todo el mundo, para obtener los horarios de metro relati-
terísticas del sitio web de World Online. En una los desarrolladores originales de World vos al lugar donde se encuentre.
industria lóbrega y anticuada reacia a los cam- Online siguen proporcionando las principa- Existe una lista actualizada con las docenas
bios, World Online era una rara excepción. les directivas para el crecimiento del frame- de sitios que utilizan Django en http://code.
Gran parte del éxito de World Online fue debi- work, y World Online contribuye con otros djangoproject.com/wiki/DjangoPoweredSites
do a la tecnología que había detrás de sus aspectos importantes como tiempo laboral,
páginas, y a la filosofía que dice que los pro- material publicitario y alojamiento/ancho de Sobre este libro
gramadores informáticos son igual de impor- banda para la página web del framework
tantes que los propios periodistas a la hora de (http://www.djangoproject.com/). El objetivo de este libro es explicar todas
crear periodismo de calidad del siglo XXI. las cosas que hace Django y convertirle
Por esto se desarrolló Django: los desarrolla- Quién usa Django en un experto en ellas. Al leer este libro
dores de World Online necesitaban un frame- aprenderá las habilidades necesarias para
work para desarrollar sitios web complejos Muchos desarrolladores web de todo el desarrollar sitios web potentes de forma
sobre bases de datos de forma indolora, fácil mundo utilizan Django. Algunos ejemplos rápida, con un código limpio y fácil de
y con los plazos temporales del periodismo. concretos: mantener.
En otoño de 2003, dos desarrolladores de  Por supuesto, World Online sigue utili- El contenido completo del libro puede
World Online, Adrian Holovaty y Simon zando Django para todos sus sitios web, encontrarse en http://the-geek.org/djan-
Willison, se pusieron a crear este framework. tanto internos como los de los clientes go-book/ y la versión en inglés en http://
Decidieron utilizar Python, un lenguaje del comerciales. Algunos de sus sitios que www.djangobook.com/en/beta/.
que se habían enamorado recientemente. corren con Django son: Copyright 2006 Adrian Holovaty y Jacob
Tras explorar (y quedar decepcionados con)  http://www.ljworld.com/ Kaplan-Moss.
las librerías de programación web disponibles  http://www.lawrence.com/ Copyright de la traducción: Ricardo Cárdenes
en Python, empezaron a crear Django.  http://www.6newslawrence.com/ Medina y Gabriel Rodríguez Alberich
Dos años más tarde, en verano de 2005, tras  http://www.visitlawrence.com/ Esta obra tiene licencia GNU Free Document
haber desarrollado Django hasta un punto  http://www.lawrencechamber.com/ License.

www.revistasprofesionales.com 65 SOLO PROGRAMADORES nº 158


Video 21/2/08 13:26 Página 66

VIDEO-TUTORIAL

Menú Arts
JORGE RUBIRA Edition, de escritorio, y hará uso de colores, degra-
dados y transparencias entre otros efectos. El
En esta nueva edición de los entorno de desarrollo elegido en esta ocasión ha
vídeo-tutoriales vamos a explicar sido NetBeans 6.0.
cómo crear un menú artístico ¿Cómo obtener el vídeo-tutorial?
usando colores, degradados,
transparencias y otros efectos, todo El material que conforma este vídeo-tutorial
consiste en un archivo de vídeo y unos archivos
ello con tecnología Java y el IDE de código que implementan el proyecto. El
NetBeans 6. vídeo-tutorial así como el material del proyecto
desarrollado pueden descargarse desde
www.revistasprofesionales.com. El formato del
Creación de menús artísticos vídeo es WMV y el tamaño de la descarga es de
40 MB aproximadamente.
Muy probablemente el lector haya sentido la
necesidad, en algún momento de su carrera pro-
fesional, de crear una interfaz gráfica de usuario ¿Tienes sugerencias para el próximo
con controles absolutamente personalizados, vídeo-tutorial?
intentando así huir del clásico aspecto que ofre-
cen siempre la mayoría de aplicaciones. Pues bien, Nos interesa saber cómo podemos mejorar los
en el vídeo-tutorial de este mes, Jorge Rubira nos vídeos y sus contenidos, de modo que si tenéis
enseña a crear un menú artístico, en el que la cualquier sugerencia para futuros vídeos, no
única limitación será nuestra propia imaginación. dudéis en transmitirla a Jorge Rubira, el autor:
Este menú será una aplicación Java Standard [email protected].

SOLO PROGRAMADORES nº 158 66 www.revistasprofesionales.com


anuncio RP 210*280 21/2/08 13:31 Página 91
210X280_G.indd 1
Crea mejores aplicaciones para tu equipo y la web,
CONTENTA A TODOS SIN COMPROMETER NADA. en los plazos establecidos, con herramientas que
pulvericen los tiempos, maximicen la experiencia
®
y den resultados. Más consejos y herramientas en
NUEVO VISUAL STUDIO 2008. desafiatodoslosretos.com

15/2/08 18:36:04

También podría gustarte