Entrades amb etiqueta service builder .

Compartir la Capa de Servicios

Data de publicació 27/05/16 12:17

¡Buenas!

 

Hoy os explico diferentes maneras de compartir la capa de servicios que hayáis creado con el service builder entre diferentes portlets.

 

Primero, tenemos que contar que tenéis un portlet base base-portlet, el cuál habéis creado entidades y servicios con el service builder. Si quisieramos que un segundo portlet y un hook, por ejemplo, accedieran a estos servicios, replicarlos para cada plugin sería ineficiente y causante d’errores de inconsistencia en el futuro.

 

La mejor opción siempre es que todos los plugin accedan a la misma capa:


Untitled.png

 

 

Propondremos dos opciones:

 
  • Crear los diferentes portlets y hooks en un mismo plugin.

  • Compartir la capa de servicios a nivel de tomcat.

 

Crear los diferentes portlets y hooks en un mismo plugin

 

La idea es crear diferentes portlets en un mismo plugin de Liferay y tener unos servicios creados con el Service Builder. De esta manera, estos servicios seran disponibles y accesibles por cada portlet o hook dentro del plugin.

 

Compartir la capa de servicios a nivel de tomcat

 

Si la propuesta anterior no fuera posible, también podriamos exportar la capa de servicios mediante un archivo jar. Cuando ejecutas el service builder, este archivo se genera en: “your-portlet/docroot/WEB-INF/lib/your-portlet-service.jar”.

 

Este jar nos da acceso a los local service que hayas programado. Para que todos los plugin de tu instancia puedan usarlo este jar lo tienes que añadir en este directorio del servidor: “<<Liferay-tomcat>>tomcat-x.x.x/lib/ext”.

 

Recuerda, para cualquier actualización de los servicios, se tendrá que reemplazar el jar y, además, reiniciar el tomcat.


¡Espero que os haya ayudado!

Localizar Entidades Custom

Data de publicació 30/03/16 12:55

Hoy explicaré cómo localizar nuestras entidades creadas con el Service Builder de Liferay. Para hacer esto tendremos que modificar el archivo service.xml para la entidad que queramos localizar:

 

<entity name="Entidad" local-service="true" remote-service="true" 
     uuid="true">
     <!-- PK fields -->

     <column name="entidadId" type="long" primary="true" />
        
     ...
        
     <column name="nombre" type="String" localized="true" />

</entity>        …

Asi cuando agamos la acción build service, en vez de generarnos un campo nombre como un objeto String, serà un objeto Map<Locale,String>.

 

Ahora, tendremos que tener en cuenta que tenemos que tratar siempre un objeto Map des de la vista, pasando por el controlador hasta la persistencia. Por ejemplo, el campo nombre se guardará como un xml en base de datos, por lo tanto crear un finder en el service.xml por la columna nombre no sería viable, se debería crear una custom sql que parseará el xml por locale.

 

Des de la vista tendremos la etiqueta liferay-ui:input-localized que nos servirá para añadir campos localizados:

 
<label class="aui-field-label" for="<portlet:namespace />nombre"><liferay-ui:message key="name" /></label>
<liferay-ui:input-localized *xml="" name="nombre" />
* el campo xml es dónde podemos introducir los valores del input, en formato xml.
 
 

Los idiomas disponibles son los especificados en el site (Configurarlo en Site Administration). En la acción podremos recoger el dato de la siguiente manera:

 

Map<Locale,String> nombre = LocalizationUtil.getLocalizationMap(actionRequest, "nombre");

 

Y finalmente, nos faltará modificar los servicios para añadir nuevos objetos localizados:

 

public Entidad addEntidad(Map<Locale,String> nombre, ….) throws SystemException, PortalException {
        Entidad entidad = null;
        
        long entidadId = 
               counterLocalService.increment(Entidad.class.getName());
        
        entidad = entidadPersistence.create(entidadId);
        
        entidad.setCreateDate(DateUtil.newDate());
        entidad.setUserId(userId);
        entidad.setUserName(userName);
 
        entidad.setNombreMap(nombre);
                      …
 
        entidad = entidadPersistence.update(entidad);
}

 

Y ya tendríamos la entidad localizada. Tened en cuenta que para cualquier cosa que hagáis con esta entidad, por ejemplo un search container, ahora tendréis un xml.


¡Espero que os sea útil!

Liferay Custom SQL

Data de publicació 11/03/15 15:06

El Service Builder de Liferay te permite crear tu propio modelo de negocio y, además, te crea los servicios los cuáles usarán el modelo que has especificado en el service.xml.

Liferay también te puede generar finders para devolver datos o colecciones de datos de la persistencia. Aún así, a veces necesitamos más lógica a la hora de hacer una consulta. Especifico estas tablas a modo de ejemplo:

Empleado [ID, NOMBRE, DNI, FECHA_NACIMIENTO, DEPARTAMENTO_ID, etc]
Departamento [ID, CIUDAD, NUM_EMPLEADOS, etc]

 

No entraremos como hacer finders con el service.xml pero sí hace falta remarcar que esos finders se hacen a partir de los datos que tiene una entidad. Por ejemplo: podemos crear un finder en la entidad Empleado que devuelva todos los empleados con fecha de nacimiento y departamento indicados.

Para hacer un ejemplo, encontrar todos los empleados que tengan su departamento en una ciudad especifica ya no es posible hacerlo des de el service.xml, por lo tanto tenemos que hacer una custom sql.

Antes de empezar creando la custom sql se ha de añadir (si no esta añadido ya) un archivo default.xml en la ruta 'docroot/WEB-INF/src/custom-sql/' y, des de éste, añadiremos el archivo que vayamos a crear:

<?xml version="1.0"?>
<custom-sql>
    <sql file="custom-sql/empleado.xml" />
</custom-sql>
 

A partir de aquí, la creación son 3 pasos:

1. Especificar tu custom SQL

En el mismo directorio que se encuentra default.xml creamos un archivo empleado.xml. Tendrá la siguiente forma:

<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
    <sql id="[fully-qualified class name + method]">
        <![CDATA[
            SQL QUERY
        ]]>
    </sql>
    <sql id="[fully-qualified class name + method2]">
        <![CDATA[
            SQL QUERY 2
        ]]>
    </sql>
</custom-sql>


El "fully-qualified class name" ha de ser de la forma: "com.[proyecto].service.persistance.EntidadFinder".
La sentencia sql irá entre els tags " <![CDATA[ " y " ]]> ":

<?xml version="1.0" encoding="UTF-8"?>
<custom-sql>
    <sql id="com.proyecto.service.persistance.EmpleadoFinder.getEmpleadosPorCiudad">
        <![CDATA[           
            Select empleado.*
               From Empleado empleado
               Left outer join Departamento departamento
                  on empleado.depatamentoId=departamento.id
               where (departamento.ciudad Like ?)
        ]]>
    </sql>
</custom-sql>


Esta custom sql es como un formulario que se rellenará con cada petición. En este caso se substituirá el símbolo '?' por el nombre de una ciudad.

 

2. Método Finder

El Service Builder no crea la clase "EntidadFinderImpl.java", por lo que nos tocará a nosotros este paso. Se crea en el directorio "com/[proyecto]/service/persistance/", en nuestro caso haremos la clase "EmpleadoFinderImpl.java":

package com.proyecto.service.persistence;
 
public class EmpleadoFinderImpl extends BasePersistanceImpl<Empleado>
                                implements EmpleadoFinder {
 
}


Una vez hecho esto, tenemos que hacer la acción de 'build service'. Se creará a partir de la clase "EmpleadoFinderImpl.java", la interfaz "EmpleadoFinder.java" y la clase "EmpleadoFinderUtil.java".

Ahora podemos completar nuestra clase "EmpleadoFinderImpl.java":

package com.proyecto.service.persistence;
 
public class EmpleadoFinderImpl extends BasePersistanceImpl<Empleado> 
          implements EmpleadoFinder {
    public static String GET_EMPLEADOS_POR_CIUDAD =
                     EmpleadoFinder.class.getName() + "getEmpleadosPorCiudad";
     
    public List<Empleado> getEmpleadosPorCiudad(String ciudad, int begin, int end) 
        throws SystemException {
        Session session = null;
        try {
            session = openSession();
 
            /*Recuperas la función custom sql que has creado en el xml*/
            String sql = CustomSQLUtil.get(GET_EMPLEADOS_POR_CIUDAD);
 
            /*Creas un objeto sql a partir de la custom sql*/
            SQLQuery q = session.createSQLQuery(sql);
            q.setCacheable(false);
            /*Añades la entidad empleado que será el objeto de retorno*/
            q.addEntity("EMPLEADO", EmpleadoImpl.class);
 
            QueryPos qPos = QueryPos.getInstance(q);
            /*Añades en orden los parámetros necesarios para ejecutar la sql*/
            qPos.add(ciudad);
 
            return (List<Empleado>) QueryUtil.list(q, getDialect(), begin, end);
        catch (Exception e) {
            try {
                throw new SystemException(e);
            catch (SystemException se) {
                se.printStackTrace();
            }
        finally {
            closeSession(session);
        }
        return null;
    }
}

Volvemos a hacer el 'build service' i ya tenemos creada nuestra función custom.
 

3. Enlazar con el service

Liferay te genera los servicios para tu modelo de negocio, para acceder a tu custom sql es recomendable que tenga la misma forma de acceso que estos servicios.

En este paso tan solo tenemos que abrir el archivo LocalServiceImpl (o ServiceImpl dependiendo si los servicios son locales o remotos) y añadir una función que llame al finder:

public class EmpleadoLocalServiceImpl extends EmpleadoLocalServiceBaseImpl {
     
    public List<Empleado> getEmpleadosPorCiudad(String ciutat, int begin, int end)
             throws SystemException {
        EmpleadoFinderUtil.getEmpleadosPorCiudad(ciutat,begin,end);
    }
}


De nuevo, y por último, volvemos a hacer 'build service' para que se cree el servicio. Ahora des de tu portlet podrás llamar a "EmpleadoLocalServiceUtil.getEmpleadosPorCiudad("Barcelona",0,num);"

Un saludo y, ¡espero que os haya servido de ayuda!

Liferay Model Hints

Data de publicació 14/11/14 04:36

Una vez, con el Service Builder, hayas creado tus entidades y la implementación del modelo de negocio de tu portal, es interesante especificar como se deberían presentar los datos al usuario (de las entidades creadas).

Con los Model Hints puedes especificar esta información y, además, puedes marcar el tamaño de los campos en la base de datos.

Estas modificaciones se han de realizar en el archivo 'portlet-model-hints.xmlque se encuentra en la ruta: ‘docroot/WEB-INF/src/META-INF’.

Los Model Hints te permiten configurar la librería de tags AlloyUI ‘aui’ para mostrar los campos de tu modelo de negocio.

Ejemplo de uso
Con esta entidad creada con el Service Builder (archivo ‘service.xml’):
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//ES"
      "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd">
<service-builder package-path="com.proliferay.servicebuilder">
    <author>duvidu</author>
    <namespace>PERSONAS</namespace>
    <entity name="Persona" table="PERSONA" local-service="true" remote-service="true">
        <column name="personaId" type="long" primary="true" />
        <column
name="Nombre" type="String" />
        <column
name="Apellido" type="String" />
        <column
name="DNI" type="String" />
        <column
name="fechaNacimiento" type="Date" />
        <column
name="observaciones" type="String" />
    </entity>
</service-builder>

 

Se autogenera el archivo ‘portlet-model-hints.xml’:

<?xml version="1.0"?>
<model-hints>
    <model name="
com.proliferay.servicebuilder.model.com.profilerayersona
           table="PERSONAlocal-service="trueremote-service="true">
        <column name="personaIdtype="longprimary="true" />
        <column 
name="Nombretype="String" />
        <column 
name="Apellidotype="String" />
        <column 
name="DNItype="String" />
        <column 
name="fechaNacimientotype="Date" />
        <column 
name="observacionestype="String" />
    </entity>

</model-hints>

 

Quiero limitar en un campo fecha que los usuarios solo puedan introducir fechas pasadas, como la de nacimiento. Entonces en el archivo 'portlet-model-hints.xml' marcamos para el campo ‘fechaNacimiento’ un hint llamado ‘year-range-future’ a falso:

<?xml version="1.0"?>
<model-hints>
    <model name="
com.proliferay.servicebuilder.model.com.profilerayersona
           table="PERSONAlocal-service="trueremote-service="true">
        <column name="personaIdtype="longprimary="true" />
        <column 
name="Nombretype="String" />
        <column 
name="Apellidotype="String" />
        <column 
name="DNItype="String" />
        <column 
name="fechaNacimientotype="Date" >
             <hint name="year-range-future">false</hint>
        </
column>
        <column 
name="observacionestype="String" />
    </entity>

</model-hints>

 

Para que este cambio sea efectivo se ha de hacer un Build Service.

Así, si tuviéramos un formulario para introducir fechas para el nacimiento con los tags aui, no permitiría introducir fechas futuras.

Como hemos dicho, con los Model Hints también puedes modificar el tamaño de un campo en la Base de Datos. Si fuera el caso de que necesitáramos que el campo ‘observaciones’ fuera más grande que el por defecto entonces usamos el ‘max-length’:

<?xml version="1.0"?>
<model-hints>
    <model name="
com.proliferay.servicebuilder.model.com.profilerayersona
           table="PERSONAlocal-service="trueremote-service="true">
        <column name="personaIdtype="longprimary="true" />
        <column 
name="Nombretype="String" />
        <column 
name="Apellidotype="String" />
        <column 
name="DNItype="String" />
        <column 
name="fechaNacimientotype="Date" >
             <hint
name="year-range-future">false</hint>
        </
column>
        <column 
name="observacionestype="String" >
             <hint name="max-length">400</hint>
        </
column>
    </entity>
</
model-hints>

 

Recuerda hacer el Build Service y el Deploy para que se propague el cambio a la Base da Datos y podrás ver como el campo ha cambiado.

La lista completa de Model Hints es la siguiente:

modelhints.png

¡Espero que os sirva de ayuda!

Bloggers recents Bloggers recents

Oscar Rodríguez
Apunts: 9
Estrelles: 2
Data: 28/09/16
David Berruezo
Apunts: 14
Estrelles: 1
Data: 22/07/16
Javi Martín
Apunts: 2
Estrelles: 1
Data: 20/05/16
Javier Torres
Apunts: 5
Estrelles: 3
Data: 11/04/16
Sergi Mingueza
Apunts: 4
Estrelles: 1
Data: 19/10/15
Matilde Gallardo
Apunts: 1
Estrelles: 0
Data: 26/02/15
Adrià Vilà
Apunts: 4
Estrelles: 4
Data: 31/08/14
Elena Ruiz
Apunts: 1
Estrelles: 2
Data: 13/03/14