Liferay 6.1 Service Builder

78
Liferay 6.1 Service Builder

description

 

Transcript of Liferay 6.1 Service Builder

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