Top Banner
Liferay 6.1 Service Builder
78

Liferay 6.1 Service Builder

Nov 18, 2014

Download

Technology

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Liferay 6.1  Service Builder

Liferay 6.1Service Builder

Page 2: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Índice de contenidos

‣ Introducción.

‣ Fichero service.xml.

‣ Ejercicio.

Page 3: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 4: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 5: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ El fichero service.xml debe incluir la dtd correspondiente al Service builder adecuado:

‣ Una vez incluida la DTD se deben incluir los elementos XML necesarios:

‣ Elemento service-builder.

‣ Elemento namespace.

‣ Elemento entity

‣ ...

<?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>

Page 6: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ 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>

<!ELEMENT service-builder (author?, namespace, entity+, exceptions?)>

Page 7: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 8: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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*)>

Page 9: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 10: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 11: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento column:

‣ Representa una columna en la tabla de una base de datos.

‣ No tiene elementos hijo:

‣ Ejemplo:

<!ELEMENT column (#PCDATA)>

<column name="entryId" type="String" primary="true" /><column name="companyId" type="String" />

Page 12: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 13: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ La entidad tiene un método getNombre que devuelve como valor de retorno una cadena de caracteres.

<column name="nombre" type="String" />

Page 14: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 15: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />

Page 16: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 17: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 18: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 19: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento finder:

‣ Representa métodos finder que se generarán automáticamente.

‣ Tiene un elemento hijo llamado finder-column:

‣ Ejemplo:

<!ELEMENT finder (finder-column+)>

<finder name="CompanyId" return-type="Collection"><finder-column name="companyId" />

</finder>

Page 20: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 21: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 22: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento finder-column:

‣ Representa una columna a partir de la cuál se busca.

‣ No tiene elementos hijo:

‣ Ejemplo:

<finder name="CompanyId" return-type="Collection"><finder-column name="companyId" /></finder>

<!ELEMENT finder-column (#PCDATA)>

Page 23: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento finder-column:

‣ Atributos:

<!ATTLIST finder-column! name CDATA #REQUIRED! case-sensitive CDATA #IMPLIED! comparator CDATA #IMPLIED>

Page 24: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 25: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 26: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ Ejemplo:

<order by="asc"><order-column name="parentLayoutId" /><order-column name="priority" />

</order>

<!ELEMENT order (order-column+)>

Page 27: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento order:

‣ Atributos:

‣ El atributo by toma dos valores:

‣ asc o desc: ordenación ascendente o descendente.

<!ATTLIST order! by CDATA #IMPLIED>

Page 28: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ Ejemplo:

<!ELEMENT order-column (#PCDATA)>

<order by="asc"><order-column name="parentLayoutId" /><order-column name="priority" />

</order>

Page 29: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Fichero service.xml

‣ Elemento order-column:

‣ Atributos:

‣ El atributo order-by toma dos valores:

‣ asc o desc: ordenación ascendente o descendente.

<!ATTLIST order-column! name CDATA #REQUIRED! case-sensitive CDATA #IMPLIED! order-by CDATA #IMPLIED>

<order><order-column name="articleId" order-by="asc" /><order-column name="version" order-by="desc" />

</order>

Page 30: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Ejercicio

‣ Introducción.

‣ Fichero service.xml.

‣ Generación del servicio.

‣ Código generado.

‣ Asociaciones.

Page 31: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 32: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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)

Page 33: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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/PortletPrueba

Page 34: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />...

Page 35: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 36: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Generación del servicio

‣ Una vez construido correctamente el fichero service.xml, la generación del servicio se realiza mediante la herramienta Eclipse:

Page 37: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Código generado

‣ Introducción.

‣ Modelo.

‣ Servicio de persistencia.

‣ Servicio de negocio.

‣ Ficheros de configuración.

Page 38: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 39: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Modelo

‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:

Page 40: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Modelo

‣ La interface FacturaModel:

‣ Define todos los métodos set y get necesarios.

public interface FacturaModel extends BaseModel<Factura> {

...

}

NUNCA DEBE MODIFICARSE O REFERENCIARSE DIRECTAMENTE.

Page 41: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Modelo

‣ La interface Factura:

‣ Hereda de FacturaModel.

...public interface Factura extends FacturaModel {}

Esta interface DEBE utilizarse SIEMPRE que se desea referenciar una entidad que conceptualmente representa una factura.

NUNCA DEBE MODIFICARSE DIRECTAMENTE.

Page 42: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 43: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 44: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Modelo

¿Cómo?

¿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?

Page 45: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 46: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Servicio de persistencia

‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:

Page 47: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 48: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 49: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 50: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 51: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Servicio de negocio

‣ Para el problema planteado, básicamente el código generado podría resumirse mediante el siguiente esquema:

Page 52: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 53: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 54: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 55: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 56: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

‣ ...

Page 57: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.ServiceMonitorAdvice" factory-method="getInstance"><property name="monitoringDestinationName" value="liferay/monitoring" /><property name="nextMethodInterceptor" ref="asyncAdvice" />

</bean>

Page 58: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 59: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 60: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />

Page 61: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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>

Page 62: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />

Page 63: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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.

Page 64: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Asociaciones

‣ Hibernate propone un modelo muy interesante que mediante ficheros de mapeo permite manejar asociaciones de todo tipo.

‣ Ejemplo:

...<class name="Address"> <id name="id" column="addressId"> <generator class="native"/>

</id> ...

</class>

<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>

Page 65: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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 User

Page 66: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Asociaciones

‣ El fichero service.xml que define estas entidades se encuentra en portal-impl/src/com/portal:

Page 67: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />

Page 68: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Asociaciones

‣ Entidad Role:

Se define la relación con la entidad User

...<!-- 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" />

...

Page 69: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ 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.

...<column name="shoppingItemPrices" type="Collection" entity="ShoppingItemPrice" mapping-key="itemId" />...

Page 70: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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" />...

Page 71: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Asociaciones

‣ Clases de utilidad:

‣ RoleLocalServiceUtil.

‣ UserLocalServiceUtil.

‣ Fachada de Servicios:

‣ UserLocalService y UserLocalServiceImpl.

‣ RoleLocalService y RoleLocalServiceImpl.

‣ Servicios persistentes:

‣ UserPersistence y UserPersistenceImpl.

‣ RolePersistence y RolePersistenceImpl.

Page 72: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ El método que implementa esta funcionalidad se llama getUserRoles que se encuentra definido en el servicio.

public static java.util.List<com.liferay.portal.model.Role> getUserRoles(long userId) throws com.liferay.portal.SystemException {return getService().getUserRoles(userId);

}

Page 73: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

Asociaciones

‣ Este método se encuentra en la clase RoleLocalServiceImpl:

‣ Se apoya en el servicio persistente de la Entidad User para llevar a cabo la operación.

public List<Role> getUserRoles(long userId) throws SystemException {

return userPersistence.getRoles(userId);}

Page 74: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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);}

Page 75: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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();}

...

Page 76: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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");}

}...

Page 77: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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:

‣ La clase AddRole es una clase interna dentro de UserPersistenceImpl:

...protected class AddRole {

...addRole = new AddRole(this);

Page 78: Liferay 6.1  Service Builder

Service Builder

Preparado por Jesús Salinas Revelles

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)});...