• Save
Seminario Liferay 6.1 sobre gestion avanzada de portales y tecnologias JAVA Empresariales. CLEFormacion
Upcoming SlideShare
Loading in...5
×
 

Seminario Liferay 6.1 sobre gestion avanzada de portales y tecnologias JAVA Empresariales. CLEFormacion

on

  • 7,397 views

Características más importantes de Liferay 6.1: La gestión avanzada de portales y las tecnologías JAVA Empresariales

Características más importantes de Liferay 6.1: La gestión avanzada de portales y las tecnologías JAVA Empresariales

Statistics

Views

Total Views
7,397
Views on SlideShare
6,790
Embed Views
607

Actions

Likes
8
Downloads
0
Comments
0

10 Embeds 607

http://silviamcgovern.wordpress.com 199
http://www.cosmos-intelligence.com 183
http://www.paginasfacebook.net 107
http://www.paginasfacebook.com 71
http://www.slashdocs.com 28
http://cosmos-intelligence.com 8
http://moodle.ieselrincon.org 5
http://5791808657584046432_4786126e2c4b75b88bb94f0ecb95bf730363757d.blogspot.com 2
http://websfacebook.blogspot.com.es 2
http://www.cleformacion.com 2
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Seminario Liferay 6.1 sobre gestion avanzada de portales y tecnologias JAVA Empresariales. CLEFormacion Seminario Liferay 6.1 sobre gestion avanzada de portales y tecnologias JAVA Empresariales. CLEFormacion Presentation Transcript

  • Características más importantes de Liferay 6.1 Liferay 6.1 La gestión avanzada de portales y las tecnologías Java Empresariales Viernes 8 de Junio de 2012 Centro de Innovación del BBVA (Madrid) Jesús Salinas Revelleslunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Índice ‣ Introducción. ‣ El panel de control. ‣ Organizaciones y sitios web. ‣ Usuarios y roles. ‣ Trabajando con taxonomías. ‣ Contenidos web. ‣ Multimedia. ‣ Plantillas.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Índice ‣ Flujos de trabajo. ‣ Listas de datos dinámicas. ‣ Redes sociales. ‣ Campos personalizados. ‣ OpenSocial. ‣ Stage. ‣ Configuración.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Introducción ‣ Pasamos a comentar a continuación algunas de las funcionalidades más importantes que nos ofrece Liferay Portal por defecto. ‣ Son funcionalidades que puede aprender a configurar cualquier usuario de la plataforma.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 El panel de control ‣ Introducción. ‣ La sección del usuario. ‣ La sección Liferay. ‣ La sección Portal. ‣ La sección Servidor.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Introducción ‣ El panel de control es la herramienta de administración y configuración del sistema. ‣ Permite al usuario acceder a funcionalidades que ofrece la plataforma en función de su role, es decir, el panel de control es un área dentro del gestor que cambia en función de los permisos que tiene cada usuario. ‣ Para acceder a él, por defecto, se hace mediante la barra Ir a.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Introducción ‣ Si eres administrador el panel de control tiene cuatro secciones: ‣ Cuenta de usuario, Liferay, Portal y Servidor.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Introducción ‣ Si eres editor la barra de administración es muy limitada y su panel de control también.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 La sección del usuariolunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 La sección Liferaylunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 La sección Portal ‣ Nos permite realizar todo tipo de tareas administrativas: Esta sección nos permite gestionar usuarios, grupos de usuarios, etclunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 La sección Portal Este panel permite listar todos los usuarios, ‣ Gestión de usuarios: añadir, buscar, etc. Esta sección nos Listado de usuarios permite gestionar usuarios, grupos de usuarios, etclunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 La sección Servidor ‣ En esta sección encontramos las siguientes opciones:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organizaciones y sitios web ‣ Hasta la versión 6 de Liferay se manejan dos conceptos: ‣ Organización y ‣ Comunidad. ‣ Para la versión 6.1 desaparece el concepto de Comunidad y se incorpora el concepto de Sitio Web.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organización ‣ Las organizaciones son colecciones de usuarios jerárquica. ‣ Las organizaciones son recursos que pueden tener páginas. ‣ Hay un tipo especial de organización llamado location, que define donde se encuentra. ‣ Las organizaciones son muy útiles para definir las jerarquías a las que pertenecen los usuarios.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organización Una organización es una estructura jerárquica.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organización ‣ Por ejemplo: Se está utilizando Liferay para trabajar con una gran organización. Si se quiere definir el usuario Antonio Molina mediante el organigrama de la empresa. Se supone que trabaja como ingeniero informático en la oficina de Sevilla, en la división Sur, en el departamento de I+D+i. Este usuario debe ser miembro de las siguientes organizaciones: ‣ I+D+i. ‣ División Sur. ‣ Localización Sevilla. ‣ Las organizaciones pueden formar parte de un sitio web.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organización ‣ Los miembros de una organización SÓLO pueden ser usuarios:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Organización ‣ Se pueden asignar roles de organización a una organización, de tal forma que, todos los usuarios que pertenezcan a dicha organización automáticamente tendrá esos roles:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Sitio web ‣ Como ya se ha comentado antes, el sitio web es la evolución del antiguo concepto de comunidad:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Sitio web ‣ Para cada sitio web podemos realizar las siguientes operaciones:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Sitio web ‣ Por ejemplo, se pueden gestionar los miembros de un sitio web:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Usuarios ‣ Personas que acceden de alguna forma al portal que se quiere desarrollar:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Usuarios ‣ Los usuarios pueden acceder a los portales, los usuarios pertenecen a organizaciones o sitios web. Pueden agruparse de varias formas: ‣ Miembros de organizaciones. ‣ Pueden encontrarse dentro de grupos de usuarios. ‣ Miembros de sitios web. ‣ Los usuarios tienen asociados unos roles que definen qué pueden y qué no pueden hacer en función de dónde se encuentran.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Usuarios ‣ Los usuarios pueden acceder a los portales. ‣ Los usuarios se organizan en grupos de usuarios. ‣ Los usuarios pertenecen a organizaciones. ‣ Las organizaciones pueden organizarse en jerarquías. ‣ Los usuarios, grupos y organizaciones pueden pertenecer a comunidades que tienen un interés común.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Grupo de usuarios ‣ Conjunto arbitrario de usuarios creado por un administrador.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Grupo de usuarios ‣ Sólo usuarios pueden ser miembros de un grupo:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Grupo de usuarios ‣ Un grupo de usuarios puede tener asociado un conjunto de páginas. ‣ Importante: un grupo de usuarios NO pueden tener asociados roles.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Equipos ‣ Grupo de usuarios definido exclusivamente para un sitio web:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Equipos ‣ Se dan de alta usuarios dentro de un equipo:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Equipos ‣ Una vez definido un equipo, se pueden definir permisos en las aplicaciones del portal sobre estos (siempre sobre el sitio web donde hayan sido definidos).lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Roles ‣ Identificador lógico que tiene asociado una serie de permisos. ‣ Existen tres tipos: ‣ Roles normales. ‣ Roles de organización. ‣ Roles de sitios. ‣ Se les denomina role scopes. Estos roles se utilizan para definir permisos dentro de un portal, organización o comunidad. ‣ Usuarios, comunidades y organizaciones pueden asociarse a un determinado role.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ La gestión de categorías se realiza mediante el panel de control, dentro de la sección Liferay:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ Se pueden crear nuevos vocabularios, por ejemplo, un vocabulario para el portal del Empleado. ‣ Se puede definir la visibilidad del vocabulario en función del role del usuario.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ Se pueden crear categoría asociadas a un vocabulariolunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ La gestión de etiquetas se realiza mediante el panel de control, dentro de la sección Liferay:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ Se pueden crear etiquetas:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Trabajando con taxonomías ‣ Como ya se ha comentado en la introducción, la clave de las etiquetas es que pueden ser creadas por el usuario de forma totalmente flexible y dinámica.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ La generación de contenidos web es uno de los elementos más importantes dentro del concepto de portal, dado que permite, a los gestores del portal y a los usuarios que acceden a él, dotar de contenidos a la herramienta. ‣ Liferay ofrece una serie de funcionalidades que permite generar, revisar y mantener contenidos web de una forma cómoda, flexible y avanzada: ‣ Editor de contenidos web: WYSWYG. ‣ Portlets auxiliares para el manejo de contenidos. ‣ Integración con flujos de trabajo. ‣ ...lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ Dentro de la sección Liferay podemos encontrar un enlace llamado Contenidos Web:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ Esta sección nos permite crear, editar, borrar y buscar contenidos web.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ La lista de portlets para la gestión de contenidos se encuentra disponible mediante la opción Añadir de la barra superior, en la opción Más:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ Liferay permite crear contenidos web totalmente personalizados. ‣ De forma estándar, cuando se quiere crear contenidos web se utiliza el portlet Contenido web accesible desde el panel de control:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Contenidos web ‣ Hasta ahora no hemos tenido en cuenta: Las estructuras y las plantillas nos permitirán ofrecer valor añadido a la hora de definir nuevos contenidos weblunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Soporte a múltiples lenguajes ‣ Liferay proporciona soporte a diferentes lenguajes, la gestión de contenidos web no podía ser menos. ‣ Podemos definir el mismo contenido web en diferentes idiomas, de tal manera que si se cambia el idioma de visualización de contenidos, cambia también el del contenido web. ‣ El proceso se realiza mediante una etiqueta llamada localizado (en español).lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Soporte a múltiples lenguajes ‣ Se crea un documento en inglés:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Soporte a múltiples lenguajes ‣ Posteriormente se edita:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Soporte a múltiples lenguajes ‣ El documento se edita cambian el idioma en el que está escrito:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Multimedia ‣ Documentos y Multimedia actúa como un disco compartido virtual, con atributos y metadatos de fichero, versionado y personalización de carpetas. ‣ Los administradores pueden manejar carpetas y documentos, cambiar los permisos y navegar por la biblioteca de documentos.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Multimedia ‣ Interfaz de usuario innovadora, drag and drop, selección con ratón. ‣ Repositorio unificado: conecta a múltiples repositorios: sharepoint, documentum, alfresco. ‣ Previsualización de formatos estándares. ‣ Definir nuevos tipos de documentos: los documentos tienen características específicas: formulario visual para que el usuario pueda incorporar. ‣ Aplicación iphone. ‣ Dropbox: Liferay Sync.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Plantillaslunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Flujos de trabajo ‣ Configuración de los flujos de trabajo utilizados dentro de Liferay:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Listas de datos dinámicas ‣ Esta nueva funcionalidad nos permite crear listas dinámicas:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Listas de datos dinámicas ‣ Se pueden definir los datos a manejar:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Listas de datos dinámicas ‣ El visor nos permite manejar dichas listas:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Redes sociales ‣ Introducción. ‣ Blogs. ‣ Calendario. ‣ Wiki. ‣ Foro. ‣ Mail. ‣ Proyectos de la comunidad.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Introducción ‣ Liferay portal proporciona un conjunto de aplicaciones colaborativas que pueden usarse para construir comunidades de usuarios para tus webs. ‣ Todas estas aplicaciones comparten una apariencia común, modelo de seguridad, etc. ‣ Vamos a analizar cómo configurar y administrar blogs, calendarios, chats,wikis, foros y correo electrónico.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ El término blog procede de web log, web diaria, en español también conocido como bitácora. ‣ No es más que una lista de entradas donde los usuarios pueden asociar comentarios. ‣ Un blog es un sitio web que recopila textos o artículos de uno o varios autores, apareciendo primero el más reciente, a los que los lectores pueden asociar comentarios.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ Liferay tiene un portlet llamado Blogs que permite proporcionar un servicio de blogs para los usuarios de la web. ‣ Asociado a este existe un segundo portlet llamado Blogs Aggregator que recupera entradas de distintos y las organiza en una lista.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ Portlet Blogs: ‣ Sólo puede crearse una instancia por comunidad u organización. ‣ Si se añade un portlet de este tipo a la página de una comunidad u organización, se crea un blog compartido para los miembros de la comunidad u organización. ‣ Si se añade este portlet al espacio personal de un usuario sólo será para el usuario.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ Portlet Blogs. Configuración: ‣ Por defecto, sólo el dueño de la comunidad puede añadir entradas al blog. ‣ Para modificar este comportamiento se deben cambiar los permisos asociados. ‣ Una vez solventados los problemas de permisos, el usuario podrá incluir entradas en el blog haciendo click sobre el botón:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ Portlet Blogs. Crear entradas:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Blogs ‣ Agregador de blogs: ‣ Te permite publicar entradas de diferentes bloggers en una página.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Calendario ‣ El portlet Agenda (Calendar portlet) es una solución de calendario muy completa:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Calendario ‣ Se pueden incorporar eventos de diferentes tipos, recibir alarmas vía email o sms, importar o exportar el calendario, etc. ‣ También se pueden importar y exportar calendarios en formato ICS para usarlo en otras aplicaciones. ‣ Los calendarios se pueden utilizar como calendarios compartidos para una comunidad u organización, o como calendarios personales. Esto se configura definiendo un determinado ámbito dentro de la configuración del portlet:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Wiki ‣ El portlet Wiki ofrece una aplicación Wiki con todas las características que se esperan.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ El portlet nos ofrece en la barra principal enlaces para acceder a Mensajes recientes, Mis mensajes, etc. ‣ Se pueden añadir nuevas categorías y crear nuevos hilos de discusión.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ Categorías: ‣ Se pueden buscar y crear categorías dentro del foro, es una forma de organizar el flujo de información.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ Asociados a cada categoría se crean hilos de discusión:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ Mis mensajes: ‣ Se puede localizar de una forma sencilla todos los mensajes que a creado un usuario:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ Mis suscripciones: ‣ El usuario puede suscribirse a categorías. Se selecciona la categoría y mediante el botón Acciones se marca la opción Suscribirse. ‣ Una vez añadidas las suscripciones, en la pestaña Mis suscripciones estarán disponibles para un acceso rápido.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Foros ‣ Mensajes recientes:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Mails ‣ Cada usuario tiene la posibilidad de consultar su correo electrónico previamente configurado o configurar nuevas cuentas de correo electrónico. Para configurar una cuenta se debe hacer click sobre la opción añadir cuenta de correo electrónico:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Mails ‣ Por ejemplo:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Vaadin Maillunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Proyectos de la comunidadlunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Proyectos de la comunidadlunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Campos personalizados ‣ Existe un mecanismo para añadir nuevos campos a la entidades que ya existen en el núcleo de Liferay sin necesidad de modificar el modelo y sus servicios asociados. ‣ Este mecanismo se conoce como Campos personalizados. ‣ Desde el panel de control se puede acceder a la funcionalidad que comentamos:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Campos personalizados ‣ Seleccionando la opción Editar pueden añadirse campos: ‣ Se debe definir una clave y un tipo de dato.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Campos personalizados ‣ Los tipos disponibles para la versión 6 de Liferay son:lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 OpenSocial ‣ Liferay Portal 6 ofrece un contenedor OpenSocial basado en Shindig. ‣ Gadgets OpenSocial permite incluir en nuestras aplicaciones este tipo de aplicaciones.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 OpenSocial ‣ Por ejemplo: ‣ http://www.labpixies.com/campaigns/todo/todo.xml ‣ http://www.google.com/ig/modules/horoscope.xmllunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Stage ‣ Mecanismo muy interesante para poder actualizar los contenidos de un determinado portal y pasarlo a producción cuando sea necesario. ‣ Este sistema ha evolucionado mucho en esta última versión.lunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Configuración de un sitio weblunes 11 de junio de 2012
  • Características más importantes de Liferay 6.1 Configuración de la plataformalunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Liferay 6.1 La gestión avanzada de portales y las tecnologías Java Empresariales Viernes 8 de Junio de 2012 Centro de Innovación del BBVA (Madrid) Jesús Salinas Revelleslunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Índice de contenidos ‣ Introducción. ‣ ¿Cuándo? ‣ ¿Dónde? ‣ Portal. ‣ Plugin Portlets. ‣ Plugin Ext. ‣ Plugin Hook.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Liferay nos ofrece una serie de funcionalidades por defecto que nos hacen la vida más fácil y que en muchos casos, pueden encajar con los servicios que necesita nuestro cliente. ‣ En muchas otras ocasiones esto no será posible, el desarrollador tiene que incluir nueva funcionalidad en la plataforma. ‣ Capacidad de integración: ‣ Nos ofrece diferentes estrategias para incorporar nuevas funcionalidades dentro de la plataforma.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción Gestores Bases de datos documentales Motores de Motores de Liferay Portal Informes workflow Sistemas de gestión ... integrallunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Liferay nos permite crear módulos/piezas software apoyándonos en los frameworks JavaEE más conocidos: ‣ Capa de presentación: Struts, JavaServer Faces, etc. ‣ Capa de negocio: Spring Framework (POA, IoC, gestión de transacciones). ‣ Capa de persistencia: Hibernate, iBatis, etc. ‣ También se puede trabajar con tecnología Servlet y JSP. ‣ El desarrollador puede aprovechar su Know-How para crear infinidad de aplicaciones que posteriormente podrán integrarse en una plataforma común de forma sencilla y simple.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Como ya se ha comentado antes, Liferay permite al desarrollador crear nuevas funcionalidades utilizando diferentes estrategias. ‣ Estas estrategias de desarrollo deben conocerse, sabiendo cuál elegir en cada momento. ‣ Una mala decisión puede condicionar en gran medida el éxito o el fracaso de un desarrollo. Éstas son: ‣ Plugin Portlet. ‣ Plugin Hook. ‣ Plugin Ext.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cuándo? ‣ Como ya se ha comentado antes, tenemos tres alternativas cuando desarrollamos nuevas funcionalidades en Liferay: ‣ Portlets: desarrollos nuevos que no tienen nada que ver con portlets que ya existen en Liferay. ‣ Hooks: modificaciones no muy profundas sobre el core del producto. ‣ Ext: modificaciones profundas de la plataforma.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Dónde? ‣ Herramientas disponibles para desarrollar: ‣ Eclipse Liferay IDE. ‣ NetBeans. ‣ Cualquier herramienta de desarrollo que trabaje con Java.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Dónde?lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Dónde? ‣ Trabajando con Plugin SDKlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Portal ‣ Un portal es una aplicación web que proporciona personalización, autenticación, mecanismos para incorporar contenidos en una página web y centraliza la capa de presentación de un sistema de información. ‣ Un portal debe tener características avanzadas para la personalización de los contenidos de usuario. ‣ Las páginas de un portal pueden estar formadas por los contenidos generados por diferentes portlets.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Portal ‣ Todas las características de un portal se apoyan en el siguiente concepto: ‣ Integrar diferentes aplicaciones en la misma pantalla. ‣ El usuario interactúa con el portal y el portal interactúa con diferentes aplicaciones de backend, integrándolas a todas en una única ventana del navegador sobre la que el usuario actúa. ‣ Esta integración habitualmente se conoce como at the glass.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Portal ‣ Analicemos las características más importantes de la definición de portal: ‣ Personalización de usuario: permite que el usuario personalice los contenidos que ve en las páginas del portal. ‣ Personalización del backend: permite al administrador personalizar un determinado componente para un entorno específico. ‣ Single sign on: el usuario tendrá que autenticarse una sola vez. ‣ Incorporación de contenido: ‣ Concepto de componente: permite que se desarrollen componentes que se puedan incorporar en el portal. Son como bloques de construcción.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plugin Portlet ‣ Introducción. ‣ ¿Qué es un portlet? ‣ ¿Quién puede construir un portlet? ‣ ¿Cómo se construye un portlet?lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ La tecnología Portlet va a permitir al desarrollador crear componentes de interfaz de usuario intercambiables e independientes para construir páginas en portales web. ‣ Se basa en tecnología Java. ‣ Java Community Process es el organismo que actúa como mecanismo para desarrollar especificaciones técnicas estándares para tecnologías Java. ‣ Se ha encargado de definir la especificación estándar de Portlets. Ésta explica cuáles son los requisitos que se deben cumplir para crear aplicaciones que cumplan la especificación. ‣ http://www.jcp.orglunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ La web del JCP (Java Community Process) proporciona información muy interesante sobre las distintas especificaciones. ‣ Éstas se organizan en documentos llamados Java Specification Requests, habitualmente conocidos como JSRs.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Existen dos versiones de la especificación Portlets, y se conocen como: ‣ JSR-168: Especificación de Portlets v 1.0 ‣ JSR-286: Especificación de Portlets v 2.0lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Es una aplicación que genera una porción de contenido que puede ser incluido dentro de la página de un portal: Ventana del portlet Modos y estados del portlets Fragmento de marcadolunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Es un componente web basado en tecnología Java que se encarga de procesar peticiones y generar contenido dinámico: ... public class MiPortlet extends GenericPortlet { private static final String NORMAL_VIEW = "/normal.jsp"; private static final String MAXIMIZED_VIEW = "/ maximized.jsp"; private static final String HELP_VIEW = "/help.jsp"; private PortletRequestDispatcher normalView; private PortletRequestDispatcher maximizedView; private PortletRequestDispatcher helpView; public void doView( RenderRequest request, RenderResponse response ) throws PortletException, IOException { if( WindowState.MINIMIZED.equals ( request.getWindowState() ) ) { ! return; } ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Los portales usan a los portlets como componentes de interface de usuario intercambiables que proporcionan la capa de presentación a un sistema de información.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ El contenido generado por un portlet se llama fragmento y, no es más que un trozo de código de marcado. ‣ Estos fragmentos tienen que cumplir una serie de reglas para que puedan agruparse con otros fragmentos para generar un documento completo. ‣ El contenido generado por un portlet se agrupa junto con el contenido de otros portlets para crear la página de un portal. ‣ El ciclo de vida de un portlet es controlado mediante el contenedor de portlets.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Estados de la ventana: ‣ La ventana de un portlet se puede encontrar en diferentes estados. Los estados por defectos son: ‣ Normal. ‣ Maximizado. ‣ Minimizado.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Estados de la ventana: Este botón hace que la ventana pase a ‣ Normal y minimizado: estado minimizado Si de nuevo se hace click en este botón se vuelve al estado normallunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Qué es un portlet? ‣ Estados de la ventana: Este botón hace que la ventana pase a ‣ Normal y maximizado: estado maximizado Si se hace click en este botón se vuelve al estado normallunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Quién puede construir un portlet? ‣ Desarrolladores que conocen las tecnologías JavaEE core: Servlets y JSP: ‣ La especificación de Portlets es muy similar a la especificación de Servlets. ‣ Conocida una, conocidas todas. ‣ Las especificación de Portlets trabaja con JSP para generar la vista. ‣ Desarrolladores JavaEE que conocen Framework de desarrollo: ‣ JavaServer Faces, ‣ Struts, ‣ etc.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Creación de una clase que hereda de GenericPortlet:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Ejemplo: ... public class PortletBasico extends GenericPortlet{ ... }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet?lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Renderización: ‣ Como ya se ha comentado antes, esta clase abstracta implementa el método render() de la interface Portlet y proporciona otros métodos en los que delega la renderización del portlet en función del modo en el que se encuentra. ‣ Los modos de un portlet indican la función que está proporcionando en cada momento. La especificación define tres modos: ‣ view. ‣ help. ‣ edit.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Renderización: ‣ Sus métodos de renderización son: ‣ doView(): método llamado por el método render cuando el portlet se encuentra en modo view. ‣ doHelp(): método llamado por el método render cuando el portlet se encuentra en modo help. ‣ doEdit(): método llamado por el método render cuando el portlet se encuentra en modo edit.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Acciones: ‣ El método processAction() debe redefinirse para construir la acción que quiere desarrollar el portlet: public void processAction(ActionRequest request, ActionResponse response) ! ! ! throws PortletException, IOException { ! // Se recuperan los parámetros de la petición ! String nombre = request.getParameter("nombre"); ! String ruta = request.getParameter("ruta"); ! String contenido = request.getParameter("contenido"); ... }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Acciones: ‣ El contenedor de portlets llama al método processAction() para permitir que el portlet procese una acción asociada a la petición. ‣ Este método es invocado si la petición del cliente fue originada por una URL creada mediante el método RenderResponse.createActionURL().lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Construyendo acciones en un portlet: ‣ El método processAction() se ejecuta cada vez que un portlet tiene que realizar una acción. ‣ ¿Si tiene que ejecutar varias acciones? ¿el método processAction() tiene que manejar todas las acciones? ... public void processAction(...){ ... if(...){ }else if(){ } ... }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se construye un portlet? ‣ Construyendo acciones en un portlet: ‣ Gracias a la anotación @ProcessAction el portlet puede tener tantos métodos diferentes como acciones tenga que llevar a cabo. Evidentemente, la cabecera del método debe cumplir unos requisitos: @ProcessAction(name="guardarFichero") public void accion1(ActionRequest request, ActionResponse response) throws PortletException,IOException @ProcessAction(name="borrarFichero") public void accion2(ActionRequest request, ActionResponse response) throws PortletException,IOExceptionlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración ‣ Fichero portlet.xml. ‣ Fichero liferay-display.xml. ‣ Fichero liferay-portlet.xml. ‣ Fichero liferay-plugin-package.properties.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero portlet.xml ‣ El descriptor de despliegue estándar para portlets se llama portlet.xml. ‣ Es un fichero xml que permite definir las características de los portlets que se están manejando. ‣ Ejemplo: <?xml version="1.0" encoding="UTF-8"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet- app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/ portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> <portlet> ... </portlet> </portlet-app>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-display.xml ‣ Este fichero permite definir la categoría donde se podrán encontrar el portlet dentro de Liferay una vez se despliegue. <?xml version="1.0"?> <!DOCTYPE display PUBLIC "-//Liferay//DTD Display 5.2.0//EN" "http://www.liferay.com/dtd/liferay-display_5_2_0.dtd"> <display> Identificador INTERNACIONALIZADO de la <category name=" category.sample "> categoría donde se quiere incluir el portlet <portlet id=" PortletBasico01 " /> </category> El atributo id debe coincidir </display> con el nombre del portlet que se ha definido en el fichero portlet.xmllunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-display.xml La categoría definida en el fichero liferay- display.xml determina la categoría donde se podrá encontrarlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-portlet.xml ‣ Este fichero es la extensión de portlet.xml para Liferay. ‣ Se encarga de definir características avanzadas del portlet: ‣ icon: define el icono que aparece en la ventana del portlet. ‣ instanceable: si este elemento está a true significa que puede aparecer en la página tantas veces como se quiera. En cambio si su valor es false, sólo podrá aparecer una vez. ‣ css-class-wrapper: nombre del class asociado al div que va a envolver este portlet cuando se renderize en la página del portal. ‣ header-portlet-css. ‣ ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-portlet.xml ‣ Ejemplo: <?xml version="1.0"?> <!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay- portlet-app_5_2_0.dtd"> <liferay-portlet-app> <portlet> <portlet-name>PortletBasico01</portlet-name> <icon>/icon.png</icon> <instanceable>true</instanceable> <header-portlet-css>/css/test.css</header-portlet-css> <footer-portlet-javascript>/js/test.js</footer-portlet- javascript> </portlet> </liferay-portlet-app>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-plugin- package.properties name=PortletBasico01 module-group-id=liferay module-incremental-version=1 tags= short-description= change-log= page-url=http://www.liferay.com author=Liferay, Inc. licenses=MITlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejercicio ‣ Paso 1: Listado de documentos.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejercicio ‣ Paso 2: Creación de documentos.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejerciciolunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plugin Ext ‣ Introducción. ‣ Estrategia de desarrollo. ‣ Trabajando con el entorno. ‣ Despliegue del plugin Ext.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ El plugin Extension es el plugin que proporciona un mayor nivel de personalización del portal Liferay. ‣ Se puede cambiar cualquier cosa del producto. ‣ Plugin Ext ha sido creado para proporcionar una forma de separar el código introducido por el programador y el código de Liferay, de tal forma que los desarrolladores pueden saber dónde empieza su código y dónde el de Liferay. ‣ No se debe modificar el código de Liferay directamente para realizar cambios en el producto. Se mantiene el código separado y el plugin se encarga de solapara tus cambios encima del código de Liferay. ‣ Esto también hace que las actualizaciones de versión sean más sencillas, dado que se puede actualizar Liferay y posteriormente, inyectar el plugin Ext para la nueva versión.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Estrategia de desarrollo ‣ La estrategia para usar este plugin es muy simple: extender, no modificar.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Trabajando con el entorno ‣ Clase StrutsPortlet. ‣ Fichero liferay-portlet.xml. ‣ Definición de acciones. ‣ Definición de la navegación. ‣ Páginas JSP.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Clase StrutsPortlet ‣ Se encuentra en el paquete com.liferay.portlet. ‣ Es el portlet diseñado por Liferay para integrar el Framework Struts. ‣ El fichero portlet.xml debe tenerlo en cuenta: <?xml version="1.0"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/ portlet-app_2_0.xsd"version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance" xsi:schemaLocation="http://java.sun.com/xml/ns/ portlet/portlet-app_2_0.xsd http://java.sun.com/ xml/ns/portlet/portlet-app_2_0.xsd"> <portlet> <portlet-name>portletEjercicio</portlet-name> <display-name>portletEjercicio</display-name> <portlet-class> com.liferay.portlet.StrutsPortlet </portlet-class>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Clase StrutsPortlet ‣ Este portlet trabaja con parámetros iniciales que determinan las urls asociadas a los modos VIEW, HELP y EDIT, si existen. ‣ Se configuran en el fichero portlet.xml: <portlet> ! <portlet-name>ProyectoStruts</portlet-name> ! <display-name>ProyectoStruts</display-name> ! <portlet-class>com.liferay.portlet.StrutsPortlet</portlet- class> ! <init-param> ! ! <name>view-action</name> ! ! <value>/jsp/input</value> ! </init-param> ! <init-param> ! ! <name>help-action</name> ! ! <value>/jsp/help</value> ! </init-param> ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-portlet.xml ‣ Se configura la ruta de Struts que se va a manejar: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay- portlet-app_5_2_0.dtd"> <liferay-portlet-app> <portlet> <portlet-name>ProyectoStruts</portlet-name> <icon>/images/world.png</icon> <struts-path>jsp</struts-path> <use-default-template>true</use-default-template> <restore-current-view>true</restore-current-view> <instanceable>true</instanceable> <private-request-attributes>false</private-request- attributes> </portlet> ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Definición de acciones ‣ Las acciones son clases Java que heredan de PortletAction: public class Accion01 extends PortletAction { @Override public void processAction( ActionMapping mapping, ActionForm form, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { ... ‣ Habitualmente se redefinen los métodos processAction y render.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Definición de la navegación ‣ Se realiza mediante el fichero struts-config.xml. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http:// jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <action-mappings> <action path="/jsp/input" forward="/portlet/jsp/ listarUsuarios.jsp"></action> <action path="/jsp/borrar" type="acciones.BorrarUsuarioAction"input="/jsp/ inicio.jsp"> <forward name="exito" path="/portlet/jsp/ listarUsuarios.jsp"></forward> </action>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Páginas JSP ‣ Se define de forma totalmente normal, pero debe encontrarse en la ruta html/portlet/. Ejemplo 1: <action path="/jsp/input" forward="/portlet/jsp/paginaPrueba.jsp"> </action> ‣ La página debe encontrarse en la ruta html/portlet/jsp/paginaPrueba.jsp. ‣ Ejemplo 2: <action path="/portal/layout" type="com.liferay.portal.action.LayoutAction"> ! <forward name="portal.layout" path="portal.layout" /> </action> <definition name="portal.layout" extends="portal"> ! <put name="content" value="/portal/layout.jsp" /> ! <put name="selectable" value="true" /> </definition>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Despliegue del plugin Ext ‣ Los plugins Ext son plugins que se pueden desplegar en caliente como los hooks y los portlets, pero, cuidado, esto puede ser engañoso. ‣ Estos plugins son más parecidos al entorno Ext utilizado en anteriores versiones de Liferay en la forma de trabajar con él. ‣ Existen dos formas de desplegar un plugin Ext: ‣ Mediante los scripts Ant disponibles en Plugins SDK, especialmente deploy y direct-deploy. ‣ Creando un fichero war y desplegándolo manualmente en Liferay: ‣ Copiándolo en la carpeta deploy de la instalación. ‣ Mediante la interfaz web.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Despliegue del plugin Ext ‣ Independientemente del proceso de despliegue utilizado, posteriormente, ocurre lo mismo, y no tiene nada que ver con lo que ocurre cuando se despliega otro tipo de plugin: ‣ Se crea ext-service.jar a partir del código que se encuentra en la carpeta ext-service/src. ‣ Se despliega este jar classpath global. El deployer hace esto después de extraerlo del war, o el script Ant lo hace como parte de direct-deploy. ‣ Se crea ext-impl.jar a partir del código que se encuentra en la carpeta ext-impl/src. ‣ El deployer o script entonces comienza a copiar los ficheros en Liferay. Primero, despliega cualquier fichero portal-*.properties o system- *.properties en la carpeta WEB-INF/classes. Y posteriormente, despliega el fichero ext-impl.jar en la carpeta WEB-INF/lib de Liferay. ‣ El deployer o el script copia las carpetas que existen en la carpeta ext- web en la carpeta de Liferay asociada integrando así los cambios con el código de Liferay.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Despliegue del plugin Ext ‣ Debido a estas operaciones, el despliegue de un plugin Ext implica un posterior restart del servidor obligatorio. ‣ El código que aparece en el plugin Ext no se encuentra aislado, forma parte del código de Liferay. Se ejecuta como parte de la aplicación, de la misma forma que lo hace el código de Liferay. ‣ La primera consecuencia de todo esto es que NO se puede deshacer un proceso de despliege. Se necesita tener una copia limpia de nuestra instalación por si comentemos errores. ‣ Se recomienda hacer un proceso de despliegue incremental, siempre sabiendo que si se hace algo más podemos volver a la instalación de Liferay inicial.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Despliegue del plugin Ext cd your-tomcat-install # deleting web application rm -rf webapps/*-ext # deleting jars and config files from Liferay find -name "ext-*" | xargs rm -rf # stopping Liferay bin/shutdown.sh ps ax | grep life #... wait until life ends ;) ....# ps ax | grep life #... wait until life ends ;) ....# ps ax | grep life #... wait until life ends ;) ....# # Starting Liferay bin/startup.sh tail -f logs/catalina.outlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejercicio ‣ Introducción. ‣ Creación de plugin Ext. ‣ Disponibilidad del portlet. ‣ Estado de la ventana del portlet. ‣ Visualización de contenidos. ‣ Inspección del portlet. ‣ Modificación del portlet. ‣ Conclusión.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ El portlet Mi cuenta/My Account es elemento muy habitual dentro de Liferay portal.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Lamentablemente, por defecto, no se encuentra disponible para su uso en cualquier página de Liferay, sólo a través del panel de control. ‣ Vamos, aprovechando el plugin Ext, a realizar las modificaciones necesarias para que pueda ser utilizado en cualquier sitio. ‣ Posteriormente, lo personalizaremos para que muestre sólo la información que sea necesaria.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Creación de plugin Ext ‣ Trabajando con Eclipse IDE y plugin SDK implica seguir un asistente. ‣ La estructura del proyecto, como ya es sabido, es tal que así:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Disponibilidad del portlet ‣ El primer paso será, editar el fichero de sistema liferay- portlet.xml eliminando del portlet 2 la entrada <system>true</system>. ‣ De esa forma el portlet de administración My Account se encontrará disponible para ser utilizado. <liferay-portlet-app> <portlet> ! <portlet-name>2</portlet-name> ! <icon>/html/icons/my_account.png</icon> ! <struts-path>my_account</struts-path> ! ... ! <system>true</system> </portlet>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Disponibilidad del portlet ‣ El segundo paso será modificar el plugin Ext previamente creado para añadir el fichero portal.xml un directorio llamado resource-actions previamente creado.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Disponibilidad del portlet <portlet-resource> <portlet-name>125</portlet-name> <permissions> <supports> <action-key>ADD_TO_PAGE</action-key> <action-key>ACCESS_IN_CONTROL_PANEL</action-key> <action-key>CONFIGURATION</action-key> <action-key>EXPORT_USER</action-key> <action-key>VIEW</action-key> </supports> <community-defaults> <action-key>VIEW</action-key> </community-defaults> <guest-defaults> <action-key>VIEW</action-key> </guest-defaults> <guest-unsupported> <action-key>ACCESS_IN_CONTROL_PANEL</action-key> <action-key>CONFIGURATION</action-key> </guest-unsupported> </permissions> </portlet-resource>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Estado de la ventana del portlet ‣ Por defecto, el portlet aparece minimizado y sólo si se maximiza se muestra la información del usuario. ‣ Esto es así debido a la configuración de una clase llamada ViewAction asociada al portlet. ‣ Para modificar su comportamiento, mediante el entorno Ext sobrescribimos dicha clase.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Estado de la ventana del portlet ‣ Redefinir el método render: public class ViewAction extends PortletAction { public ActionForward render( ! ActionMapping mapping, ActionForm form, PortletConfig portletConfig, ! RenderRequest renderRequest, RenderResponse renderResponse)throws Exception { ! ! ... ! ! ! } }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Visualización de contenidos ‣ Una vez resuelto el problema de la disponibilidad del portlet, se describe el proceso de personalización.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Visualización de contenidos ‣ Se quiere modificar el portlet para que muestre algo tal que así, se quieren modificar las secciones y los elementos que aparecen en cada sección.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Visualización de contenidos ‣ ¿Cómo se construye la barra lateral? ‣ ¿Y el panel de detalle? ‣ Obligatoriamente el programador necesita conocer el código de este portlet. ‣ StrutsPortlet: ‣ view-action: /my_account/viewlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Inspección del portlet ‣ Se busca el portlet en el fichero portlet.xml identificando el parámetro view-action. <portlet> <portlet-name>2</portlet-name> <display-name>My Account</display-name> <portlet-class> com.liferay.portlet.StrutsPortlet </portlet-class> <init-param> <name>view-action</name> <value>/my_account/view</value> </init-param> ! ! ... </portlet>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Inspección del portlet ‣ Con ese parámetro se busca en el fichero struts-config.xml: ... <action path="/my_account/view" type="com.liferay.portlet.myaccount.action.ViewAction"> <forward name="portlet.my_account.edit_user" path="portlet.enterprise_admin.edit_user" /> <forward name="portlet.my_account.view" path="portlet.my_account.view" /> </action> ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Inspección del portlet ‣ Con el atributo path de la entrada forward busco en el fichero tiles-def.xml: ... <definition name="portlet.enterprise_admin.edit_user" extends="portlet.enterprise_admin"> ! <put name="portlet_content" value="/portlet/enterprise_admin/edit_user.jsp" /> </definition> ... ‣ La página edit_user.jsp del portlet de admin es el punto de partida.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Inspección del portlet ‣ Secciones de la página: ... String[] mainSections = PropsValues.USERS_FORM_ADD_MAIN; String[] identificationSections = PropsValues.USERS_FORM_ADD_IDENTIFICATION; String[] miscellaneousSections = PropsValues.USERS_FORM_ADD_MISCELLANEOUS; ... ‣ Se cargan a través del portal.propertieslunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Inspección del portlet ‣ Fichero portal.properties estándar: ... users.form.my.account.main=details,password,organizations,commun ities,user-groups,roles,categorization users.form.my.account.identification=addresses,phone- numbers,additional-email-addresses,websites,instant- messenger,social-network,sms,open-id users.form.my.account.miscellaneous=announcements,display- settings,comments,custom-fields ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ La modificación de la barra lateral implica la personalización de estos campos en el fichero portal-ext.properties. ‣ Por ejemplo: ... # La seccion Varios solo muestra los siguientes elementos users.form.my.account.miscellaneous=display-settings,comments ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Si se quieren añadir nuevas secciones o borrar alguna de las que existe se deberá modificar el código de la página jsp: // Secciones por defecto String[] mainSections = PropsValues.USERS_FORM_ADD_MAIN; String[] identificationSections = PropsValues.USERS_FORM_ADD_IDENTIFICATION; String[] miscellaneousSections = PropsValues.USERS_FORM_ADD_MISCELLANEOUS; // Nueva seccion: Informacion profesional String [] professionalSections = {"dependency","job","security-level", "licence-number","professional-skill"};lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Si se quieren añadir nuevas secciones o borrar alguna de las que existe se deberá modificar el código de la página jsp (cont.): ... String[] allSections = ArrayUtil.append(mainSections, ArrayUtil.append(identificationSections, miscellaneousSections))); ... ... // Se anade una nueva seccion y se elimina otra String[] allSections = ArrayUtil.append(mainSections, ArrayUtil.append(identificationSections, professionalSections)); ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Si se quieren añadir nuevas secciones o borrar alguna de las que existe se deberá modificar el código de la página jsp (cont.): ... String[][] categorySections = {mainSections, identificationSections, miscellaneousSections}; ... ... String[][] categorySections = {mainSections, identificationSections, professionalSections}; ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Si se quieren añadir nuevas secciones se deberá modificar el código de la página jsp (cont.): ‣ Nombres de las categorías: private static String[] _CATEGORY_NAMES = {"user-information", "identification", "miscellaneous"}; // Nueva seccion: Informacion profesional private static String[] _CATEGORY_NAMES = {"user-information", "identification","professional-information"};lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet for (String section : allSections) { String sectionId = _getSectionId(section); String sectionJsp = "/html/portlet/enterprise_admin/user/" + _getSectionJsp(section) + ".jsp"; %> <!-- Begin fragment <%= sectionId %> --> <div class="form-section <%= (curSection.equals(section) || curSection.equals(sectionId)) ? "selected" : "aui-helper-hidden- accessible" %>" id="<%= sectionId %>"> ! <liferay-util:include page="<%= sectionJsp %>" /> </div> <!-- End fragment <%= sectionId %> --> <%}%>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Una vez construido el array con todas las categorías se itera sobre cada una de ellas construyendo un div para cada una: <div ...> ! <liferay-util:include page="<%= sectionJsp %>" /> </div> ‣ ¿Se hace un include de una página jsp?? ¿Cuál? String sectionId = _getSectionId(section); String sectionJsp = "/html/portlet/enterprise_admin/user/" + _getSectionJsp(section) + ".jsp";lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Se debe crear una página jsp en la carpeta /html/portlet/ enterprise_admin/user cuyo nombre siga las siguientes reglas: ‣ Elemento addresses -> página addresses.jsp ‣ Elemento contract-date -> página contract_date.jsp ‣ ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación del portlet ‣ Ejemplo: Fichero contract_date.jsp <%@page import="com.liferay.portal.model.User"%> <%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %> <h3><liferay-ui:message key="contract-date" /></h3> <% User selUser = (User)request.getAttribute("user.selUser"); %> <liferay-ui:custom-attribute ! classPK="<%= (selUser != null) ? selUser.getUserId() : 0 %>" ! name="fecha-de-entrada" ! className="com.liferay.portal.model.User"> </liferay-ui:custom-attribute>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Conclusiónlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plugin Hook ‣ Introducción. ‣ Tipos de Hooks.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Los hooks son trozos de código diseñados para puentear Liferay sustituyendo elementos específicos del portal. ‣ El plugin Ext ha sido diseñado con el mismo objetivo: sobrescribir y personalizar Liferay. ‣ ¿Por qué existen dos plugins para realizar la misma operación? ‣ Realmente no sirven para lo mismo, el programador debe tener muy clara la diferencia. ‣ Los Hooks se despliegan en caliente pero su nivel de personalización NO es tan elevado como los plugins Ext.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ El plugin Hook se desarrolla gracias al entorno PluginSDK y almacena dos ficheros de configuración específicos: ‣ Fichero liferay-hook.xml. ‣ Fichero liferay-plugin-package.properties. ‣ La carpeta docroot/WEB-INF/src almacena el código Java a incorporar en el proyecto. ‣ La carpeta docroot almacena las páginas jsp que queremos incluir.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-hook.xml ‣ Proporciona la configuración necesaria para definir el plugin Hook: <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> ... </hook>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero liferay-hook.xml ‣ Los elementos más importantes: ‣ custom-jsp-dir. ‣ language-properties. ‣ portal-properties. ‣ service.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Tipos de Hooks ‣ Fichero portal.properties. ‣ Internacionalización. ‣ Modificación de páginas JSP. ‣ Modificación de servicios.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ Como ya sabemos, la personalización del fichero portal.properties nos permite modificar el comportamiento del producto. ‣ Hasta la versión 5 de Liferay sólo podía hacerse a través de Ext. ‣ El plugin Hook puede modificar el fichero portal.properties de una forma más simple. ‣ Ahora bien, el plugin Hook no puede sobrescribir todas las propiedades. <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> <portal-properties>portal.properties</portal-properties> </hook>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ El último valor nos permite trabajar con Listeners: ‣ value.object.listener.* ‣ Ejemplo: value.object.listener.com.liferay.portal.model.User=com.empresa. model.UserRegistrationListenerlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ Los listeners son una característica muy interesante que podemos utilizar gracias a los Hooks. ‣ Los Hooks nos permiten introducir listerners propios aplicados a cualquier clase del modelo: usuarios, roles, organizaciones, etc. ‣ Para ello, PRIMERO se debe diseñar una clase que hereda de BaseModelListener implementando los métodos que interesen en cada caso, y SEGUNDO, debe incluirse en el fichero de propiedades la configuración necesaria.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ El listener se define como una clase que hereda de la clase BaseModelListener<T>. ‣ Sólo se redefinen los métodos necesarios: ‣ onAfterCreate().lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ Métodos de la clase BaseModelListener:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ Ejemplo: ... public class UserRegistrationListener extends BaseModelListener<User> { @Override public void onAfterCreate(User model) throws ModelListenerException { if (model != null) { ! // Paso 1: Se recupera la informacion del usuario que se ! // acaba de crear. ! String userFullName = model.getFullName(); ! String userEmail = model.getEmailAddress(); ! String userScreenName = model.getScreenName(); ...! !lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificando propiedades del portal.properties ‣ Se añade la configuración: ‣ Fichero liferay-hook.xml: <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> <portal-properties>portal.properties</portal-properties> </hook> ‣ Fichero portal.properties: value.object.listener.com.liferay.portal.model.User=model.UserRe gistrationListenerlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Internacionalización ‣ El elemento language-properties: <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http:// www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> <language-properties> content/Language.properties </language-properties> <language-properties> content/Language_en.properties </language-properties> <language-properties> content/Language_es.properties </language-properties> </hook>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Internacionalización ‣ Los ficheros de propiedades se almacenan dentro de la carpeta docroot/WEB_INF/src: # Portlet MY_ACCOUNT professional-information=Informaci&oacute;n profesional professional-category=Categor&iacute;a profesional contract-type=Tipo de contrato mutua-accidentes=Mutua de accidentes contract-date=Fecha de entrada en la empresa professional-profile=Perfil profesional years-of-experience=Años de experiencia knowledge=Conocimientos especializados training-courses=Cursos de formaci&oacute;n selected-portal=Portal seleccionado selected-language=Idioma seleccionadolunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación de páginas JSP ‣ El elemento custom-jsp-dir: <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http:// www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> ... <custom-jsp-dir>/custom_jsps</custom-jsp-dir> ... </hook> ‣ Se define la ruta a partir de la cual se almacenan las páginas jsp que se solaparán con el core de Liferay.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modificación de servicios ‣ El elemento service: <?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.0.0//EN" "http:// www.liferay.com/dtd/liferay-hook_6_0_0.dtd"> <hook> <service> <service-type> com.liferay.portlet.calendar.service.CalEventLocalService </service-type> <service-impl> com.hook.calendar.service.CalEventLocalServiceImpl </service-impl> </service> </hook> ‣ El hook nos permite redefinir las implementaciones de los servicios que Liferay utiliza para operar.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejemplo ‣ Extensión del portlet Directory:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejemplolunes 11 de junio de 2012
  • Mejora de la productividad mediante la generación avanzada de servicios: Service Builder Liferay 6.1 La gestión avanzada de portales y las tecnologías Java Empresariales Viernes 8 de Junio de 2012 Centro de Innovación del BBVA (Madrid) Jesús Salinas Revelleslunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Índice de contenidos ‣ Introducción. ‣ Fichero service.xml. ‣ Ejercicio.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Es una herramienta desarrollada por Liferay para la creación automática de interfaces y clases que son usadas por el portal o portlets, es decir, nos permite crear servicios Java. ‣ Se puede acceder a estos servicios de diferentes formas: ‣ Acceso local mediante código Java. ‣ Acceso remoto mediante servicios web. ‣ La generación de estas clases e interfaces pasa por construir adecuadamente un fichero xml llamado service.xml, siguiendo una sintaxis específica. ‣ Se pasan a describir a continuación las reglas a seguir para su correcta construcción.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Este fichero permite definir el código que posteriormente va a generar Service builder. ‣ Ejemplo: <?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/ liferay-service-builder_5_2_0.dtd"> <service-builder package-path="com.ext.portlet.reports"> <namespace>Reports</namespace> <entity name="ReportsEntry" local-service="true" remote- service="false" ... > <column name="entryId" type="String" primary="true" /> <column name="companyId" type="String" /> <column name="userId" type="String" /> ... </entity> </service-builder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ El fichero service.xml debe incluir la dtd correspondiente al Service builder adecuado: <?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/ liferay-service-builder_5_2_0.dtd"> <service-builder package-path="com.ext.portlet.reports"> ... </service-builder> ‣ Una vez incluida la DTD se deben incluir los elementos XML necesarios: ‣ Elemento service-builder. ‣ Elemento namespace. ‣ Elemento entity ‣ ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento service-builder: ‣ Es el elemento raíz del fichero, todos los elementos que se definan posteriormente son elementos hijo de este: <!ELEMENT service-builder (author?, namespace, entity+, exceptions?)> ‣ Ejemplo: <?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay- service-builder_5_2_0.dtd"> <service-builder package-path="com.ext.portlet.reports"> ... </service-builder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento service-builder: ‣ Atributo package-path: ‣ Ruta del paquete donde se almacena el código fuente: <?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay- service-builder_5_2_0.dtd"> <service-builder package-path="com.ext.portlet.reports"> ... </service-builder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento entity: ‣ Una entidad habitualmente representa una fachada de negocio y una tabla en la base de datos. Si la entidad no tiene columnas sólo representa una fachada. ‣ Si la entidad tiene columnas, se generan el value object, el POJO que se mapea a la base de datos, y otras utilidades basadas en la definición de órdenes y finders. ‣ Sus elementos hijo son: <!ELEMENT entity (column*, order?, finder*, reference*, tx- required*)>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento entity: ‣ Sus atributos son: <!ATTLIST entity ! name CDATA #REQUIRED ! table CDATA #IMPLIED ! uuid CDATA #IMPLIED ! local-service CDATA #IMPLIED ! remote-service CDATA #IMPLIED ! persistence-class CDATA #IMPLIED ! data-source CDATA #IMPLIED ! session-factory CDATA #IMPLIED ! tx-manager CDATA #IMPLIED ! cache-enabled CDATA #IMPLIED >lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento entity: ‣ Atributo name: nombre de la entidad. ‣ Atributo table: nombre de la tabla donde se mapea la entidad. ‣ Atributo uuid: si el valor está a true, el servicio genera una columna UUID. Por defecto, a false. ‣ Atributo local-service: si está a true, se genera un servicio con interfaces locales. ‣ Atributo remote-service: si está a true, se genera un servicio con interfaces remotas. ‣ Atributo persistence-class: nombre de la clase persistente que se genera.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ Representa una columna en la tabla de una base de datos. ‣ No tiene elementos hijo: <!ELEMENT column (#PCDATA)> ‣ Ejemplo: <column name="entryId" type="String" primary="true" /> <column name="companyId" type="String" />lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ Atributos del elemento: <!ATTLIST column ! name CDATA #REQUIRED ! db-name CDATA #IMPLIED ! type CDATA #REQUIRED ! primary CDATA #IMPLIED ! entity CDATA #IMPLIED ! mapping-key CDATA #IMPLIED ! mapping-table CDATA #IMPLIED ! id-type CDATA #IMPLIED ! id-param CDATA #IMPLIED ! convert-null CDATA #IMPLIED ! localized CDATA #IMPLIED >lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ Atributo name: nombre de la columna, especifica el nombre de los getter y setter en la entidad ‣ type: especifica el tipo de la columna. ‣ Ejemplo: <column name="nombre" type="String" /> ‣ La entidad tiene un método getNombre que devuelve como valor de retorno una cadena de caracteres.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ Nota, tipos en el service builder: ‣ boolean => BOOLEAN. ‣ int, Integer, short => INTEGER. ‣ long => LONG. ‣ float, double => DOUBLE. ‣ String => VARCHAR (<4000), STRING (=4000), TEXT (>4000). ‣ Date => DATE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ primary: si es true, la columna es parte de la clave primaria de la entidad. Si varias columnas tienen este atributo a true, implica que la clave es compuesta. ‣ Ejemplo: <column name="entryId" type="String" primary="true" />lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ entity: nombre de la entidad que se relaciona con este atributo. ‣ mapping-key: clave de mapeo. ‣ mapping-table: tabla de mapeo.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento column: ‣ Los atributos id-type y id-param se utilizan para crear claves primarias que se generan automáticamente cuando se insertan registros en la tabla. ‣ Se pueden implementar de cuatro formas diferentes.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml <entity name="Account" local-service="true" remote-service="true"> ! <!-- PK fields --> ! <column name="accountId" type="long" primary="true" /> ! <!-- Audit fields --> ! <column name="companyId" type="long" /> ! <column name="userId" type="long" /> ! <column name="userName" type="String" /> ! <column name="createDate" type="Date" /> ! <column name="modifiedDate" type="Date" /> ! <!-- Other fields --> ! ... ! <column name="type" type="String" /> ! <column name="size" type="String" /> </entity>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder: ‣ Representa métodos finder que se generarán automáticamente. ‣ Tiene un elemento hijo llamado finder-column: <!ELEMENT finder (finder-column+)> ‣ Ejemplo: <finder name="CompanyId" return-type="Collection"> <finder-column name="companyId" /> </finder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder: ‣ Atributos: <!ATTLIST finder ! name CDATA #REQUIRED ! return-type CDATA #REQUIRED ! unique CDATA #IMPLIED ! where CDATA #IMPLIED ! db-index CDATA #IMPLIED >lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder: ‣ Atributos: ‣ name: nombre del método ‣ return-type: tipo del valor de retorno. Los valores válidos son Collection o el nombre de una entidad. ‣ unique: si es true, el método debe devolver una única entidad. ‣ db-index: si es true, el servicio genera automáticamente un índice SQL para el método. Por defecto el valor es true. ‣ Ejemplo: <finder name="CompanyId" return-type="Collection"> ... </finder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder-column: ‣ Representa una columna a partir de la cuál se busca. ‣ No tiene elementos hijo: <!ELEMENT finder-column (#PCDATA)> ‣ Ejemplo: <finder name="CompanyId" return-type="Collection"> <finder-column name="companyId" /> </finder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder-column: ‣ Atributos: <!ATTLIST finder-column ! name CDATA #REQUIRED ! case-sensitive CDATA #IMPLIED ! comparator CDATA #IMPLIED >lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento finder-column: ‣ Atributos: ‣ name: nombre de la columna. ‣ case-sensitive: valor booleano utilizado si la columna es de tipo String. ‣ comparator: puede tomar como valor =, !=, <, <=, >, >=, o LIKE y es usado para comparar la columna. ‣ Ejemplo: <finder name="CompanyId" return-type="Collection"> ... </finder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Ejemplo: <finder name="CompanyId" return-type="Collection"> ! <finder-column name="companyId" /> </finder> <finder name="UserId" return-type="Collection"> ! <finder-column name="userId" /> </finder> <finder name="C_C" return-type="Collection"> ! <finder-column name="companyId" /> ! <finder-column name="classNameId" /> </finder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento order: ‣ Representa la ordenación por defecto que se aplica a las entidades cuando se envían desde la base de datos. ‣ Tiene un elemento hijo order-column: <!ELEMENT order (order-column+)> ‣ Ejemplo: <order by="asc"> <order-column name="parentLayoutId" /> <order-column name="priority" /> </order>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento order: ‣ Atributos: <!ATTLIST order ! by CDATA #IMPLIED > ‣ El atributo by toma dos valores: ‣ asc o desc: ordenación ascendente o descendente.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento order-column: ‣ Representa la ordenación por defecto que se aplica a las entidades cuando se envían desde la base de datos. ‣ No tiene elementos hijo: <!ELEMENT order-column (#PCDATA)> ‣ Ejemplo: <order by="asc"> <order-column name="parentLayoutId" /> <order-column name="priority" /> </order>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ Elemento order-column: ‣ Atributos: <!ATTLIST order-column ! name CDATA #REQUIRED ! case-sensitive CDATA #IMPLIED ! order-by CDATA #IMPLIED > ‣ El atributo order-by toma dos valores: ‣ asc o desc: ordenación ascendente o descendente. <order> <order-column name="articleId" order-by="asc" /> <order-column name="version" order-by="desc" /> </order>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ejercicio ‣ Introducción. ‣ Fichero service.xml. ‣ Generación del servicio. ‣ Código generado. ‣ Asociaciones.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Se describe a continuación el proceso de utilización de Service builder en el entorno Ext. ‣ Creación del fichero service.xml. ‣ Generación del servicio. ‣ Código generado. ‣ Vamos a crear un servicio que nos permite manejar entidades de tipo Factura.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ La tabla sobre la que se quiere trabajar es: create table Factura ( id_ VARCHAR(75) not null primary key, razonSocial VARCHAR(75) null, cif VARCHAR(75) null, nombreCliente VARCHAR(75) null, fechaServicio DATE null,importe DOUBLE )lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml ‣ El fichero service.xml debe crearse en el directorio ext-impl. ‣ Se crea, para nuestro ejemplo, en el directorio: ‣ src/com/ext/portlet/PortletPruebalunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml <?xml version="1.0"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 5.2.0//EN" "http://www.liferay.com/dtd/liferay- service-builder_5_2_0.dtd"> <service-builder package- path="com.ext.portlet.PortletPrueba"> <namespace>Prueba</namespace> <entity name="Factura" local-service="true" remote- service="false"persistence-class="com.ext.portlet. PortletPrueba.FacturaEntryPersistenceImpl"> <column name="id" type="String" primary="true" /> <column name="razonSocial" type="String" /> <column name="cif" type="String" /> <column name="nombreCliente" type="String" /> <column name="fechaServicio" type="Date" /> <column name="importe" type="Double" /> ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Fichero service.xml <order by="asc"> <order-column name="nombreCliente" case- sensitive="false" /> </order> <finder name="nombreCliente" return-type="Collection"> <finder-column name="nombreCliente" /> </finder> <finder name="cif" return-type="Collection"> <finder-column name="cif" /> </finder> </entity> </service-builder>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Generación del servicio ‣ Una vez construido correctamente el fichero service.xml, la generación del servicio se realiza mediante la herramienta Eclipse:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Código generado ‣ Introducción. ‣ Modelo. ‣ Servicio de persistencia. ‣ Servicio de negocio. ‣ Ficheros de configuración.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Éste se puede clasificar de varias formas. ‣ Si pensamos en los distintos niveles de la aplicación: ‣ Código asociado al modelo. ‣ Código asociado al servicio de persistencia. ‣ Código asociado al servicio de negocio. ‣ Si pensamos en clases e interfaces: ‣ Implementaciones de los servicios. ‣ Especificaciones de los servicios. ‣ En principio, vamos a utilizar la primera para describir el código generado.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ La interface FacturaModel: public interface FacturaModel extends BaseModel<Factura> { ... } ‣ Define todos los métodos set y get necesarios. NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ La interface Factura: ‣ Hereda de FacturaModel. ... public interface Factura extends FacturaModel { } NUNCA DEBE MODIFICARSE DIRECTAMENTE. Esta interface DEBE utilizarse SIEMPRE que se desea referenciar una entidad que conceptualmente representa una factura.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ La clase FacturaModelImpl: ‣ Esta clase implementa la interface FacturaModel implementando todos los métodos get y set. public class FacturaModelImpl extends BaseModelImpl<Factura> ! implements FacturaModel { ! public static final String TABLE_NAME = "Factura"; ! public static final Object[][] TABLE_COLUMNS = { ! ! ! { "facturaId", new Integer(Types.BIGINT) }, ! ! ! { "companyId", new Integer(Types.BIGINT) }, ! ! ! { "cliente", new Integer(Types.VARCHAR) }, ! ! ! { "razonSocial", new Integer(Types.VARCHAR) }, ! ! ! { "fechaEmision", new Integer(Types.TIMESTAMP) }, ! ! ! { "importe", new Integer(Types.DOUBLE) } ! }; NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ La clase FacturaImpl: ‣ Esta clase es la implementación del modelo. Hereda de FacturaModelImpl e implementa Factura: ... public class FacturaImpl extends FacturaModelImpl implements Factura { ! public FacturaImpl() { ! } } NUNCA DEBE REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ¿Por qué se trabaja con un conjunto de clases e interfaces para resolver un problema teóricamente más simple? ¿Puedo modificar el código generado por el service builder? ¿Cómo?lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Modelo ‣ Service Builder, mediante su fichero service.xml, nos permite crear de forma totalmente automática el modelo del servicio que queremos definir. ‣ Pero si, por la razón que sea, necesitamos modificar y adaptar el modelo de forma manual, será posible gracias a la arquitectura que propone Liferay. ‣ Cualquier modificación que necesitemos hacer se llevará a cabo en la clase FacturaImpl.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de persistencia ‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de persistencia ‣ La interface FacturaPersistence: define todos los métodos que proporciona el servicio de persistencia para el concepto Factura. ... public interface FacturaPersistence extends BasePersistence<Factura> { NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de persistencia ‣ La clase FacturaPersistenceImpl: es la implementación de todos los métodos definidos en la interface FacturaPersistence. ... public class FacturaPersistenceImpl extends BasePersistenceImpl<Factura> ! implements FacturaPersistence { NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de persistencia ‣ La clase FacturaUtil: mediante Spring Framework se inyecta la implementación del servicio de persistencia asociado a Facturas y mediante métodos estáticos se proporciona el servicio. ... public class FacturaUtil { private static FacturaPersistence _persistence; public void setPersistence(FacturaPersistence persistence) { ! ! _persistence = persistence; } public static void clearCache() { getPersistence().clearCache(); } ... NUNCA DEBE MODIFICARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de persistencia ‣ Las clases e interfaces del servicio de persistencia se crean de forma automática. ‣ La clase utility para el servicio de Facturas envuelve la implementación del servicio de persistencia y proporciona acceso a las operaciones CRUD del modelo. ‣ Esta utilidad SÓLO debe ser utilizada por el servicio de negocio asociado y siempre dentro de una transacción. Nunca debemos utilizarlo desde una página jsp, un controlador, etc.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de negocio ‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de negocio ‣ La interface FacturaLocalService: ‣ Define todos los métodos proporcionados por el servicio de negocio que posteriormente tendrán que ser implementados. ... @Transactional(isolation = Isolation.PORTAL, rollbackFor={PortalException.class, SystemException.class}) public interface FacturaLocalService { ... public es.ematiz.model.Factura addFactura(Factura factura) throws SystemException; ... NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de negocio ‣ La clase FacturaLocalServiceBaseImpl: ‣ Esta clase implementa todos los métodos definidos en la interface FacturaLocalService. ‣ Mediante Spring Framework, el servicio de persistencia de Facturas es inyectado en esta clase para poder implementar los servicios necesarios: public abstract class FacturaLocalServiceBaseImpl implements FacturaLocalService { protected FacturaPersistence facturaPersistence; public Factura addFactura(Factura factura) throws SystemException { factura.setNew(true); return facturaPersistence.update(factura, false); } NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de negocio ‣ La clase FacturaLocalServiceImpl: ‣ Esta clase hereda de FacturaLocalServiceBaseImpl. ... public class FacturaLocalServiceImpl extends FacturaLocalServiceBaseImpl { } Todos los métodos que se quieren añadir en el servicio DEBEN incluirse aquí. NUNCA DEBE REFERENCIARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Servicio de negocio ‣ La clase FacturaLocalServiceUtil: ‣ Define todos los métodos que expone el servicio de negocio mediante métodos estáticos. ‣ Esta es la clase que debe utilizar el programador cuando quiere utilizar el servicio de negocio. ... public class FacturaLocalServiceUtil { public static Factura addFactura(Factura factura) throws SystemException { return getService().addFactura(factura); } ... NUNCA DEBE MODIFICARSE DIRECTAMENTE.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ Como ya se ha comentado anteriormente, Liferay maneja sus servicios apoyándose básicamente en dos tecnologías: ‣ Spring Framework. ‣ Hibernate Framework. ‣ El uso de estas tecnologías implica la incorporación de un conjunto de ficheros de configuración. Se pasan a describir a continuación: ‣ base-spring.xml. ‣ cluster-spring.xml. ‣ dynamic-data-source-spring.xml. ‣ hibernate-spring.xml. ‣ infraestructure-spring.xml. ‣ ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ base-spring.xml: ‣ Es un fichero de configuración de Spring Framework que define diferentes advice de programación orientada a aspectos. ... <bean id="basePersistence" abstract="true"> <property name="dataSource" ref="liferayDataSource" /> <property name="sessionFactory" ref="liferaySessionFactory" /> </bean> <bean id="serviceAdvice" class="com.liferay.portal.monitoring.statistics.service.ServiceM onitorAdvice" factory-method="getInstance"> <property name="monitoringDestinationName" value="liferay/monitoring" /> <property name="nextMethodInterceptor" ref="asyncAdvice" /> </bean>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ base-spring.xml: ‣ Es interesante hacer énfasis en el advice para la gestión de transacciones: ... <bean id="transactionAdvice" class= "com.liferay.portal.spring.transaction.TransactionInterceptor"> <property name="transactionManager" ref="liferayTransactionManager" /> <property name="transactionAttributeSource"> <bean class="com.liferay.portal.spring.transaction. AnnotationTransactionAttributeSource" /> </property> </bean>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ dynamic-data-source-spring.xml: ... <bean id="transactionAdvice" class="com.liferay.portal.dao.jdbc .aop.DynamicDataSourceTransactionInterceptor"> <property name="transactionManager" ref="liferayTransactionManager" /> <property name="transactionAttributeSource"> <bean class="org.springframework.transaction.annotation. AnnotationTransactionAttributeSource"> <constructor-arg> ! <bean class="com.liferay.portal.spring.annotation. PortalTransactionAnnotationParser" /> </constructor-arg> </bean> </property> </bean>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ hibernate-spring.xml: ‣ Define la forma en que Spring Framework maneja Hibernate en la capa de datos: <bean id="liferayHibernateSessionFactory" class="com.liferay.portal.spring.hibernate. PortletHibernateConfiguration"> ! <property name="dataSource" ref="liferayDataSource" /> </bean> <bean id="liferaySessionFactory" class="com.liferay.portal.dao.orm.hibernate. SessionFactoryImpl"> ! <property name="sessionFactoryClassLoader" ref="portletClassLoader" /> ! <property name="sessionFactoryImplementor" ref="liferayHibernateSessionFactory" /> </bean> <bean id="liferayTransactionManager" class="com.liferay.portal.kernel.util.InfrastructureUtil" factory-method="getTransactionManager" />lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ infraestructure-spring.xml: ‣ Se define la fuente de datos para Liferay: <bean id="liferayDataSource" class="org.springframework.jdbc.datasource. LazyConnectionDataSourceProxy"> <property name="targetDataSource"> <bean class="com.liferay.portal.kernel.util. InfrastructureUtil" factory-method="getDataSource" /> </property> </bean>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ portlet-spring.xml: las inyecciones de dependencias necesarias para el correcto funcionamiento de los servicios se define aquí: <bean id="es.ematiz.service.FacturaLocalService" class="es.ematiz.service.impl.FacturaLocalServiceImpl" /> <bean id="es.ematiz.service.FacturaLocalServiceUtil" class="es.ematiz.service.FacturaLocalServiceUtil"> ! <property name="service" ref="es.ematiz.service.FacturaLocalService" /> </bean> <bean id="es.ematiz.service.persistence.FacturaPersistence" class="es.ematiz.service.persistence.FacturaPersistenceImpl" parent="basePersistence" />lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Ficheros de configuración ‣ portlet-model-hints.xml: este fichero nos permite modificar el comportamiento por defecto a la hora de generar las columnas en las tablas: ... <model name="es.model.TimeSheetLine"> ! ! <field name="uuid" type="String" /> ! ! <field name="timeSheetLineId" type="long" /> ! ! <field name="projectCode" type="String" /> ! ! <field name="hourType" type="String" /> ! ! <field name="timeSheetId" type="long" /> ! ! <field name="info" type="String"> ! ! ! <hint name="max-length">300</hint> ! ! </field> ! ! <field name="projectName" type="String" /> ! </model> </model-hints>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Desde un punto de vista teórico una asociación queda definida por la direccionalidad que indica cómo se navega en dicha asociación y la cardinalidad que indica el número de objetos de cada extremo que intervienen en la relación. ‣ Según la direccionalidad tenemos dos tipos: ‣ Unidireccional: la asociación sólo es navegable en un sentido, por lo que desde uno de sus extremos no se podrá llegar a los objetos del otro extremo. ‣ Bidireccional: la asociación es navegable en ambos sentidos. Por lo que desde cualquiera de sus extremos se puede acceder a los objetos del otro extremo.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Hibernate propone un modelo muy interesante que mediante ficheros de mapeo permite manejar asociaciones de todo tipo. ‣ Ejemplo: <class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set> </class> ... <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> ... </class>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ El Service Builder de Liferay, en cambio, propone un modelo diferente. ‣ El concepto de asociación se va a ilustrar a partir de un ejemplo de Liferay: ‣ Las entidades User y Role: Role Userlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ El fichero service.xml que define estas entidades se encuentra en portal-impl/src/com/portal:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Entidad Role: <entity name="Role" local-service="true" remote- service="true"> <!-- PK fields --> <column name="roleId" type="long" primary="true" /> <!-- Audit fields --> <column name="companyId" type="long" /> <!-- Other fields --> <column name="classNameId" type="long" /> <column name="classPK" type="long" /> <column name="name" type="String" /> <column name="title" type="String" /> <column name="description" type="String" /> <column name="type" type="int" /> <column name="subtype" type="String" />lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Entidad Role: ... <!-- Relationships --> <column name="groups" type="Collection" entity="Group" mapping-table="Groups_Roles" /> <column name="permissions" type="Collection" entity="Permission" mapping- table="Roles_Permissions" /> <column name="users" type="Collection" entity="User" mapping-table="Users_Roles" /> ... Se define la relación con la entidad Userlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ One to many: ‣ Se define mediante el elemento column. ‣ Los atributos entity y mapping-key se utilizan y el atributo mapping- table NO. ‣ Ejemplo: ... <column name="shoppingItemPrices" type="Collection" entity="ShoppingItemPrice" mapping-key="itemId" /> ... ‣ La columna especifica que habrá un método getter llamado getShoppingItemPrices() que devuelve una colección. Mapeará una columna llamada itemId en la tabla que mapea a la entidad ShoppingItemPrice.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Many to many: ‣ Se define mediante el elemento column. ‣ Los atributos entity y mapping-table se utilizan y el atributo mapping- key NO. ‣ Ejemplo: ... <column name="roles" type="Collection" entity="Role" mapping-table="Groups_Roles" /> ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Clases de utilidad: ‣ RoleLocalServiceUtil. ‣ UserLocalServiceUtil. ‣ Fachada de Servicios: ‣ UserLocalService y UserLocalServiceImpl. ‣ RoleLocalService y RoleLocalServiceImpl. ‣ Servicios persistentes: ‣ UserPersistence y UserPersistenceImpl. ‣ RolePersistence y RolePersistenceImpl.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 1. Método getUserRoles: ‣ La relación entre ambas entidades puede percibirse en el método getUserRoles de la clase RoleLocalServiceUtil. ‣ Se pasa como parámetro el identificador de un usuario y se devuelve la lista de roles asociados a dicho usuario: public static java.util.List<com.liferay.portal.model.Role> getUserRoles( long userId) throws com.liferay.portal.SystemException { return getService().getUserRoles(userId); } ‣ El método que implementa esta funcionalidad se llama getUserRoles que se encuentra definido en el servicio.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Este método se encuentra en la clase RoleLocalServiceImpl: public List<Role> getUserRoles(long userId) throws SystemException { return userPersistence.getRoles(userId); } ‣ Se apoya en el servicio persistente de la Entidad User para llevar a cabo la operación.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 2. Método addUserRoles: ‣ Se encuentra en la clase RoleLocalServiceUtil. ‣ Este método asocia un usuario a una lista de roles. ‣ Como es lógico, las entidades se crean primero y posteriormente se conectan. public static void addUserRoles(long userId, long[] roleIds) throws com.liferay.portal.SystemException { getService().addUserRoles(userId, roleIds); }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 2. Método addUserRoles: ‣ El método addUserRoles de la implementación del servicio se apoya en el servicio de Usuarios: ... public void addUserRoles(long userId, long[] roleIds) throws SystemException { userPersistence.addRoles(userId, roleIds); userLocalService.reIndex(userId); PermissionCacheUtil.clearCache(); } ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 2. Método addUserRoles: ‣ La entidad persistente del usuario proporciona el acceso correcto: ... public void addRoles(long pk, long[] rolePKs) throws SystemException { try { for (long rolePK : rolePKs) { addRole.add(pk, rolePK); } } catch (Exception e) { throw processException(e); } finally { FinderCacheUtil.clearCache("Users_Roles"); } } ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 2. Método addUserRoles: ‣ El objeto addRole es el elemento que realmente define la asociación entre ambas entidades. ‣ En el código de la clase se puede encontrar: ... addRole = new AddRole(this); ‣ La clase AddRole es una clase interna dentro de UserPersistenceImpl: ... protected class AddRole {lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Asociaciones ‣ Ejemplo 2. Método addUserRoles: ‣ La clase interna AddRole tiene un método que asocia Role y Usuario: _sqlUpdate = SqlUpdateFactoryUtil.getSqlUpdate( getDataSource(), "INSERT INTO Users_Roles (userId, roleId) VALUES (?, ?)", new int[] { Types.BIGINT, Types.BIGINT }); protected void add(long userId, long roleId) throws SystemException { ... _sqlUpdate.update(new Object[] {new Long(userId), new Long (roleId)}); ...lunes 11 de junio de 2012
  • Diseño y maquetación Liferay 6.1 La gestión avanzada de portales y las tecnologías Java Empresariales Viernes 8 de Junio de 2012 Centro de Innovación del BBVA (Madrid) Jesús Salinas Revelleslunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Índice de contenidos ‣ Introducción. ‣ Layout templates. ‣ Temas. ‣ Configuración por defecto.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Liferay permite configurar los portales con los que trabajamos, desde el punto de vista del diseño, mediante: ‣ Layouts o plantillas de página. ‣ Themes o temas. ‣ El proceso de instalación de ambos elementos se puede realizar mediante la interfaz de Liferay, a través de su panel de control, seleccionando la opción Instalación de Plugins:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Una plantilla es un producto software organizado de una forma específica que permite definir cómo se pueden distribuir los portlets dentro de una página sobre la que se aplica la plantilla. ‣ Históricamente han tenido forma de rejilla y se construyen mediante tablas HTML. ‣ Por defecto, el portal viene acompañado por varios layout templates.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Para acceder a ellos desde una página: El acceso a esta opción permite determinar la Se selecciona la plantilla adecuada. plantilla que se va a aplicar sobre la páginalunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Para desarrollar nuestras propias plantillas se debe construir un proyecto web dinámico. Por ejemplo: ‣ En el proyecto se encuentran ficheros que definen la estructura de la plantilla y ficheros de configuración.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Estructura de la plantilla: ‣ fichero *.png: imagen que muestra la forma de la plantilla ‣ fichero *.tpl: plantilla normal ‣ fichero *.wap.tpl: plantilla wap.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Ejemplo. fichero *.png:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Ejemplo. fichero *.tpl: <div class="columns-1-2-1" id="content-wrapper"> <table class="lfr-grid" id="layout-grid"> <tr id="row-1"> <td class="lfr-column" id="column-1" valign="top" colspan="2"> $processor.processColumn("column-1") Estos valores </td> </tr> deben coincidir <tr id="row-2"> <td class="lfr-column seventy" id="column-2" valign="top"> $processor.processColumn("column-2") </td> <td class="lfr-column thirty" id="column-3" valign="top"> $processor.processColumn("column-3") </td> </tr> <tr id="row-3"> <td class="lfr-column" id="column-4" valign="top" colspan="2"> $processor.processColumn("column-4") </td> </tr> </table> </div>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Ejemplo. fichero *wap.tpl: <table> <tr> <td colspan="2"> $processor.processColumn("column-1") </td> </tr> <tr> <td> $processor.processColumn("column-2") </td> <td> $processor.processColumn("column-3") </td> </tr> <tr> <td colspan="2"> $processor.processColumn("column-4") </td> </tr> </table>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Nota: ‣ El método processColumn() asociado a la variable processor crea un área donde los portlets pueden ser arrastrados.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Como se puede ver, las plantillas que proporcionaba Liferay Portal hasta la versión 6 no fomentan la accesibilidad de nuestras aplicaciones web, dado que se utilizan tablas para organizar los contenidos dentro de la plantilla. ‣ Se recomienda el uso de otro tipo de elementos para la maquetación de, por ejemplo: <div class="columns-1-2" id="content-wrapper"> <div class="lfr-grid" id="layout-grid"> <div class="lfr-column" id="column-1" > $processor.processColumn("column-1") </di> <div class="lfr-column" id="column-2" > $processor.processColumn("column-2") </div> </div> </div>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Ficheros de configuración: ‣ liferay-layout-templates.xml: <?xml version="1.0"?> <!DOCTYPE layout-templates PUBLIC "-//Liferay//DTD Layout Templates 6.1.0//EN" "http://www.liferay.com/dtd/liferay- layout-templates_6_1_0.dtd"> <layout-templates> ! <custom> ! <layout-template id="ProyectoTemplate" name="ProyectoTemplate"> ! <template-path>/ProyectoTemplate.tpl</template-path> ! <wap-template-path>/ProyectoTemplate.wap.tpl </wap-template-path> ! <thumbnail-path>/ProyectoTemplate.png</thumbnail-path> </layout-template> ! </custom> </layout-templates>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Layout template ‣ Ficheros de configuración: ‣ liferay-plugin-package.xml: <?xml version="1.0" encoding="UTF-8"?> ... <plugin-package> <name>1-2-1 Columns Templates</name> <module-id>liferay/1-2-1-columns-layouttpl/5.2.0.1/war</ module-id> <types> <type>layout-template</type> </types> <short-description> This plugin is a 1-2-1 columns layout template. </short-description> <change-log></change-log> <page-url>http://www.liferay.com</page-url> <author>Liferay, Inc.</author> <licenses> <license osi-approved="true">MIT</license> </licenses> <liferay-versions> <liferay-version>5.2.0+</liferay-version> </liferay-versions> </plugin-package>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Temas ‣ Introducción. ‣ ¿Cómo se cargan nuevos temas? ‣ ¿Cómo se aplican los temas en el portal?lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Un tema en Liferay es un producto software organizado de una forma específica que utiliza hojas de estilo CSS, imágenes, JavaScript y plantillas Velocity para controlar el look and feel de las páginas generadas en el portal. ‣ Liferay tiene una serie de temas por defecto que va a poder aplicar de forma general a cualquier página o de forma totalmente específica a páginas pertenecientes a comunidades, organizaciones, etc. ‣ El desarrollador podrá definir temas totalmente personalizados.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ El tema que se aplica por defecto se llama Classic:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Introducción ‣ Este tema está formado por tres variantes:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se cargan nuevos temas? ‣ Esta operación se realiza desde el panel de control, seleccionando la opción Instalación de Plugins dentro de la sección Servidor: Este botón permite instalar temas adicionales.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se cargan nuevos temas? ‣ El botón Instalar más temas nos permite instalar nuevos temas del repositorio o subiendo el fichero que almacena el tema:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se cargan nuevos temas? ‣ Esta operación también se puede realizar mediante el acceso a la opción Página dentro de la opción Administrar de la barra superior.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se aplican los temas en el portal? ‣ Una vez que se han instalado en el sistema los temas con los que se quiere trabajar, la aplicación de dichos temas sobre los portales es muy simple e intuitivo.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado ¿Cómo se aplican los temas en el portal? ‣ El sistema permite aplicar estilos a conjuntos de páginas o a páginas aislado, proporcionando así un nivel de flexibilidad muy grande: Se está aplicando un tema SÓLO sobre la página Prueba2lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración por defecto ‣ Cuando se crea un sitio web o un usuario, a todas sus páginas se asocia un tema por defecto. ‣ El portal por defecto viene acompañado por un tema y un layout por defecto: ‣ Tema classic. ‣ Plantilla 2_columns_ii. ‣ Evidentemente, este comportamiento por defecto puede modificarse.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración por defectolunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración por defecto ‣ Los parámetros por defecto asociados a look and feel se encuentra en el fichero portal.properties que se encuentra en: ‣ portal-impl.jar Este fichero controla entre otras cosas el look and feel de la plataformalunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración por defecto ‣ Al abrir el fichero se pueden visualizar los parámetros por defecto asociados Se definen distintos parámetros que condicionan el comportamiento del portal.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Configuración por defecto ‣ Para incorporar modificaciones sobre esta configuración por defecto se deben añadir los nuevos valores en el fichero portal-ext.properties.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Classic Theme ‣ Este tema se puede encontrar en la instalación de Liferay: ‣ /html/themes/classic. Hojas de estilo que se aplican Imágenes que se utilizan En esta carpeta se almacenan las plantillas Velocity que definen la estructura de las páginas del portal.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Classic Theme ‣ Se pasan a describir a continuación los distintos elementos que forman este tema: ‣ Plantillas. ‣ Hojas de estilo con CSS. ‣ JavaScript. ‣ Imágenes.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plantillas ‣ Para la construcción de plantillas se utiliza Velocity. ‣ Encontramos los siguientes ficheros vm: ‣ portal_normal.vm: plantilla que define la página completa. ‣ navigation.vm: plantilla que define la barra de navegación. ‣ portlet.vm: plantilla que define la estructura del portlet.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plantillas ‣ Antes de describir la funcionalidad que ofrecen cada una de ellas debemos comentar que la clase VelocityVariables.java, que se encuentra en el paquete com.liferay.portal.velocity, se encargará de definir un conjunto de variables Velocity que posteriormente serán referenciadas en las plantillas. ... public class VelocityVariables { public static void insertHelperUtilities( VelocityContext velocityContext, String[] restrictedVariables) { // Array util velocityContext.put("arrayUtil", ArrayUtil_IW.getInstance()); // Browser sniffer velocityContext.put( "browserSniffer", BrowserSnifferUtil.getBrowserSniffer ()); ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plantillas ‣ Se pasa a describir en profundidad cada una de las plantillas que forman parte del tema. ‣ Esto permitirá al programador tener un conocimiento más profundo de la estructura de un tema para posteriormente poder modificarlo.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Plantilla principal ‣ El fichero portal_normal.vm define la plantilla principal: ‣ Si se analiza de forma simplista, no es más que una página HTML. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> ... </head> <body ...> <div id="wrapper"> ... </div> </body> ... </html>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación Barra de navegaciónlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ El fichero que representa a la barra de navegación es navigation.vm: <nav class="$nav_css_class" id="navigation"> <h1> ! <span>#language("navigation")</span> </h1> <ul> #foreach ($nav_item in $nav_items) ! #if ($nav_item.isSelected()) ! ! <li class="selected"> ! #else ! ! <li> ! #end ! <a href="$nav_item.getURL()" $nav_item.getTarget()><span> $nav_item.icon() $nav_item.getName()</span></a> ! #if ($nav_item.hasChildren()) ! ! <ul class="child-menu"> ! ! #foreach ($nav_child in $nav_item.getChildren()) ! ! ... ! </ul> </nav>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Conceptualmente, el elemento más importante dentro de la plantilla navigation.vm es nav_items. ‣ Esta referencia se ha creado en dos pasos: ‣ Paso 1: en el fichero VelocityVariables.java: // Navigation items Lista de objetos if (layout != null) { de tipo NavItem RequestVars requestVars = new RequestVars( que representan request, themeDisplay, layout.getAncestorPlid(), cada elemento layout.getAncestorLayoutId()); navegable. List<NavItem> navItems = NavItem.fromLayouts(requestVars, layouts); velocityContext.put("navItems", navItems); }lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Paso 2: en el fichero init.vm: ## ---------- Navigation ---------- ## #if ($navItems) #set ($nav_items = $navItems) #set ($has_navigation = ($nav_items && $nav_items.size()> 0)) #end La variable velocity nav_items se crea a partir de la variable navItemslunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Proceso de creación de la barra de navegación: ‣ Implica la generación en HTML de algo tal que así: <ul> <li> <a href=”url01” title=”Enlace genérico 1”>Elemento 1</a> </li> <li> <a href=” url02” title=”Enlace genérico 2”>Elemento 2 </a> </li> <li> <a href=” url03” title=”Enlace genérico 3”>Elemento 3 </a> </li> ... </ul> ‣ Los objetos de navegación que se almacenan en la variable nav_items son los que deben proporcionarnos toda la información: ‣ nombre, url, etc.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Proceso de creación de la barra de navegación: ‣ Evidentemente, se debe montar una iteración para cada elemento de navegación, <li></li>: #foreach ($nav_item in $nav_items) ## todo lo que aparece se aplica a cada elemento de ## navegación almacenado en ## nav_items, cada uno de esos ## elementos se referencia mediante $nav_item ... #endlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Proceso de creación de la barra de navegación: ‣ Paso 1: se define el class a aplicar en función de si el link está o no seleccionado: #if ($nav_item.isSelected()) #set ($nav_item_class = "selected") #else #set ($nav_item_class = "") #endlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Proceso de creación de la barra de navegación: ‣ Paso 2: se crea el link con la información asociada al elemento de navegación: <li class="$nav_item_class"> <a href="$nav_item.getURL()" $nav_item.getTarget()> <span>$nav_item.getName()</span> </a> ... </li>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Barra de navegación ‣ Proceso de creación de la barra de navegación: ‣ Paso 3: si un elemento de navegación tiene hijos, estos también se gestionan: #if ($nav_item.hasChildren()) <ul class="child-menu"> #foreach ($nav_child in $nav_item.getChildren()) #if ($nav_child.isSelected()) #set ($nav_child_class = "selected") #else #set ($nav_child_class = "") #end <li class="$nav_child_class"> <a href="$nav_child.getURL()" $nav_child.getTarget()> $nav_child.getName()</a> </li> #end </ul> #endlunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Portlets ‣ El fichero portlet.vm representa la plantilla que envuelve a cualquier portlet:lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Portlets ‣ El fichero portlet.vm representa la plantilla que envuelve a cualquier portlet: #set ($portlet_display = $portletDisplay) #set ($portlet_id = $htmlUtil.escapeAttribute($portlet_display.getId())) #set ($portlet_title = $portlet_display.getTitle()) #set ($portlet_back_url = $htmlUtil.escapeAttribute ($portlet_display.getURLBack())) <section class="portlet" id="portlet_$portlet_id"> ! <header class="portlet-topper"> ! ! <h1 class="portlet-title"> ! ! ! $theme.iconPortlet() <span class="portlet-title-text"> $portlet_title</span> ! ! </h1> ... ! ! $portlet_display.writeContent($writer) ! </div> </section>lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Hojas de estilo ‣ Los ficheros CSS permiten aplicar estilos sobre las plantillas HTML previamente diseñadas.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Hojas de estilo ‣ main.css: incluye una referencia a las demás hojas de estilo. ‣ base.css: estilos básicos genéricos. ‣ application.css: definen los elementos genéricos de la aplicación: ‣ ventanas de diálogo, pop-ups, pestañas, etiquetas, etc. ‣ layout.css: ajusta todos los estilos relacionados con layouts. ‣ navigation.css. ‣ No se recomienda la edición de ninguno de estos ficheros. Para realizar modificaciones se utiliza el fichero custom.css.lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Hojas de estilo ‣ Fichero custom.css: /* This file allows you to override default styles in one central location for easier upgrade and maintenance. */ /* ---------- Base ---------- */ body { background: #46423D; color: #FFF; } /* ---------- Wrapper ---------- */ #wrapper { margin: 0 auto; width: 960px; } /* ---------- Banner ---------- */ ...lunes 11 de junio de 2012
  • Estrategias de desarrollo avanzado Imágeneslunes 11 de junio de 2012