Česky   |  Deutsch   |  English   |  Español   |  Français   |  Indonesia   |  日本語   |  한글   |  Polski   |  Português (BR)   |  Türkçe   |  中文   |  正體中文   |  Tu idioma  
PlanetNetbeans
Planet NetBeans es un rama de NetBeans relacionado con toda la Blogosphere.
Feeds
[RSS 1.0 Feed] [RSS 2.0 Feed]
[FOAF Subscriptions] [OPML Subscriptions]
¿Tienes un blog acerca de NetBeans? Agrega tu blog a PlanetNetBeans.
Feed Subscripciones

Powered by:    Planet

Última actualización:
August 16, 2018 10:14 AM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
AVBravo - August 07, 2018 05:22 PM
Ejecutar payara micro desde NetBeans


Documentación Oficial de Payara Micro
https://payara.gitbooks.io/payara-server/content/documentation/payara-micro/payara-micro.html



Existen diversas maneras de ejecutar Payara Micro desde NetBeans, en esta ocasión usaremos el plugin oficial que nos ofrece muchas ventajas, lo encontramos en  el repositorio

https://github.com/payara/ecosystem-netbeans-plugin/releases




Descargamos el  archivo correspondiente a la versión de  NetBeans (en mi caso Apache NetBeans 9.0)
Descomprimir el archivo e ingresamos a NetBeans IDE y procedemos a Instalar el plugin
NetBeans --> Tools --> Plugins

Dejamos seleccionados todos los componentes

al finalizar la instalación, procedemos a  Reiniciar el IDE


Observamos el icono para reiniciar PayaraMicro esta instalado en la  barra de NetBeans



Procedemos con un ejemplo:
Vanos a crear un proyecto nuevo Payara Micro
Desde el menú

Fie --> New Project

Seleccionar
Categories: Maven 
Project: Payara Micro Application

Indicamos el nombre del proyecto

Seleccionamos la versiòn  de Payara que deseamos usar


al finalizar se genera el nuevo proyecto

Podemos observar el archivo pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.avbravo</groupId>
    <artifactId>payara</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>payara</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.javaee>8.0</version.javaee>
        <version.payara.micro>5.182</version.payara.micro>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>${version.javaee}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>fish.payara.maven.plugins</groupId>
                <artifactId>payara-micro-maven-plugin</artifactId>
                <version>1.0.1</version>
                <configuration>
                    <payaraVersion>${version.payara.micro}</payaraVersion>
                    <deployWar>false</deployWar>
                    <commandLineOptions>
                        <option>
                            <key>--autoBindHttp</key>
                        </option>
                        <option>
                            <key>--deploy</key>
                            <value>${project.build.directory}/${project.build.finalName}</value>
                        </option>
                    </commandLineOptions>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

En las propiedades del proyecto se muestra la categoría Payara Micro

En  Run:

  • Server : No seleccionar ningún servidor: <No Server Selected>
  • Java EE Version: Cambiar  Java EE 6 Web por  Java EE 7 Web
Se muestra un dialogo solicitando confirmación del cambio



Al finalizar ejecutamos el proyecto 

El IDE inicia las descargas de dependencias de maven, esperamos un momento que finalice.

Cuando se termina de descargar las dependencias se ejecuta el proyecto sobre PayaraMicro

Abrimos el navegador

Cambiar el nombre  final del proyecto  para mostrar  url diferente
Editar el archivo pom.xml y agregar
 <finalName>payara</finalName>
guardamos el archivo

Desde NetBeans dar clic en Refrescar Payara Micro

En la consola de NetBeans se muestra el mensaje

Ejecutar el proyecto








Convertir un Proyecto WEB JEE a Payara Micro


Existen dos formas:
1. Mediante el plugin
2. Editando directamente el archivo pom.xml

1.Mediante el plugin

Desde el menú File --> New File



Categories: Payara
Files Type: Payara Micro Maven Plugin


Indicamos la versión de Payara Micro
el proyecto es automáticamente convertido a Payara Micro

En las propiedades del proyecto , se muestra Payara Micro

En Run
cambiamos a <Not Selected Server>

con esto podemos ejecutar el proyecto desde NetBeans sobre Payara Micro.



Otra forma es:

2. Editando directamente el archivo pom.xml

Agregamos
 <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <version.javaee>8.0</version.javaee>
        <version.payara.micro>5.182</version.payara.micro>
    </properties>

Cambiamos   

<plugins>
           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


Por

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>fish.payara.maven.plugins</groupId>
                <artifactId>payara-micro-maven-plugin</artifactId>
                <version>1.0.1</version>
                <configuration>
                    <payaraVersion>${version.payara.micro}</payaraVersion>
                    <deployWar>false</deployWar>
                    <commandLineOptions>
                        <option>
                            <key>--autoBindHttp</key>
                        </option>
                        <option>
                            <key>--deploy</key>
                            <value>${project.build.directory}/${project.build.finalName}</value>
                        </option>
                    </commandLineOptions>
                </configuration>
            </plugin>
        </plugins>

Reiniciamos NetBeans IDE


Se muestra el icono del server

Nos aseguramos que las propiedades del proyecto
Aparezca Micro


y en run no se selecciona ningún server.

Nota:
Si ejecutamos varios proyectos dese NetBeans IDE con Payara Micro, generalmente se asignaran puertos diferentes para cada proyecto, por ejemplo 8080, 8081


Error Maven

En algunas ocasiones cuando convertimos un proyecto Web, podemos encontrar el error al ejecutarlo

Se muestra el error
Exploding webapp
Assembling webapp [store] in [/home/avbravo/NetBeansProjects/sc/store/target/store]
Processing war project
Copying webapp resources [/home/avbravo/NetBeansProjects/sc/store/src/main/webapp]
------------------------------------------------------------------------
BUILD FAILURE
------------------------------------------------------------------------
Total time: 3.253 s
Finished at: 2018-08-07T12:14:56-05:00
Final Memory: 26M/377M
------------------------------------------------------------------------
Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.3:exploded (default-cli) on project store: Failed to copy file for artifact [com.avbravo:storeejb:jar:18.08.1:compile]: /home/avbravo/NetBeansProjects/sc/storeejb/target/classes (Es un directorio) -> [Help 1]

To see the full stack trace of the errors, re-run Maven with the -e switch.
Re-run Maven using the -X switch to enable full debug logging.

For more information about the errors and possible solutions, please read the following articles:
[Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException


Editamos el archivo pom.xml
 y cambiamos

 <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <inherited>true</inherited>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
por

 <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <inherited>true</inherited>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>


AVBravo - August 03, 2018 01:39 AM
reportwizard en NetBeans 9.0

Hace poco se libero Apache NetBeans 9.0
https://netbeans.apache.org/

Victor Orozco muestra como habilitar Java EE para Apache NetBeans 9.0
https://vorozco.com/blog/2018/2018-07-30-NetBeans-9-JavaEE-JakartaEE.html

Victor nos muestra lo sencillo que es simplemente agregando
desde Tools --> Plugins --> Settings

http://updates.netbeans.org/netbeans/updates/8.2/uc/final/distribution/catalog.xml.gz


y activar
  • HTML5 Kit
  • JSF
  • SOAP Web Services
  • EJB and EAR
  • RESTful Web Services
  • Java EE Base



Instalar  reportwizard en NetBeans 9.0


http://plugins.netbeans.org/plugin/74252/?show=true


Descargamos el plugin



Instalamos el plugin en el IDE

Desde el menu Windows --> Reportwizard

Escribimos o pegamos el entity

Nos muestra el reporte generado









AVBravo - July 21, 2018 03:46 PM
Crear subreportes en segundos con reportwizard plugins

Crear subreportes en segundos con reportwizard plugins

En muchas ocasiones necesitamos crear un subreporte, generalmente usamos JasperReport, mediante iReport(descontinuado) o Jaspersoft Studio. Que son excelentes herramientas con una interfaz muy fácil para crear reportes.

Necesitaba crear reportes muy rápidos sin utilizar una herramienta con los componentes para generarlos, solo deseaba crear una clase Java y a partir de esta clase generar reportes simples, agrupados con operaciones sobre los atributos y con subreportes.
Ya esta disponible el plugin en versiòn muy básica, para test.

http://plugins.netbeans.org/plugin/74252/?show=true




Un manual básico de su funcionamiento

REPORTE SIMPLE

Con una clase simple

solo presionas el botòn 

Se genera los archivos .jrxml y .jasper
y al ejecutarlo


REPORTE AGRUPADO




Puedes generar reportes agrupados con dos pasos:
1. Crear el entity



2. Indicar las propiedades dar clic en el botòn
 3. En las propiedades



Solo editamos el JSON, indicando los mensajes y atributos
Page {
size:"A4",
}
Group {
field:"grupo",
staticTextHeader:"Grupo",
staticTexFooter:"Suma",
fieldFooter:"cantidad",
operation:"Sum"
}
Summary{
staticText:"Total de cantidad",
field:"cantidad",
operation:"Sum"
}
Generamos el reporte




SUBREPORTES

Tenemos dos entity


Definimos las clases
Clase para Facturas

Definir la clase para Detalles


Generamos el reporte



Ejecutamos el proyecto


Genera los archivos .jrxml y .jasper de manera que los puedes editar desde iReport o JasperSoft Studio.







AVBravo - July 09, 2018 11:59 PM
Plugin NetBeans para generar reporte desde una clase Java

El potencial de NetBeans, entre muchas alternativas se encuentra en NetBeans Platform. Mediante el uso de Apis y plugins nos permite ampliar las funcionalidades del IDE.
Podemos crear componentes para resolver cualquier necesidad, este plugin permite que en base a un entity(clase en Java), generar reportes tipo jaspertReport.



Objetivo:
A partir de un entity
  • Generar archivo .jrxml
  • Generar el archivo .jasper
  • Permitir editar el archivo .jrml
  • No se desea una utilizar componente visual del reporte, se desea trabajar directamente con el .jrxml
Después de crear el plugin en NetBBeans IDE




Dar clic derecho en el proyecto y seleccionar Create NBM.




Instalar el plugin



Seleccionar pestaña Downloaded --> Add plugins--> Buscamos el archivo org-avbravo-reportwizard.nbm

procedemos a instalar el plugin haciendo clic en el botòn Install.


Nos muestra el numero de versiòn , presionar el botòn Next.


Apareceria la licencia de uso, si esta se ha especificado.

Luego se muestra el dialogo para confirmar los certificados 

Mensaje de finalizaciòn de instalaciòn.


Para verificar que esta instalado seleccionamos la pestaña Installed

Ejecutar el plugin.
Desde el menu de NetBeans->Windows--> ReportWizard

Se muestra la ventana del plugin.

Seleccionamos un proyecto web dando clic en  el botòn 

En la secciòn Entity, escribimos la clase Java (Soporta autocompletado).
En este ejemplo usamos un entity que definimos con el framework ejbjmoordb para imprimir los documentos que tenemos en una coleccion llamada Tamano en una base de datos mongodb.
El plugin genera el nombre del entity en base al nombre de la clase que se este escribiendo.

Presionar el botòn Siguiente  
con esto tenemos el código del archivo .jrxml que podemos editar.
Existen dos tipos de reportes bases:
  • All :donde tenemos etiquetas en la sección columnHeader 
  •  Details: Muestra las etiquetas al lado del texto.




Allí podemos editar el reporte adaptarlo a las necesidades.
Si observamos el proyecto web



Para generar el archivo .jrxml dar clic en el botón:  
se envía el mensaje

ç
Observamos en el proyecto, se muestra el archivo .jrxml generado.

Ahora compilamos el reporte 

Observar el proyecto web, contamos con el archivo .jasper generado.


Repetimos el mismo proceso para Details, generamos el .jrxml, y compilamos el reporte.
Proyecto web

Cerramos el plugin, si ejecutamos el proyecto web.
Si ejecutamos el reporte All

Reporte Details

Los nombres de reportes y títulos los puedes cambiar desde el plugin.
Este plugin no es reemplazo a otros plugins o herrramientas para JaspertReport, es un plugin orientado a crear reportes muy rápidos con solo indicar el enitty.

Como son archivos .jrxml, .jasper puedes manipularlos desde cualquier herramienta que lo soporte.

















AVBravo - June 22, 2018 01:36 AM
Libro de trucos JakartaEE

Libro de Trucos JakartaEE versiòn 0.1
Este libro que empece a escribir hace un tiempo, recopila algunos trucos para Java Server Faces, Java EE, Jakarta EE, EJBJMoorDB.
Esta disponible para revisiòn y descarga.
https://legacy.gitbook.com/book/avbravo/trucosjakartaee/details

Es la versiòn 0.1, faltan muchos aspectos por considerar, es una guía para principiantes.


AVBravo - June 16, 2018 08:10 PM
ejbjmoordb Método complete(String query)

ejbjmoordb  Método complete(String query)

Se utiliza para hacer filtros para componentes autocomplete.

Componentes
<p:autocomplete>
Necesitamos definir los atributos

Componente
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <composite:interface >


        <composite:attribute name="value" />
        <composite:attribute name="multiple" default="false" />
        <composite:attribute name="dropdown"  default="false"/>
         <composite:attribute name="minQueryLength"  default="1"/>
        <composite:attribute name="itemLabel" />
        <composite:attribute name="update" />
        <composite:attribute name="rendered"/>
        <composite:attribute name="field"/>
        <composite:attribute name="fromstart" default="true"/>
         <composite:attribute name="required" default="false" />
         <composite:attribute name="size"  default="25"/>
        <composite:attribute name="listener"  
                             method-signature="void handleSelect(org.primefaces.event.SelectEvent)" />

    </composite:interface>
    <composite:implementation>

        <p:autoComplete     dropdown="#{cc.attrs.dropdown}"    
                            scrollHeight="250"  
                             size="#{cc.attrs.size}" 
                             multiple="#{cc.attrs.multiple}" 
                            emptyMessage="#{app['info.nohayregistros']}" 
                            value="#{cc.attrs.value}"  
                            completeMethod="#{tamanoController.tamanoServices.complete}"    
                            var="p"
                             required="#{cc.attrs.required}"
                            itemLabel="#{cc.attrs.itemLabel}"
                            itemValue="#{p}" 
                            forceSelection="true"> 
            <f:converter binding="#{tamanoConverter}"/>
            <f:attribute name="field" value="#{cc.attrs.field}"/>
               <f:attribute name="fromstart" value="#{cc.attrs.fromstart}"/>
                <f:attribute name="fielddropdown" value="#{cc.attrs.dropdown}"/>
            <f:attribute name="fieldminquerylength" value="#{cc.attrs.minQueryLength}"/>
            <p:ajax event="itemSelect" listener="#{cc.attrs.listener}"
                    update="#{cc.attrs.update}" />  
            <f:facet name="itemtip">
                <h:panelGrid columns="1" cellpadding="5">
                    <h:outputText value="#{msg['field.idtamano']} #{p.idtamano}" />
                    <h:outputText value="#{msg['field.descripcion']} #{p.descripcion}" />


                </h:panelGrid>
            </f:facet>
        </p:autoComplete>  

    </composite:implementation>

</html>
Services
Definir el método complete.

public List<Tamano> complete(String query) {
        List<Tamano> suggestions = new ArrayList<>();
        try {
            suggestions = repository.complete(query);
        } catch (Exception e) {
            JsfUtil.errorMessage("complete() " + e.getLocalizedMessage());
        }
        return suggestions;
    }
Código completo
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.avbravo.storeejb.services;

import com.avbravo.storeejb.repository.TamanoRepository;
import com.avbravo.avbravoutils.JsfUtil;
import com.avbravo.storeejb.entity.*;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import org.bson.Document;

/**
 *
 * @authoravbravo
 */
@Stateless
public class TamanoServices {

    @Inject
    TamanoRepository repository;
    List<Tamano> tamanoList = new ArrayList<>();

    public List<Tamano> complete(String query) {
        List<Tamano> suggestions = new ArrayList<>();
        try {
            suggestions = repository.complete(query);
        } catch (Exception e) {
            JsfUtil.errorMessage("complete() " + e.getLocalizedMessage());
        }
        return suggestions;
    }

    // <editor-fold defaultstate="collapsed" desc="getTamanoList()">
    public List<Tamano> getTamanoList() {
        try {
            tamanoList = repository.findAll(new Document("idtamano", 1));
        } catch (Exception e) {
            JsfUtil.errorMessage("getTamanoList() " + e.getLocalizedMessage());
        }
        return tamanoList;
    }// </editor-fold>

    public void setTamanoList(List<Tamano> tamanoList) {
        this.tamanoList = tamanoList;
    }

}
Controller
Injectar el Services, crear mètodos get/set

@Inject

TamanoServices tamanoServices;


public TamanoServices getTamanoServices() {

return tamanoServices;

}


public void setTamanoServices(TamanoServices tamanoServices) {

this.tamanoServices = tamanoServices;

}
Pagina .xhtml
 <p:outputLabel value="#{msg['field.descripcion']}"/>
 <e:autocompletetamano listener="#{tamanoController.handleSelect}"
                       value="#{tamanoController.tamanoSelected}"
                       itemLabel=" #{p.descripcion}"
                       field="descripcion"
                       update=" :form:dataTable"/>

AVBravo - June 14, 2018 07:39 PM
Bases de datos en tiempo de ejecución ejbjmoord (MongoDB)

Bases de datos en tiempo de ejecución ejbjmoord (MongoDB)
En algunas ocasiones deseamos crear bases de datos de manera dinámica, (en tiempo de ejecución) para separar las colecciones que almacenemos en mongodb en varias bases de datos,  con ejbjmoordb, se puede especificar fácilmente mediante el método modeloRepository.setDatabase("mibasedatos");
Si no lo indicamos se tomara el que esta definido en el repository.

Cuando definimos un Repository indicamos la base de datos.


public ModeloRepository(){


super(Modelo.class,"store","modelo");


}


/*


* To change this license header, choose License Headers in Project Properties.


* To change this template file, choose Tools | Templates


* and open the template in the editor.


*/


package com.avbravo.storeejb.repository;


import javax.ejb.Stateless;


import javax.ejb.EJB;


import com.avbravo.ejbjmoordb.mongodb.repository.Repository;


import com.avbravo.storeejb.entity.Modelo;


import com.avbravo.storeejb.provider.MongoClientStoreejbProvider;


import com.mongodb.MongoClient;


import javax.annotation.PostConstruct;


import javax.annotation.PreDestroy;





/**


*


* @author avbravo


*/


@Stateless


public class ModeloRepository extends Repository<Modelo > {





@EJB


MongoClientStoreejbProvider MongoClientStoreejbProvider;


@Override


protected MongoClient getMongoClient() {


return MongoClientStoreejbProvider.getMongoClient();


}


public ModeloRepository(){


super(Modelo.class,"store","modelo");


}


@Override


public Object findById(String key, String value) {


return search(key,value);


}


@Override


public Object findById(String key, Integer value) {


return search(key,value);


}








}

Controller

Si deseamos especificar otra base de datos distinta a la definida en el repository, en el controller agregar en ell metodo init(), el nombre de la base de datos mediante myRepository.setDatabase("mydatabase");

@PostConstruct


public void init() {


try {


modeloRepository.setDatabase("mistore");


}


....


}

El framework creara esta base de datos nueva y almacenara la colecciòn en ella.

Ejemplo 2:

Deseamos crear una base de datos o trabajar con las colecciones dentro de ella en base a un parametro del usuario logegado.
exit: Ctrl + ↩

@PostConstruct


public void init() {


try {


modeloRepository.setDatabase(loginController.getUsuario.getIdtienda());


}


....


}









Al ejecutar la aplicación se crea dinamicamente la nueva base de datos.














De esta manera podemos crear un solo proyecto ejb, y manejar infinitas bases de datos creadas en tiempo de ejecuciòn, relacionadas entre si.








AVBravo - June 07, 2018 03:29 PM
Optional... item Glassfish/Payara

Algunos métodos podemos definir un parametro opcional  por ejemplo Object... item



public String prepare(String action, Object... item) {
        String url = "";
        try {
            loginController.put("pagerol", page.toString());
            loginController.put("rol", action);
            switch (action) {
                case "new":
                    rol = new Rol();
                    rolSelected = new Rol();

                    writable = false;
                    break;

                case "view":
                    if (item.length != 0) {
                        rolSelected = (Rol) item[0];
                        rol = rolSelected;
                        loginController.put("idrol", rol.getIdrol());
                    }

                    url = "/pages/rol/view.xhtml";
                    break;
                case "golist":

                    url = "/pages/rol/list.xhtml";
                    break;

                case "gonew":
                    rol = new Rol();
                    rolSelected = new Rol();
                    url = "/pages/rol/new.xhtml";
                    break;
            }

        } catch (Exception e) {
            JsfUtil.errorMessage("prepare() " + e.getLocalizedMessage());
        }

        return url;
    }// </editor-fold>


Desde una pagina Java Server Faces podemos invocarlo
   <a:paginator
                     clear="#{rolController.clear()}"
                    first="#{rolController.first()}"
                    back="#{rolController.back()}"
                    next="#{rolController.next()}"
                    last="#{rolController.last()}"
                    page="#{rolController.page}"
                    pages="#{rolController.pages}"
                    skip="ajax:rolController.skip(rolController.page)" 
                    new="#{rolController.prepare('gonew',rolController.rol)}"
                    printAll="#{rolController.printAll()}"

                    />

Resultados 
Glassfish 5.0, funciona sin problemas

Payara 5.0, Glassfish 4.0



Para que funcione en Payara 5.0, o Glassfish 4.0, hay que indicar el parámetro correspondiente sin usar el optional.


  public String prepare(String action, Rol item) {
        String url = "";
        try {
            loginController.put("pagerol", page.toString());
            loginController.put("rol", action);
            switch (action) {
                case "new":
                    rol = new Rol();
                    rolSelected = new Rol();

                    writable = false;
                    break;

                case "view":
                   
                        rolSelected =  item;
                        rol = rolSelected;
                        loginController.put("idrol", rol.getIdrol());
                 

                    url = "/pages/rol/view.xhtml";
                    break;
                case "golist":

                    url = "/pages/rol/list.xhtml";
                    break;

                case "gonew":
                    rol = new Rol();
                    rolSelected = new Rol();
                    url = "/pages/rol/new.xhtml";
                    break;
            }

        } catch (Exception e) {
            JsfUtil.errorMessage("prepare() " + e.getLocalizedMessage());
        }

        return url;
    }// </editor-fold>



AVBravo - May 25, 2018 02:07 PM
Combinar bases de datos

Combinar bases de datos
Muchas veces necesitamos usar bases de datos diferentes e integrarlas en un solo proyecto, existen varias situaciones

  • Necesitamos relacionar colecciones almacenadas en bases de datos diferentes
  • En un proyecto web deseamos manipular colecciones de bases de datos diferentes sin relacionar las colecciones

En este caso la colección de solicitud necesita tener una referencia directa con la colección Facultad, por lo tanto necesitamos agregar el proyecto commonejb al proyecto transporteejb, para que la colecciòn Solicitud se pueda relacionar con Facutad.
Proyecto; Transporteejb
Archivo pom.xml
exit: Ctrl + ↩

<dependency>


<groupId>${project.groupId}</groupId>


<artifactId>commonejb</artifactId>


<version>0.1.1</version>


</dependency>








Caso 2:En un proyecto web, deseamos manipular colecciones de bases de datos diferentes sin relacionar las colecciones

Podemos hacerlo mediante Microservicios, Rest-Full, en esta ocasiòn lo podemos hacer también mediante los proyectos ejb que agregamos al proyecto web.



Proyecto: transporte
Archivo: pom.xml

<dependency>


<groupId>${project.groupId}</groupId>


<artifactId>transporteejb</artifactId>


<version>0.3.1</version>


</dependency>


<dependency>


<groupId>${project.groupId}</groupId>


<artifactId>commonejb</artifactId>


<version>0.1.1</version>


</dependency>



AVBravo - May 25, 2018 01:24 PM
Relacionar documentos en bases de datos diferentes

Relacionar documentos en bases de datos diferentes


Podemos mezclar proyectos ejb, para establecer referencias entre documentos que no se encuentran en la misma base de datos, o en un motor NoSQL del mismo tipo. Nos permite mezclar bases de datos y colecciones diferentes.
Contamos con dos bases de datos:
  • commondb
  • transporte

Esquema General


Contamos con los tres proyectos



Proyecto commonejb
El proyecto commonejb, se comunica con la base de datos commondb .

Es un proyecto con acceso a una base de datos comunes para muchas aplicaciones, esto lo podemos hacer mediante mecanismos usando Rest-Ful, pero en este ejemplo usaremos el proyecto como dependencia para otros proyectos.
Cambiamos el nombre del MongoClientProvider de cada proyecto para que no existan conflictos. Esta clase tiene la conexión a la base de datos.
Podemos contar con bases de datos en el mismo servidor o en servidores remotos separados una de otra.

se mostraría de esta manera

Contamos con un entity llamado Facultad que puede ser usado por muchas aplicaciones.

Entity Facultad


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.avbravo.commonejb.entity;

import com.avbravo.ejbjmoordb.anotations.Embedded;
import com.avbravo.ejbjmoordb.anotations.Id;
import com.avbravo.ejbjmoordb.pojos.UserInfo;
import java.util.List;
import lombok.Getter;
import lombok.Setter;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Facultad {
    @Id
    private Integer idfacultad;
    private String facultad;
    private String activo;
      @Embedded
    List<UserInfo> userInfo;

    public Facultad() {
    }
      
      
}

El proyecto transporteejb
Da acceso a la base de datos transporte.

Si lo usamos para relacionarlo con otro proyecto , debemos usar la nomenclatura para el MongoClientProvider, repository,services con {nombreproyecto}



En las dependencias agregamos el proyecto commonejb

Podemos crear referencias a los documentos aunque no estén en la misma base de datos.
Deseamos relacionar la colección Solicitud en la base de datos transporte con la coleccion Facultad en la base de datos commondb.
Creamos un objeto de tipo List<Facultad> ya que deseamos almacenar una lista de facultades, es importante indicar en el repository la ruta donde esta ubicado el repository Facultad en el otro proyecto, de esta manera el framework, lo podrá encontrar fácilmente aunque no estén en el mismo servidor o use el mismo motor de la base de datos.

@Referenced(documment = "Facultad",
field = "idfacultad", javatype = "Integer", lazy = false,
repository = "com.avbravo.commonejb.repository.FacultadRepository")
List<Facultad> facultad;
exit: Ctrl + ↩



En este ejemplo creamos una lista de Facultades desde el Entity Solicitud en la base de datos transportes, que hace referencia a la colección Facultad que se encuentra en la otra base de datos commondb.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.avbravo.transporteejb.entity;

import com.avbravo.commonejb.entity.Facultad;
import com.avbravo.ejbjmoordb.anotations.Embedded;
import com.avbravo.ejbjmoordb.anotations.Id;
import com.avbravo.ejbjmoordb.anotations.Referenced;
import com.avbravo.ejbjmoordb.pojos.UserInfo;
import java.util.Date;
import java.util.List;
import lombok.Getter;
import lombok.Setter;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Solicitud {
    @Id
    private Integer idsolicitud;
    private String periodoacademico;
    private Date fecha;
    private String numerogrupo;
    private String carrera;
     @Referenced(documment = "Facultad",
            field = "idfacultad", javatype = "Integer", lazy = false,
           repository = "com.avbravo.commonejb.repository.FacultadRepository")
    List<Facultad> facultad;

    private String responsable;
    private String telefono;
    private String email;
    private String mision;
   
    
    @Referenced(documment = "Usuario",
            field = "username", javatype = "String", lazy = false,
           repository = "com.avbravo.transporteejb.repository.UsuarioRepository")
    Usuario usuario;
   
    
    private String objetivo;
    private String lugares;
    
    private Date fechahorapartida;
    private String lugarpartida;
    
    private Date fechahoraregreso;
    
    private String lugarllegada;
    private String recursossolicitados;
    private String observaciones;
    
     @Referenced(documment = "Estatus",
            field = "idestatus", javatype = "String", lazy = false,
           repository = "com.avbravo.transporteejb.repository.EstatusRepository")
    Estatus estatus;
    
    private Date fechaestatus;
    
    private Integer pasajeros;
      @Referenced(documment = "Tiposolicitud",
            field = "idtiposolicitud", javatype = "String", lazy = false,
           repository = "com.avbravo.transporteejb.repository.TiposolicitudRepository")
   Tiposolicitud tiposolicitud;
      
      
       @Referenced(documment = "Unidad",
            field = "idunidad", javatype = "String", lazy = false,
            repository = "com.avbravo.transporteejb.repository.UnidadRepository")
    private List<Unidad> unidad;
      private String activo;
    
    @Embedded
    List<UserInfo> userInfo;
    
}


Proyecto web transporte

Solo necesitamos agregar la dependencia transporteejb, ya que commonejb, fue agregada a ese proyecto.






AVBravo - May 21, 2018 05:19 PM
Arquitecturas de software

¿Las arquitecturas de software son importantes?.
Realmente es difícil crear aplicaciones escalables y soluciones empresariales sin basarnos es arquitecturas adecuadas.
Recientemente encontramos batallas Monolíticos vs Microservicios, SQL vs NoSQL, JakartaEE vs Spring (Boot, Cloud,Data). REST, SOA, Angular, OracleJET, Express, Play,  etc.
Para alguien que se inicia, encontraría muchos lenguajes de programaciòn herramientas, frameworks , bases de datos, Server, que puede perder el enfoque o no saber por donde iniciar.
Los patrones de diseños, metodologías (TDD, BDD, ATDD), entre algunas nos muestran el camino por donde iniciar.
Lo cierto es que cada implementaciòn puede ser afectada por las arquitecturas que cada empresa o equipos de desarrollo logren adaptar, que permita un desarrollo  eficiente y escalable.
Sin duda construir un API o framework, es un proceso complejo de cientos de pruebas, de adaptaciones, para lograr un modelo de trabajo simple para los desarrolladores.

En algunos casos el conocer las diversas etapas da un entendimiento preciso y hace màs productivo a los equipos. Las etapas de construir una arquitectura eficaz , consume mucho tiempo que es difícil ser visto por los equipos en etapas superiores.






Cada equipo se adapta a los estándares establecidos , muchos crean sus herramientas, contribuyendo a mejorar a otros equipos mediante sus casos de usos.

AVBravo - May 16, 2018 05:15 PM
multiple

<p:autocomplete> Multiple.

En algunas ocasiones necesitamos un autocomplete para almacenar múltiples selecciones.

En este ejemplo asignamos múltiples roles a un usuario.
Contamos con esta estructura

Entity

Usuario.java
import com.avbravo.ejbjmoordb.anotations.Embedded;
import com.avbravo.ejbjmoordb.anotations.Id;
import com.avbravo.ejbjmoordb.anotations.Referenced;
import com.avbravo.ejbjmoordb.pojos.UserInfo;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Usuario {

    @Id
    private String username;
    private String password;    
    private String nombre;
    private String cedula;
    private String celular;
    private String cargo;
    private String email;
    @Referenced(documment = "Rol",
            field = "idrol", javatype = "String", lazy = false,
            repository = "com.avbravo.transporteejb.repository.RolRepository")
    private List<Rol> rol;

    private String activo;
    @Embedded
    List<UserInfo> userInfo;

    public Usuario() {
    }

}

Rol.java
import com.avbravo.ejbjmoordb.anotations.Embedded;
import com.avbravo.ejbjmoordb.anotations.Id;
import com.avbravo.ejbjmoordb.pojos.UserInfo;
import java.util.List;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Rol {
  @Id
    private String idrol;
    private String rol;
      private String activo;
   @Embedded
    List<UserInfo> userInfo;
    public Rol() {
    }

    @Override
    public String toString() {
        return "Rol{" + "idrol=" + idrol + ", rol=" + rol + '}';
    }
    
    
}



Componente

<p:autoComplete     dropdown="false"   
                 
                            multiple="true" 
                            scrollHeight="250"  
                             size="25" 
                            emptyMessage="#{app['info.nohayregistros']}" 
                            value="#{usuarioController.rolList}"  
                            completeMethod="#{usuarioController.completeFiltrado}"    
                            var="p"
                            required="true"
                            itemLabel="#{p.idrol}"
                            itemValue="#{p}" forceSelection="true"> 
            <f:converter binding="#{rolConverter}"/>
            <f:attribute name="field" value="idrol"/>
            <p:ajax event="itemSelect" listener="#{rolController.handleSelect}"
                   />  
            <f:facet name="itemtip">
                <h:panelGrid columns="1" cellpadding="5">
                    <h:outputText value="#{msg['field.idrol']} #{p.idrol}" />
                    <h:outputText value="#{msg['field.rol']} #{p.rol}" />

                </h:panelGrid>
            </f:facet>
        </p:autoComplete>  


UsuarioController.java

  public List<Rol> completeFiltrado(String query) {
        List<Rol> suggestions = new ArrayList<>();
        List<Rol> temp = new ArrayList<>();
        try {
            Boolean found = false;
            query = query.trim();
            if (query.length() < 1) {
                return suggestions;
            }
            String field = (String) UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getAttributes().get("field");
            temp = rolRepository.findRegex(field, query, true, new Document(field, 1));

            if (rolList.isEmpty()) {
                if (!temp.isEmpty()) {
                    suggestions = temp;
                }
            } else {
                if (!temp.isEmpty()) {
                 
                    for (Rol r : temp) {
                        found = false;
                        for(Rol r2:rolList){
                            if(r.getIdrol().equals(r2.getIdrol())){
                                found=true;
                            }
                        }
                        if(!found){
                            suggestions.add(r);
                        }

                    }
                }

            }
            //suggestions=  rolRepository.findRegex(field,query,true,new Document(field,1));

        } catch (Exception e) {
            JsfUtil.errorMessage("complete() " + e.getLocalizedMessage());
        }
        return suggestions;
    }


AVBravo - March 24, 2018 04:02 PM
ejbjmoordb 0.5.7

ejbjmoordb 0.5.7
Nueva versión soporta busquedas con expresiónes regulares agregando filtros.

Ejemplos:

  • Busca en el documento referenciado "articulo.idarticulo", que inicie por el valor en el atributo query.


String query="1-x";


List<Inventario> list = inventarioRepository.findRegex("articulo.idarticulo", query, true, new Document(field, 1));

  • Ejemplo con Filter(Busca por expresion regular en articulo.idarticulo y aplica dos filtros más (Solo String para otros tipos de valores use Filter)



List<Inventario> list = inventarioRepository.findRegex("articulo.idarticulo", query, true, "id", bodegaSelected.getIdbodega(), "tipoid", "bodega", new Document(field, 1));

Ejemplo con Filter(Busca por expresion regular en articulo.idarticulo y aplica dos filtros más




exit: Ctrl + ↩


Bson filter =Filters.and(Filters.eq("id",bodegaSelected.getIdbodega()), Filters.eq("tipoid","bodega"));


List<Inventario> ist = inventarioRepository.findRegex("articulo.idarticulo", query, true, filter, new Document(f




MétodoBases de datos NoSQL (MongoDB)
public List< T > findRegex(String key, String value, Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresion
public List<T> findRegexInText(String key, String value, Boolean caseSensitive, Document... docSort)MongoDBBusca en cualquier parte del Texto
public List<T> findRegexPagination(String key, String value, Boolean caseSensitive, Integer pageNumber, Integer rowsForPage,Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión con paginación.
public List<T> findRegexInTextPagination(String key, String value, Boolean caseSensitive, Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en cualquier parte del texto con paginación

Filtros agregando por una condición and adicional(String keySecond,String valueSecond)
List<T> findRegex(String key, String value, Boolean caseSensitive, String keySecond,String valueSecond,Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión y agrega un filtro and adicional por otro atributo.
List<T> findRegexInText(String key, String value, Boolean caseSensitive, String keySecond,String valueSecond, Document... docSort)MongoDBBusca en cualquier parte del texto agregando un filtro and por otro atributo.
List<T> findRegexPagination(String key, String value, Boolean caseSensitive,String keySecond,String valueSecond, Integer pageNumber, Integer rowsForPage,Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión con paginación, agregando un filtro and por otro atributo.
List<T> findRegexInTextPagination(String key, String value, Boolean caseSensitive, String keySecond,String valueSecond,Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en cualquier parte del texto agregando un filtro and adicional por otro atributo y aplica paginación.

Filtros agregando dos condiciónes and adicional(String keySecond,String valueSecond,String keyThree, String valueTree)
List<T> findRegex(String key, String value, Boolean caseSensitive, String keySecond, String valueSecond, String keyThree, String valueTree, Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión y agrega dos flltros and adicionales
List<T> findRegexInText(String key, String value, Boolean caseSensitive, String keySecond, String valueSecond,String keyThree, String valueTree, Document... docSort)MongoDBBusca en cualquier parte del texto agregando dos filtros and adicionales.
List<T> findRegexPagination(String key, String value, Boolean caseSensitive, String keySecond, String valueSecond, String keyThree, String valueThree,Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión con paginación, agregando dos filtros and adicionales.
List<T> findRegexInTextPagination(String key, String value, Boolean caseSensitive, String keySecond, String valueSecond,String keyThree, String valueThree, Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en cualquier parte del texto agregando dos filtros and adicional por otro atributo y aplica paginación.

Filters
List<T> findRegex(String key, String value, Boolean caseSensitive,Bson filter, Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresón agrega un filtro Bson.
List<T> findRegexInText(String key, String value, Boolean caseSensitive, Bson filter, Document... docSort)MongoDBBusca en cualquier parte del Texto y aplica filtros Bson.
List<T> findRegexPagination(String key, String value, Boolean caseSensitive, Bson filter, Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en el texto desde el inicio que coincida con la expresión con paginación y aplica el filtro que le indiquemos
List<T> findRegexInTextPagination(String key, String value, Boolean caseSensitive, Bson filter, Integer pageNumber, Integer rowsForPage, Document... docSort)MongoDBBusca en cualquier parte del texto con paginación, e implementa un filtro que se indique.


AVBravo - March 12, 2018 09:24 PM
ejbmoordb 0.5.6

ejbmoordb 0.5.6
La nueva versiòn incorpora nuevos mètodos:

Búsquedas por Día filterDayWithoutHour()

  • En algunos casos tenemos formularios donde se almacenan en formato dd/MM/yyyy hh:mm:ss
  • Necesitamos hacer busquedas por ejemplo de un solo dia sin tomar en cuenta las horas.
Por ejemplo si creamos la fecha de inicio con 01/02/2018 05:00:00, y hacemos una busqueda directa por el campofechainicio(), pasandole solo el dia no lo encontraría en la lista, ya que necesita los demàs datos (horas ,minutps y segundos). En este caso recurrimos al mètodo filterDateWithOutHour(), que hace busquedas en un dia sin tomar en cuenta la hora.



Resultado:
Devuelve los documentos qBúsquedas en Fecha filterDayWithoutHour()ue estén filtrados en ese dìa sin tomar en cuenta horas, minutos y segundos.
Se usa para consultar un dia especifico.
Mètodo

  • List<T> filterDayWithoutHourPagination(String secondaryfield,String secondaryfieldvalue, String fielddate, Date datevalue, Integer pageNumber, Integer rowsForPage, Document... docSort)
Filtra la fecha de un dia con un and por la llave primaria (String) u otro atributo, y no toma en cuenta las horas. Por ejemplo cuando deseamos consultar los datos de un dia sin tomar en cuenta las horas.

  • List<T> filterDayWithoutHourPagination(String secondaryfield,Integer secondaryfieldvalue, String fielddate, Date datevalue, Integer pageNumber, Integer rowsForPage, Document... docSort)
Filtra la fecha de un dia con un and de llave primaria u otro atributo entero. Ignorando las horas del dìa.

  • List<T> filterDayWithoutHour(String secondaryfield,String secondaryfieldvalue, String fielddate, Date datevalue, Document... docSort)
Filtra por la fecha y otro atributo entero excluyendo la hora y sin paginaciòn.

  • List<T> filterDayWithoutHour(String secondaryfield,Integer secondaryfieldvalue, String fielddate, Date datevalue, Document... docSort)
Filtra por la fecha y el otro atributo entero excluyendo la hora y sin paginaciòn.

  • List<T> filterDayWithoutHour(String fielddate, Date datevalue, Document... docSort)
Filtra toda la colecciòn sin paginaciòn para devolver el dia que se indica sin tomar en cuenta las horas.

  • List<T> filterDayWithoutHourPagination(String fielddate, Date datevalue, Integer pageNumber, Integer rowsForPage, Document... docSort)
Filtra toda la colecciòn con paginaciòn para devolver el dia que se indica sin tomar en cuenta las horas.

Parametros

PàrametroDescripciòn
secondaryfieldNombre de campo adicional para el filtro. Por ejemplo filtrar por fecha y por el idagente.
secondaryfieldvalueValor del campo secundario de filtro
datefieldnombre del campo fecha a buscar
valuedatevalor del campo fecha a buscar excluyendo la hora.
docSortDocument con la ordenaciòn.
pageNumberNùmero de pagina actual
rowsForPagenumero de filas por pagina.
Ejemplo

permisoList = permisoRepository.filterDayWithoutHourPagination("agente.idagente", agente.getIdagente(), "fechainicio", ppermisoSearch.getFechainicio(),page,rowPage, new Document("idpermiso", -1));

Si fuese manual construir el filtro de la siguiente manera:


Bson filter = Filters.and(


Filters.eq("agente.idagente",agente.getIdagente())


, Filters.gte("fechainicio", permisoSearch.getFechainicio()),


Filters.lte("fechainicio", permisoSearch.getFechainicio()));







permisoList = permisoRepository.filters(filter, new Document("idpermiso", -1));











Búsquedas entre Fechas con filtros




  • List<T> filterBetweenDate(String secondaryfield,String secondaryfieldvalue,String fieldnamestart, Date datestartvalue, String fieldlimitname, Date datelimitvalue, Document... docSort)







Filtra en un rango de fechas e incluye una condiciòn and en el filtro para buscar por otro campo sin paginaciòn. Ejemplo buscar de todos los idagente =14 y fecha entre el 1 y 28 de ewnero de 2018.






  • List<T> filterBetweenDatePagination(String secondaryfield,String secondaryfieldvalue,String fieldnamestart, Date datestartvalue, String fieldlimitname, Date datelimitvalue, Integer pageNumber, Integer rowsForPage, Document... docSort)




Filtra en un rango de fechas con paginaciòn e incluye un filtro and adicional.
Ejemplo:
permisoList = permisoRepository.filterBetweenDatePagination("agente.idagente", agente.getIdagente(),"fechainicio", lookupServices.getFechaincio(), "fechafin", lookupServices.getFechafin(), page, rowPage, new Document("idpermiso", -1));









AVBravo - March 11, 2018 02:00 AM
ejbmoordb 0.5.5 rangos de enteros y doubles

La versión ejbmoordb 0.5.5 soporta los métodos para filtrar rangos de enteros y doubles y con paginación.


    public List<T> filterBetweenDoublePagination(String fieldnamestart, Integer startvalue, String fieldlimitname, String limitvalue,Integer pageNumber, Integer rowsForPage, Document... docSort) 



 public List<T> filterBetweenDouble(String fieldnamestart, Integer startvalue, String fieldlimitname, String limitvalue, Document... docSort)



 public List<T> filterBetweenIntegerPagination(String fieldnamestart, Integer startvalue, String fieldlimitname, Integer limitvalue,Integer pageNumber, Integer rowsForPage, Document... docSort) 



public List<T> filterBetweenInteger(String fieldnamestart, Integer startvalue, String fieldlimitname, Integer limitvalue, Document... docSort)




AVBravo - March 10, 2018 07:13 PM
ejbmoordb 0.5.4 paginación

La versión 0.5.4 de ejbmoordb contiene implemenación de paginación en los nuevos  métodos:

 public List<T> findRegexPagination(String key, String value, Boolean caseSensitive, Integer pageNumber, Integer rowsForPage,Document... docSort)

public List<T> findRegexInTextPagination(String key, String value, Boolean caseSensitive, Integer pageNumber, Integer rowsForPage, Document... docSort)


public List<T> filterBetweenDatePagination(String fieldnamestart, Date datestartvalue, String fieldlimitname, Date datelimitvalue, Integer pageNumber, Integer rowsForPage, Document... docSort)

public List<T> filtersPagination(Bson filter, Integer pageNumber, Integer rowsForPage, Document... docSort)

public List<T> filterBetweenDatePagination(String fieldnamestart, Date datestartvalue, String fieldlimitname, Date datelimitvalue, Integer pageNumber, Integer rowsForPage, Document... docSort)


public List<T> findTextPagination(String key, String value, Boolean caseSensitive, Boolean diacriticSensitive,Integer pageNumber, Integer rowsForPage, Document... docSort)

public List<T> helpersPagination(String predicate, String key, Object value, Integer pageNumber, Integer rowsForPage, Document... docSort)

  public List<T> findHelperSortPagination(String predicate, Document doc, String key, String value, Integer pageNumber, Integer rowsForPage) ,



Ejemplo:
  permisoList = permisoRepository.findFilterPagination(doc,page,rowPage, new Document("idpermiso", -1));

AVBravo - March 08, 2018 10:23 PM
Filtrar fechas en Mongodb con JMoordb

En muchas ocasiones necesitamos filtrar un rango de fechas en una colecciòn en mongodb
En jmoordb, creamos un mètodo
 public List<T> filterBetweenDate(String fieldnamestart, Date datestartvalue, String fieldlimitname, Date datelimitvalue, Document[] docSort)
que devuelve un List<> de documentos de una colecciòn filtrados entre fechas.




List<Permiso> list =permisoRepository.filterBetweenDate("fechainicio", permiso.getFechainicio(), "fechafin", permiso.getFechafin(), new Document("idpermiso", -1));


AVBravo - January 26, 2018 02:01 AM
Duke's Choice Award 2017

Después de muchos años en la comunidad Java. Y formando parte de JEspanol un grupo conformado por JUG-Leaders y Java Champions de America Latina(Alexis Lopez , Diego S Lima,Jorge Vargas, Cesar Hernandez. Andres Almari, Jose Diaz Diaz, Victor Orosco), http://www.jespanol.org/ , obtuvimos un Duke's Choice Award en el Java One 2017, en el dia de hoy recibí la estatuilla. Sin duda muchas gracias a JEspañol.



AVBravo - January 22, 2018 07:55 PM
Testing (Progresivo)

Testing (Progresivo)
Realmente una parte fundamental del desarrollo de aplicaciones la implementaciòn de pruebas, en el mundo Java se cuentan con muchas herramientas. (TDD, BDD, ATDD).
Entre algunos :

  • JUnit
  • Arquillian  
  • Selenium
  • JCucumber, 
  • Mockito,
  • EasyMock

Muchas veces creamos un entorno embebido para ejecutar pruebas (Arquillian), Antonio Gongalves
escribio un blog : Java EE vs Spring Testing.
Donde explicaba la complejidad de hacer los test y la viabilidad de los mismos.

Conocemos la situación actual con EJB el movimiento de Java EE a EE4J,  la era de microservicios, muchas implementaciones han cambiado, una forma nueva de desarrollar aplicaciones y consumir data. (Rest-Ful, JAX-RS, bases de datos NoSQL).


Que ocurriría si alteramos la forma de hacer los test en un entorno JavaEE que usa EJB:
  • Hacer los test en  entornos de ejecución  y no en entornos embebidos.(Tendríamos un entorno  real para las pruebas).
  • Hacer test progresivos, tendríamos un esquema de adaptación mas ágil.
  • Generar las interfaces en base a los test(Tal vez ayudaría al equipo a entender la vista de una pagina que no paso un test), seria componer interfaces en base a testing.



Componentes:
  • Proyecto Java EE
  • Proyecto EJB que contiente los Entity y Repository
  • PayaraMicro (Podria implementar con otro)
  • Framework de Test




Modelo:

  • Utilizamos dos clases
  • UnitTest : Para reporte del test
  • UnitView: Para generar interfaces desde los test.

Ejemplos:

Test Simple

 @Test
    public String save() {
        try {

//Mock
            Color color = new Color();
            color.setActivo("si");
            color.setAutoincrementable(15);
            color.setIdcolor("rojo");
            List<UserInfo> list = new ArrayList<>();
            color.setUserInfo(list);
            Boolean expResult = true;
            
           unitTest.assertEquals("save", true, colorRepository.save(color));

         
        } catch (Exception e) {
            System.out.println("save() " + e.getLocalizedMessage());
        }

        return "";
    }

Reportes

Ejemplo de una ejecuciòn



Test diseñando una interface.
El equipo de Testing, crea el Test y genera una interfaz de como seria la aplicaciòn final.

 @Test
    public String save() {
        try {
//            unitView.message("Testeando save()");
//Mock
            Color color = new Color();
            color.setActivo("si");
            color.setAutoincrementable(15);
            color.setIdcolor("rojo");
            List<UserInfo> list = new ArrayList<>();
            color.setUserInfo(list);
            Boolean expResult = true;
            Boolean save = unitTest.assertEquals("save", true, colorRepository.save(color));

            /*
            Dibuja la interfaz
             */
            unitView.form();
            unitView.formTitle("Registros de colores");
            unitView.panel();

            unitView.panelAddInputText(Arrays.asList(new InputText("idcolor", color.getIdcolor()),
                    new InputText("activo", color.getActivo())));

           
            unitView.panelClose();
            unitView.buttonGreen("Save");
            unitView.formClose();
            if (save) {
                unitView.message("se guardo exitosamente");
            } else {
                unitView.error("No se pudo guardar");
            }

        } catch (Exception e) {
            System.out.println("save() " + e.getLocalizedMessage());
        }

        return "";
    }

Ejecución:
Genera el resultado del Test y muestra la interface.





Tabla:
 @Test
    public String findAll() {
            List<Color> colorList = colorRepository.findAll();
                unitTest.assertEquals("findAll", 1, colorList.size());
                unitView.formTitle("findAll()");
                unitView.tableHeader(Arrays.asList(new RowView("idcolor"), new RowView("activo")));
                colorRepository.findAll().forEach((c) -> {
                    unitView.tableCol(Arrays.asList(new ColView(c.getIdcolor()), new ColView(c.getActivo())));
                });
                unitView.tableClose();
         
         
   
        return "";
    }

Genera

AVBravo - December 27, 2017 04:26 AM
Jmoordb 0.3.1 Paginación MongoDB

La versión 0.3.1 de JMoordb soporta paginación mediante métodos directos.



Deseamos cargar documentos en un datatable,  primefaces, ofrece LazyDataModel, que nos brinda la posibilidad de cargar unos documentos  y no el total de la colección. Si existen miles de documentos impactaría en el rendimiento de la aplicación,
Solo se cargan los que se indiquen en la cantidad de filas por pagina.

Este ejemplo haremos de manera tradicional, crearemos un datatable y definiremos los botones para avanzar o retroceder. además implementaremos una forma tradicional de cargar los documentos, mediante paginación en mongodb, utilizando la implementación ejbmoordb 0.3.1.

Dependencias
 <dependency>
            <groupId>com.github.avbravo</groupId>
            <artifactId>ejbjmoordb</artifactId>
            <version>0.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.github.avbravo</groupId>
            <artifactId>avbravoutils</artifactId>
            <version>0.15</version>
        </dependency>

<repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>



Entity
@Getter
@Setter
public class Bodega {

    @Id
    private String idbodega;
    private String telefono;
    private String direccion;
    private String activo;
}

Facade

@Stateless
public class BodegaFacade extends AbstractFacade<Bodega> {

    @EJB
    MongoClientProvider mongoClientProvider;
    @Override
    protected MongoClient getMongoClient() {
       return mongoClientProvider.getMongoClient();
    }
    public BodegaFacade(){
        super(Bodega.class,"spardjsd","bodega");
    }
    @Override
    public Object findById(String key, String value) {
       return search(key,value);
    }
    @Override
    public Object findById(String key, Integer value) {
        return search(key,value);
    }

}


Datamodel

public class BodegaDataModel extends ListDataModel<Bodega> implements SelectableDataModel<Bodega>{

    public BodegaDataModel() {
    }
    public BodegaDataModel(List<Bodega>data) {
        super(data);
    }

    @Override
    public Bodega  getRowData(String rowKey) {
        List<Bodega> bodegaList = (List<Bodega>) getWrappedData();
        for (Bodega bodega : bodegaList) {
             if (bodega.getIdbodega().equals(rowKey)) {
                 return bodega;
             }
        }
        return null;
     }
     @Override
     public Object getRowKey(Bodega bodega) {
         return bodega.getIdbodega();
     }


}




Interface
public interface IController <T> {

    public String open();
    public String prepareNew();
    public String verifyNew();
    public void reset();
    public String showAll();
    public String save();
    public String query();
    public String edit();
    public String remove();
    public String remove(Object item);
    public String delete();
    public String deleteAll();
    public String print();
    public String printAll();
    public String prepareEdit();
    public void handleSelect(SelectEvent event);
    public String last();
    public String first();
    public String next();
    public String back();
    public String skip(Integer page);
    public void move();

}


Controller

Definir
 Integer page = 1; //getset
    Integer rowPage = 2; //getset
    List<Integer> pages = new ArrayList<>();

public List<Integer> getPages() {
        pages = new ArrayList<>();
        Integer size = bodegaFacade.sizeOfPage(rowPage);
        for (int i = 1; i <= size; i++) {
            pages.add(new Integer(i));

        }
        return pages;
    }

    public void setPages(List<Integer> pages) {
        this.pages = pages;
    }




@PostConstruct
    public void init() {
        try {


            found = false;
            forsearch = false;
            bodegaList = new ArrayList<>();
            bodegaFiltered = new ArrayList<>();
            bodega = new Bodega();
            String idbodega = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("idbodega");
            if (idbodega != null) {
                Optional<Bodega> optional = bodegaFacade.find("idbodega", idbodega);
                if (optional.isPresent()) {
                    bodega = optional.get();
                    bodegaSelected = bodega;
                    found = true;
                    forsearch = true;
                    writable = true;
                    RequestContext.getCurrentInstance().update(":form:content");
                }
            } else {
                bodegaList = bodegaFacade.findPagination(page, rowPage);

                bodegaFiltered = bodegaList;
            }
            bodegaDataModel = new BodegaDataModel(bodegaList);

        } catch (Exception e) {
            JsfUtil.errorMessage("init() " + e.getLocalizedMessage());
        }
    }// </editor-fold>




@Override
    public String last() {
        try {
            page = bodegaFacade.sizeOfPage(rowPage);
            move();
        } catch (Exception e) {
            JsfUtil.errorMessage("last() " + e.getLocalizedMessage());
        }
        return "";
    }

    @Override
    public String first() {
        try{
        page = 1;
        move();
 } catch (Exception e) {
            JsfUtil.errorMessage("first() " + e.getLocalizedMessage());
        }
        return "";
    }

    @Override
    public String next() {
        try {
            if (page < (bodegaFacade.sizeOfPage(rowPage))) {
                page++;
            }
            move();
        } catch (Exception e) {
            JsfUtil.errorMessage("next() " + e.getLocalizedMessage());
        }
        return "";
    }

    @Override
    public String back() {
        try {
            if (page > 1) {
                page--;
            }
            move();
        } catch (Exception e) {
            JsfUtil.errorMessage("back() " + e.getLocalizedMessage());
        }
        return "";
    }

    @Override
    public String skip(Integer page) {
        try {
            this.page = page;
            move();
        } catch (Exception e) {
            JsfUtil.errorMessage("skip() " + e.getLocalizedMessage());
        }
        return "";
    }

    @Override
    public void move() {
        try {

            bodegaList = bodegaFacade.findPagination(page, rowPage);

            bodegaFiltered = bodegaList;

            bodegaDataModel = new BodegaDataModel(bodegaList);

        } catch (Exception e) {
            JsfUtil.errorMessage("move() " + e.getLocalizedMessage());
        }
    }



pagina

Colocamos los botones y un selectOneMenu

 <p:dataTable id="dataTable" var="item"
                                         value="#{bodegaController.bodegaDataModel}"
                                         selectionMode="single"
                                         widgetVar="widgetDataTable"
                                         selection="#{bodegaController.bodegaSelected}"
                                         filteredValue="#{bodegaController.bodegaFiltered}"
                                         rowKey="#{item.idbodega}"
                                         rows="15"
                                         paginator="true" paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                         rowsPerPageTemplate="5,10,15" emptyMessage="#{app['info.datatableempty']}" reflow="true">
                           <f:facet name="header">
                           
                                   <p:outputPanel>
                    <p:commandButton class="btnn btnn-primary"  icon="fa fa-step-backward"                    
                                   title="Inicio"       oncomplete="remoteshowall();"
                                    action="#{bodegaController.first()}"  update=":form:dataTable " />

               <p:commandButton class="btnn btnn-primary"  icon="fa fa-caret-left"  
                                           title ="Anterior" 
                                            oncomplete="remoteshowall();"
                                           action="#{bodegaController.back()}"  update=":form:dataTable " /> 

                 <p:commandButton class="btnn btnn-primary"  icon="fa fa-play"  
                                           title="Siguiente" 
                                           oncomplete="remoteshowall();"
                                           action="#{bodegaController.next()}"  update=":form:dataTable " /> 
                             
           <p:commandButton class="btnn btnn-primary"  icon="fa fa-step-forward"  title="Fin" 
                                            oncomplete="remoteshowall();"
                                           action="#{bodegaController.last()}"  update=":form:dataTable " /> 

                <p:selectOneMenu id="pages" value="#{bodegaController.page}" effect="fold"                                                editable="false">

                                            <f:selectItems value="#{bodegaController.pages}" />
                                             <p:ajax  process="pages"  event="change"
                                                      oncomplete="remoteshowall();"
                                                 update=":form:dataTable" 
                                                 listener="#{bodegaController.skip(bodegaController.page)}"/> 
                                        </p:selectOneMenu> 
                                     
                                <p:remoteCommand  update=":form:content :form:content"
                                                  name="remoteshowall" />

                                        <div class="searchLoader">
                                            <p:graphicImage  name="/img/search-loader.gif"/>
                                        </div>
                                        <input type="text" jsf:id="globalFilter" jsf:onkeyup="PF('widgetDataTable').filter()" class="search" placeholder="#{app['button.search']}"/>
                                    </p:outputPanel>
                                </f:facet>
                                <p:ajax event="rowSelect" update=":form:bodegaDetaill" oncomplete="PF('bodegaDialog').show()" />

                                <p:column headerText="#{msg['field.idbodega']}" filterBy="#{item.idbodega}"
                                          sortBy="#{item.idbodega}"  filterMatchMode="contains" >
                                    <h:outputText value="#{item.idbodega}" />
                                </p:column>
                                <p:column headerText="#{msg['field.direccion']}" filterBy="#{item.direccion}"
                                          sortBy="#{item.direccion}"  filterMatchMode="contains" >
                                    <h:outputText value="#{item.direccion}" />
                                </p:column>
                                <p:column headerText="#{msg['field.telefono']}" filterBy="#{item.telefono}"
                                          sortBy="#{item.telefono}"  filterMatchMode="contains" >
                                    <h:outputText value="#{item.telefono}" />
                                </p:column>

                                <p:column style="width:32px;text-align: center">

                                    <p:commandButton update=":form:bodegaDetaill"
                                                     class="btnn btnn-primary"
                                                     icon="fa fa-server"
                                                     title="#{msg['button.etiqueta']}"
                                                     action="#{bodegaController.prepareEdit()}"
                                                     oncomplete="PF('bodegaDialog').show()"  >

                                        <f:param name="idbodega" value="#{item.idbodega}"/>
                                    </p:commandButton>


                                </p:column>
                                <p:column style="width:32px;text-align: center">


                                    <p:commandButton class="btnn btnn-danger"
                                                     rendered="#{applicationMenu.bodega.delete}"
                                                     icon="fa fa-trash-o"
                                                     title="#{app['button.delete']}"
                                                     process=":form:content :form:dataTable"
                                                     action="#{bodegaController.remove(item)}"
                                                     update=":form:content" >
                                        <p:confirm header="#{app['dialog.delete']}" message="#{app['info.doyouwantdelete']}" icon="ui-icon-alert" />
                                    </p:commandButton>


                                </p:column>


                            </p:dataTable>





AVBravo - October 21, 2017 02:04 AM
JMoordb v0.2.8 Implementación de Auditorias y Revisiones

Esta disponible la versión 0.2.8 de ejbmoordb, el framework para NoSQL

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.avbravo</groupId>
<artifactId>ejbjmoordb</artifactId>
<version>0.2.8</version>
</dependency>

Se actualizo el libro JMoordb con el capitulo 9 donde se muestran las nuevas implementaciones, aquí puedes consultar al capitulo 9.

https://avbravo.gitbooks.io/jmoordb/content


Muchas ocasiones es importante hacer auditorias sobre los documentos, conocer el usuario que desarrollo determinada actividad en una fecha y hora especifica, o contar con un historial de los documentos eliminados o actualizados.
Existen infinidad de formas de hacer las implementaciones, dentro de JMoordb, se han creado dos Entitys y dos Services que facilitan las operaciones sobre documentos y permiten un mecanismo para realizar auditos sobre las operaciones realizadas.
Este capitulo muestra la implementación dentro de JMoordb y un ejemplo practico de uso.
Muchas bases de datos NoSQL almacenan diferentes versiones del mismo documento.

Introducción

Definición Interna de Entitys


EntityDescripción
AccessInfoInformación del acceso del usuario al sistema y a los documentos
UserInfoInformación del usuario que interactua con un documento.
RevisionHistoryAlmacena el documento completo en un historial para dar seguimiento a las actividades de auditorias.

Entity AccessInfo

PropiedadDescripción
idaccessinfoAutogenerado
usernameLLave primaria del usuario
datetimeFecha y hora de la operacion
formEl formulario o proceso donde se realiza el acceso
ipEl ip del usuario que se conecta al sistema
descriptionDescripción de la operación a realizarse.

Entity: UserInfo

PropiedadDescripción
iduserinfoAutogenerado
usernameLlave primaria del usuario
datetimeFecha y hora
descriptionDescripción de la operación a realizar

Entity: RevisionHistory.java

Descripción: Almacena la información correspondiente al documento que se elimina o actualiza.
PropiedadDescripción
idrevisionhistoryValor que se genera automáticamente
documentNombre del documento que se esta realizando la operación
idLLave primaria del documento al que se realiza la operación
descriptionDefine la operación realizada
contentAlmacena el contenido completo del documento sobre el que se realizo la operación.

Services

JMoordb ofrece Services para ser utilizados como parte de la implementación de auditoria.



Nos permitirá registrar los accesos de usuarios entre otras operaciones
 accessInfoFacade.save(accessInfoServices.generateAccessInfo(username, "login", "acceso denegado"));


Registrar las operaciones realizadas sobre los documentos 
agente.setUserInfo(userInfoServices.generateListUserinfo(loginController.getUsername(), "create"));

 


Historial de revisión

revisionHistoryFacade.save(revisionHistoryServices.getRevisionHistory(agente.getCedula(), loginController.getUsername(),
"delete", "agente", agenteFacade.toDocument(agente).toString()));




AVBravo - October 19, 2017 09:22 PM
List<> Embedidas en MongoDB con JMoordb

Las listas embebidas en los documentos en MongoDB nos permiten almacenar muchas estructuras que nos serán útil en variadas condiciones.
Usaremos JMoordb que esta disponible en los repositorios.

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
 <dependency>
<groupId>com.github.User</groupId>
<artifactId>Repo</artifactId>
<version>Tag</version>
</dependency>




En este ejemplo básico asumimos que deseamos guardar un registro de la fecha hora  y descripción de las operaciones que realiza un usuario sobre un documento.


Definimos los entity

@Getter
@Setter
public class Userinfo {
    @Id
    private String username;
    private Date datetime;
    private String description;

    public Userinfo() {
    }

    public Userinfo(String username, Date datetime, String description) {
        this.username = username;
        this.datetime = datetime;
        this.description = description;
    }

}


El entity bodega contiene un List<> embebido de Userinfo

@Getter
@Setter
public class Bodega {

    @Id
    private String idbodega;
    private String telefono;
    private String direccion;

    @Embedded
    private List<Userinfo> userinfo;
    public Bodega() {
    }
  }


Crear un EJB llamado UserinfoServices
@Stateless
public class UserinfoServices {

    public List<Userinfo> generateListUserinfo(String username, String description) {
        List<Userinfo> listUserinfo = new ArrayList<>();
        try {

            listUserinfo.add(new Userinfo(username, JsfUtil.getFechaHoraActual(), description));
        } catch (Exception e) {
            JsfUtil.errorMessage("generateUserinfo() " + e.getLocalizedMessage());
        }
        return listUserinfo;
    }
}



Desarrollamos una aplicación Java Server Faces


En el controller metodo save()
@Inject
UserinfoServices userinfoServices;
public String save() {
        try {
            //Lo datos del usuario

 bodega.setUserinfo(userinfoServices.generateListUserinfo(loginController.getUsername(), "create"));
              bodegaFacade.save(bodega);
               
        } catch (Exception e) {
            JsfUtil.errorMessage("save()" + e.getLocalizedMessage());
        }
        return "";
    }

Método editar agregamos a la lista el nuevo objeto de tipo Userinfo
public String edit() {
        try {
         bodega.getUserinfo().add(userinfoServices.generateUserinfo(loginController.getUsername(),"editado"));
            bodegaFacade.update(bodega);
            JsfUtil.successMessage(rf.getAppMessage("info.update"));
        } catch (Exception e) {
            JsfUtil.errorMessage("edit()" + e.getLocalizedMessage());
        }
        return "";
    }// </editor-fold>


Si consultamos el documento en MongoDB


si observamos userinfo tiene 3 elementos, indican las operaciones sobre el documento.

se muestran los registros de las operaciones realizadas sobre el documento.








AVBravo - October 17, 2017 01:46 AM
Duke's Choces Awards 2017 JEspañol

Hace unos años se creo una iniciativa para unir JUGLeaders y Java Champions de Latinoamerica con la finalidad de promover los avances en la plataforma Java en el idioma español.
Esta iniciativa reunió miembros de México, Guatemala, Panamá, Colombia, Peru, a esta comunidad recién creada le llamamos JEspañol. http://www.jespanol.org

      





En colaboración y el apoyo de los grandes amigos de Certificatic de Mexico, se realizo una semana virtual de JEspañol y luego varios de los miembros visitaron Mexico para conferencias presenciales.



Este año en el Java One 2017 se anunciaron los ganadores del Duke's Choices Awards.

Announcing 2017 Duke's Choice Award Nominations
https://blogs.oracle.com/java/announcing-2017-dukes-choice-award-nominations

JEspanol como grupo fuimos seleccionados como uno de los 9 ganadores de los Duke's Choices Awards 2017, varios miembros participaron como conferencistas en el Java One y recibieron el premio en nombre del grupo.


Foto de parte de los miembros recibiendo la estatuilla





Esta imagen creada por Jose Diaz, resume al grupo




AVBravo - October 10, 2017 07:05 PM
Usando APi Reflection para invocar métodos set

Hay muchas formas de usar Reflection en Java, en esta ocasión un ejemplo sencillo implementado en un proyecto Web, que utiliza Java Server Faces.
Tenemos un entity  llamado Reservadoagente que definimos con JMoordb





Deseamos asignar el valor de 3 a los atributos turnodia2 hasta turnodia3, para mostrar en un datatable como se muestra en el ejemplo:




            Class[] paramInt = new Class[1];
            paramInt[0] = Integer.TYPE;

            for (Agente a : agenteList) {

                   Reservadoagente reservadoagente = new Reservadoagente();
                   reservadoagente.setAgente(a);
                   Class cls = reservadoagente.getClass();
                   Object obj = reservadoagente;

                   for (int dia = 1; dia <= numeroDiasMes; dia++) {
                             Field field = cls.getDeclaredField("turnodia" + dia);
                             Method setter = cls.getMethod("setTurnodia" + dia, field.getType());
                             setter.setAccessible(true);
                             setter.invoke(obj, 3);
                   }
                  reservadoagenteList.add(reservadoagente);
        }





AVBravo - August 11, 2017 01:21 AM
Contador mediante Reflexión

Algunas ocasiones tenemos que contar una cantidad valores en los atributos, generalmente tendríamos que hacerlo propiedad por propiedad.
Contamos con un Entity


 necesitaríamos implementar un código donde veríamos múltiples condiciones y tenemos que usar cada atributo mediante el método get, en este ejemplo serian 31 campos. Imaginemos el escenario que sea una cantidad mayor, tendríamos un segmento de código mas o menos como el que mostramos aquí.

 for (Agente a : agenteList) {
                t1 = 0;
                t2 = 0;
                t3 = 0;
                t4 = 0;
for (Reservadoagente r : reservadoagenteList) {
if(r.getTurno1() == 1 || r.getTurno2() == 1 || r.getTurno3() == 1 || r.getTurno4() ==1 ,,, r.getTurno31()==1 ){
t1++;
}
else{
    if(r.getTurno1() == 2 || r.getTurno2() == 2 || r.getTurno3() == 2 || r.getTurno4() ==2 ,,,      
        r.getTurno31()==2 ){
        t2++;

   }
else{
    if(r.getTurno1() == 3 || r.getTurno2() == 3 || r.getTurno3() == 3 || r.getTurno4() ==3 ,,,      
        r.getTurno31()==3){
        t3++;

   }else{
 if(r.getTurno1() == 4 || r.getTurno2() == 4 || r.getTurno3() == 4 || r.getTurno4() ==4 ,,,      
        r.getTurno31()==4){
        t2++;

   }
 }

}
...


Para evitar todo esto podemos usar el API reflexión.
Simplemente invocamos los métodos get de los atributos Turnodia, y comparamos el resultado para determinar si es un 1, 2, 3, 4. Y con esto tendremos un contador de cada valor,.
        Class noparams[] = {};
                for (Reservadoagente r : reservadoagenteList) {

                        Class cls = r.getClass();
                        Object obj = r;
                        for (Method method : Reservadoagente.class.getDeclaredMethods()) {
                            if (method.getName().contains("getTurnodia")) {
                                String name = method.getName();
                                Method methodrun = cls.getDeclaredMethod(name, noparams);
                                Object result = methodrun.invoke(obj, null);
                                switch (Integer.parseInt(result.toString().trim())) {
                                    case 0:
                                        break;
                                    case 1:
                                        t1++;
                                        break;
                                    case 2:
                                        t2++;
                                        break;
                                    case 3:
                                        t3++;
                                        break;
                                    case 4:
                                        t4++;
                                        break;
                                    default:

                                }
                            }
                        }
                    }
                }


Tendríamos una representación gráfica de la siguiente manera.


AVBravo - June 27, 2017 09:05 PM
Api para seguridad mediante HttpSession

Este api simplifica el manejo de HttpSession en aplicaciones Java EE, para ayudar al desarrollador a implementar el control de las sesiones de los usuarios.
Validar login

Controlar si existe ese usuario logeado en otra sesión.



Anular las sesiones enviar token al email del usuario



Administrar las sesiones


 Manual (Online/pdf)
https://www.gitbook.com/book/avbravo/avbravosecurity/details

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Agregar la dependencias

 <dependency>
<groupId>com.github.avbravo</groupId>
<artifactId>avbravosecurity</artifactId>
<version>0.1</version>
</dependency>



 <dependency>
<groupId>com.github.avbravo</groupId>
<artifactId>avbravoutils</artifactId>
<version>0.11</version>
</dependency>

Para su uso simplemente implementamos SecurityInterface en el controller.
@Named
@SessionScoped
public class LoginController implements Serializable, SecurityInterface {


La clase BrowserSession gestiona le información de la sesión del usuario su id, tiempo de inicio, ip, browser, asigna un token automático, almacena el objeto HttpSession que permite terminar una sesión mediante métodos de la interface, y controla la cantidad de segundos para la inactividad.


  • Para verificar si hay un usuario logueado en la sesión actual

         usernameRecover = usernameRecoveryOfSession();


  • Para guardar el nombre del usuario que se logea y especificar en segundos el tiempo de inactividad  
      saveUserInSession(username, 300);


  • Para salir de la sesión
    logout("/seguridad/faces/index.xhtml?faces-redirect=true");


  • Destruir la sesión por el username
     destroyByUsername(username);

  • Obtener el token por el username
        tokenOfUsername(username)

  • Para destruir la sesión por el username y token
        destroyByToken(username, mytoken);




  • Invalidar my sesion
      invalidateMySession()



  • Obtener todas las sesiones
         List<BrowserSession> browserSessionsList  = allBrowserSessionList();


  • Eliminar todas las sesiones
        cancelAllSesion()


  • Inactivar por un browserSession
         inactiveSession(browserSesssion)


  • Obtener la fecha de expiración de un HttpSession
        getDateTiemExpiration(session)

  • Segundos para inactividad
        JsfUtil.milisegundosToTiempoString(milisegundosForInactivate(session))

  • Tiempo de creación(Date)
new Date(session.getCreationTime())


  • Tiempo de conexión (String formateado)
JsfUtil.milisegundosToTiempoString(miliSecondsOfConnection(session));

  • Ultima conexion
              new Date(session.getLastAccessedTime())

AVBravo - May 06, 2017 03:08 AM
JMoordb MongoDBRepository

Andrea Covino parte del equipo de JMoordb, trabajando en la implementación de MongoRepository, (desarrollo interno, estos cambios no estan en el repositorio oficial),   esto permite que solo definamos un entity y mediante el uso de MongoRepository desde un controller tengamos las funcionalidades que ofrece el Facade(experimental).

Observe que se dispone de una nueva anotación @DocumentInfo que permite indicar el nombre de la colección.

El modelo anterior {Entity+Facade+Controller}
Nuevo modelo {Entity +Controller{MongoRepository}}



@Getter
@Setter
@DocumentInfo(name = "planeta")
public class Planeta {
    @Id
    private String idPlaneta;
 
    private String planeta;
 
    private Date fecha;
 
    public Planeta(){ }
 
    public Planeta(String idPlaneta, String planeta, Date fecha){
        this.idPlaneta = idPlaneta;
        this.planeta = planeta;
        this.fecha = fecha;
    }

    @Override
    public String toString(){
        return "Palnetas{ idplaneta=" + idPlaneta + ", planeta=" + planeta + ", fecha=" + fecha +"}";
    }
         

}
Facade: No es necesario implementar un Facade.


Podemos observar un simple test.



     
       Planeta expectedPlaneta = new Planeta(randomId, randomId+"Plutón", new Date());
     

        MongoRepository<Planeta> planetaRepo = new MongoRepository<>(Planeta.class);
         
        planetaRepo.save(expectedPlaneta):


Nota: Es código en fases de desarrollo interno, aun no esta implementado de manera oficial,
         
       

AVBravo - May 03, 2017 01:05 AM
Jmoordb en Certificatic- Semana JEspañol

Hace aproximadamente 2 años se creo la comunidad JEspañol, http://www.jespanol.org/, con la iniciativa de Alexis Lopez(Colombia) , Cesar Hernandez(Guatemala), Jose Diaz(Perú), Diego Silva(Perú), Jorge Vargas(México) , Aristides Villarreal Bravo(Panamá), Victor Orozco(Guatemala).
La finalidad era reunir los lideres de grupos de usuarios Java de Latinomerica, con el objetivo de promover el lenguaje de programación Java.
Nuestro lema:
Un lenguaje, un idioma, Java en español.

Somos una comunidad que busca aumentar la difusión y adopción de la tecnología Java en idioma español. Para lograrlo, fomentamos la colaboración e interacción entre los grupos de usuarios Java de habla hispana, generando documentación, laboratorios y eventos en los países participantes.




Nuestros amigos de CertificaTic, (https://www.certificatic.org/) organizaron la semana de JEspañol con el lema 1 era Reunión Virtual JEspañol.




Agenda de temas










En esta oportunidad  presente:
JMoordb un API Java para NoSQL


Video en Facebook
https://www.facebook.com/CertificaTIC/videos/1744733459100643/



Libro gratis sobre JMoordb

Modelo




AVBravo - April 01, 2017 01:05 AM
The Definitive Guide to DateTime Manipulation

The Definitive Guide to DateTime Manipulation

Interesante publicación de nuestros amigos de Toptal, donde muestran una guía para manipular fechas con JavaScript.
El uso de fechas es muy común en todas las aplicaciones que desarrollemos, aqui se muestra una guía muy interesante.


var today = new Date().toLocaleDateString('en-GB', {  
day : 'numeric',
month : 'short',
year : 'numeric'
})


AVBravo - March 29, 2017 12:16 AM
Java Server Faces 2.3

Java Server Faces 2.3

Ya esta disponible JSF 2.3

Algunos enlaces

Repositorios Maven

What's new in JSF 2.3?

http://arjan-tijms.omnifaces.org/p/jsf-23.html





AVBravo - March 26, 2017 08:21 PM
AutoComplete findRegex() Expresiones Regulares ejbjmoordb

AutoComplete findRegex() Expresiones Regulares 
Desarrollaremos un ejemplo sencillo de una autocomplete utilzando expresiones regulares para busquedas en una coleccion en MongoDB, utilizando ejbmoordb.
Libro sobre jmoordb
https://www.gitbook.com/book/avbravo/jmoordb/details


Crear el Services

exit: Ctrl + ↩

@Stateless


public class AulasServices {


@Inject


AulasFacade aulasFacade;


public static LocalTime getHour(){


return LocalTime.now();


}


public List<Aulas> complete(String query) {


List<Aulas> suggestions = new ArrayList<>();


try {


query = query.trim();


if (query.length() < 1) {


return suggestions;


}


suggestions = aulasFacade.findRegex("idaula", query,true,new Document("idaula",1));




} catch (Exception e) {


JsfUtil.addErrorMessage("complete() " + e.getLocalizedMessage());


}


return suggestions;


}


}











En el Controller





exit: Ctrl + ↩


@Inject


AulasServices aulasServices;


Aulas aulasSelected;




public AulasServices getAulasServices() {


return aulasServices;


}


public void setAulasServices(AulasServices aulasServices) {


this.aulasServices = aulasServices;


}


public Aulas getAulasSelected() {


return aulasSelected;


}


public void setAulasSelected(Aulas aulasSelected) {


this.aulasSelected = aulasSelected;


}


@Override


public void handleSelect(SelectEvent event) {


try {


aulasList.removeAll(aulasList);


aulasList.add(aulasSelected);


aulasFiltered = aulasList;


aulasDataModel = new AulasDataModel(aulasList);


} catch (Exception ex) {


JsfUtil.addErrorMessage("handleSelect() " + ex.getLocalizedMessage());


}


}





En la página xhtml



<div class="form-group row">


<p:outputLabel class="col-xs-2 col-form-label" value="#{msg['info.by']} #{msg.idaula}"/>


<div class="col-xs-4">


<p:autoComplete scrollHeight="250" dropdown="false" size="45" emptyMessage="#{msg['info.nohayregistros']}"


title="#{msg['info.by']} #{msg.idaula}"


label="#{msg['info.by']} #{msg.idaula}"


alt="#{msg['info.searchby']} #{msg.idaula}"


value="#{aulasController.aulasSelected}"


completeMethod="#{aulasController.aulasServices.complete}"


var="p" itemLabel="#{p.idaula}" itemValue="#{p}" forceSelection="true">


<f:converter binding="#{aulasConverter}"/>


<p:ajax event="itemSelect" listener="#{aulasController.handleSelect}" update=" :form:msgs,:form:dataTable" />


<f:facet name="itemtip">


<h:panelGrid columns="1" cellpadding="5">


<h:outputText value="#{p.idaula}" />


<h:outputText value="#{p.maximo}" />


</h:panelGrid>


</f:facet>


</p:autoComplete>


</div>





Resultado









AVBravo - March 25, 2017 08:03 PM
jmoordb version 0.2/ findText()

Ya esta disponible la versión 0.2 de jmoordb y ejbmoordb. Se incluye el soporte para busquedas por texto y expresiones regulares que se utilizan en MongoDB.


Búsquedas por Texto findText

Base de datos
MongoDB
Sintaxis:
public List<T> findText(String key, String value,Boolean caseSensitive,Boolean diacriticSensitive, Document... docSort)
AtributoDescripción
caseSensitivetrue :Habilita la búsqueda sensitiva (mayúscula y minúscula) false: Deshabilita la búsqueda sensitiva
diacriticSensitiveHabilita o deshabilita la búsqueda diacritico.

El índice de texto de la versión 3 es diacrítico insensible. Es decir, el índice no distingue entre caracteres que contienen marcas diacríticas y su contraparte no marcada, como é, ê y e.


Las búsquedas por texto en MongoDB se basan en la descripción: Búsquedas por Texto MongoDB
En nuestro caso son útiles por ejemplo en una aplicación Java EE para usar autocomplete o búsquedas por un texto.
https://docs.mongodb.com/manual/reference/operator/query/text/
Se define un indice de texto
db.planetas.createIndex( { idplaneta: "text" } )
Se pueden ejecutar consultas
db.planetas.find( { $text: { $search: "tier" } } )

Usando JMoordb

Crear el indice


if(paisesFacade.createIndex(new Document("idpais","text"))){


System.out.println("creo el indice");


}else{


System.out.println("no creo el indice");


}

Ejemplo Realizar la consulta

Buscar los documentos que el atributo idplaneta tenga una letra a

String query ="a";


List<Planetas> suggestions = planetasFacade.findText("idplaneta", query,true,true, new Document("idplaneta",1));










AVBravo - March 25, 2017 08:02 PM
jmoordb version 0.2

Para utilizar jmoordb/ejbmoordb
Maven:

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
     <groupId>com.github.avbravo</groupId>
<artifactId>jmoordb</artifactId>
<version>0.2</version>
</dependency>
<dependency>
     <groupId>com.github.avbravo</groupId>
<artifactId>ejbjmoordb</artifactId>
<version>0.2</version>
</dependency>

AVBravo - March 25, 2017 08:01 PM
jmoordb 0.2 /findRegex()

La versión 0.2 de jmoordb/ejbmoordb soporta las busquedas mediante expresiones regulares, lo que permite que se ejecuten consultas en MongoDB similiar a una consulta Like en una base de datos relacional
B

úsquedas Expresiones Regulares (Regex)
Se utilizan para consultas mediante patrones. Funcionan de manera similar a las sentencias like en el modelo relacional en donde generalmente usamos el comodín "%s" para ampliar las operaciones de búsquedas.
Es una implementación de regex en mongodb
https://docs.mongodb.com/manual/reference/operator/query/regex
Método:
MétodoBases de datos NoSQL
public List< T > findRegex(String key, String value, Document... docSort)MongoDB
Nota: Para bases de datos couchbase puede ser el método find() en el statement puede colocar el filtro.

Ejemplo MongoDB:

Buscar un país que inicie con pan.
List< Paises > list = paisesFacade.findRegex("Pais", "pan");
Buscar un país que inicie con pan y devuelva la lista de entitys ordenados
List< Paises > list = paisesFacade.findRegex("pais","pan",true,new Document("pais",1));

Ejemplo desde consola

Creamos una colección llamada aulas

Mostrar todos

db.aulas.find()
Resultado

{ "_id" : ObjectId("58d099b6bea22215f5f24db7"), "idaula" : "PE-1", "maximo" : 40, "matriculados" : 4, "anio" : 2017 }


{ "_id" : ObjectId("58d099c1bea22215f5f24db8"), "idaula" : "PE-2", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d099cbbea22215f5f24db9"), "idaula" : "PE-3", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d099debea22215f5f24dba"), "idaula" : "PE-4", "maximo" : 40, "matriculados" : 3, "anio" : 2017 }


{ "_id" : ObjectId("58d099e7bea22215f5f24dbb"), "idaula" : "PE-5", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d099f1bea22215f5f24dbc"), "idaula" : "PE-6", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d099febea22215f5f24dbd"), "idaula" : "PD-2", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09a22bea22209d62eeec9"), "idaula" : "PD-3", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09a33bea22209d62eeeca"), "idaula" : "PD-4", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09a39bea22209d62eeecb"), "idaula" : "PD-5", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09a40bea22209d62eeecc"), "idaula" : "PD-6", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09a47bea22209d62eeecd"), "idaula" : "PD-7", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09aadbea22209d62eeece"), "idaula" : "CE-1", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ab9bea22209d62eeecf"), "idaula" : "CE-13", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac1bea22209d62eeed0"), "idaula" : "CE-14", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac8bea22209d62eeed1"), "idaula" : "CE-15", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ad0bea22209d62eeed2"), "idaula" : "CE-16", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }

Buscar los que inician con CE

db.aulas.find( {idaula: { $regex: "CE" }}  )
Resultado

{ "_id" : ObjectId("58d09aadbea22209d62eeece"), "idaula" : "CE-1", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ab9bea22209d62eeecf"), "idaula" : "CE-13", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac1bea22209d62eeed0"), "idaula" : "CE-14", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac8bea22209d62eeed1"), "idaula" : "CE-15", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ad0bea22209d62eeed2"), "idaula" : "CE-16", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }

Buscar CE-13
db.aulas.find( {idaula: { $regex: "CE-13" }}  )
Resultado
{ "_id" : ObjectId("58d09ab9bea22209d62eeecf"), "idaula" : "CE-13", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


Usando / / buscar todos que inicien con CE-

db.aulas.find( {idaula: { $regex: /CE-/ }}  )

Resultado


{ "_id" : ObjectId("58d09aadbea22209d62eeece"), "idaula" : "CE-1", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ab9bea22209d62eeecf"), "idaula" : "CE-13", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac1bea22209d62eeed0"), "idaula" : "CE-14", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ac8bea22209d62eeed1"), "idaula" : "CE-15", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }


{ "_id" : ObjectId("58d09ad0bea22209d62eeed2"), "idaula" : "CE-16", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }



Buscar cE-1 exactamente

db.aulas.find( {idaula: { $regex: /cE-1$/ }}  )

Resultado

Vacio no devuelve nada porque no existe cE-1 existe CE-1

Buscar cE-1 ignorando mayúsculas y minúsculas

 db.aulas.find( {idaula: { $regex: /cE-1$/i }}  )
Resultado
{ "_id" : ObjectId("58d09aadbea22209d62eeece"), "idaula" : "CE-1", "maximo" : 40, "matriculados" : 0, "anio" : 2017 }

Ejemplo de uso
Busca las aulas que tengan los caracteres ce, el parámetro true indica que se pueda buscar sin importar mayúscula o minúsculas.
List<Aulas> list = aulasFacade.findRegex("idaula", "ce",true,new Document("idaula",1));

AVBravo - February 28, 2017 02:40 PM
Entendiendo Promise en JavaScript

JavaScript Promises: A Tutorial with Examples
Balint Erdi de Toptal, muestra un interesante articulo donde explica Promises en Java, script mediante ejemplos muy claros.
https://www.toptal.com/javascript/javascript-promises

promise.then(function(value) {
// Do something with the 'value'
});


Es un buen articulo para entender su implementación.

AVBravo - February 15, 2017 03:34 PM
Bidirectional Relationship Support in JSON

un interesante articulo que nos muestra una solución elegante a este tipo de relaciones dentro de JSON.

AVBravo - February 14, 2017 02:01 AM
Migrar documentos de MongoDB a Couchbase con jmoordb

Migrar documentos de MongoDB a Couchbase con jmoordb

Los pasos son:

  • Definir el Entity
  • Definir el Facade MongoDB
  • Definir el Facade Couchbase
  • Definir el Provider para MongoDB
  • Definir el Provider para Couchbase




Definimos el Entity
@Getter
@Setter
public class Planetas {

    @Id
    private String idplaneta;
    private String planeta;
    @Ignore
    private Date fecha;

    public Planetas() {
    }

    public Planetas(String idplaneta, String planeta, Date fecha) {
        this.idplaneta = idplaneta;
        this.planeta = planeta;
        this.fecha = fecha;
    }

 

}


Definir el facade MongoDB

public class PlanetasFacade extends AbstractFacade<Planetas> {
 MongoClientProvider mongoclientProvider = new MongoClientProvider();
    public PlanetasFacade() {
        super(Planetas.class, "fantasy", "planetas");
    }

    @Override
    protected MongoClient getMongoClient() {
       return mongoclientProvider.getMongoClient();
    }

   @Override
    public Object findById(String key, String value) {
       return search(key,value);
    }

    @Override
    public Object findById(String key, Integer value) {
        return search(key,value);
    }

}


Definir el Facade Couchbase

public class PlanetasFacade extends CouchbaseAbstractFacade<Planetas> {
 CouchbaseClientProvider couchbseclientProvider = new  CouchbaseClientProvider();
    public PlanetasFacade() {
        super(Planetas.class, "planetas", "planetas");
    }

    @Override
    protected Cluster getCluster() {
    return  couchbseclientProvider.getCluster();
    }

     @Override
    public Object findById(String key, String value) {
        return search(key, value);
    }

    @Override
    public Object findById(String key, Integer value) {
        return search(key, value);
    }


}


Definir la clase MongoClientProvider

public class MongoClientProvider {

    private MongoClient mongoClient = null;

    public MongoClient getMongoClient() {
        mongoClient = new MongoClient();
        try {
       
        } catch (Exception e) {
            System.out.println("getMongoClient() " + e.getLocalizedMessage());
        }
        return mongoClient;
    }

}

Definir la clase CouchbaseClientProvider

public class CouchbaseClientProvider {
private Cluster cluster;


    public Cluster getCluster() {
           CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
                    .connectTimeout(10000) //10000ms = 10s, default is 5s
                    .build();
            cluster = CouchbaseCluster.create("localhost");
        return cluster;
    }


}


Código para ejecutar la migración


  com.migrador.couchbase.ejb.PlanetasFacade planetascouchbaseFacade = new PlanetasFacade() ;
            com.migrador.mongodb.ejb.PlanetasFacade planetasmongodbFacade = new com.migrador.mongodb.ejb.PlanetasFacade() ;
            
            List<Planetas> list = planetasmongodbFacade.findAll();
            if(!list.isEmpty()){
                list.forEach((p) -> {
                    planetascouchbaseFacade.save(p,false);
                });
            }

Base de datos en MongoDB



Couchbase después de la migración:






AVBravo - February 04, 2017 04:49 AM
jmoordb 0.1.9.2


jmoordb

Libro:
https://avbravo.gitbooks.io/jmoordb/content/

Jmoordb es un Object Document Mapper para Java que soporta bases de datos NoSQL (MongoDB ,OrientDB,Couchbase).

Es un Framework orientado a desarrolladores Java, ya que pueden interactuar con bases de datos NoSQL desde su código Java, para los expertos en NoSQL permite interactuar desde Java con la sintaxis de NoSQL de la base de datos que utiliza, para los expertos que vienen del mundo relacional permite ejecutar instrucciones SQL que son convertidas a instrucciones NoSQL.


  • Ofrece una sintaxis similar a JPA
  • Permite el uso de Objetos java para operaciones CRUD
  • Permite el uso de Document para operaciones con las colecciones de documentos
  • Ofrece un soporte para SQL
  • Soporta Java 8
  • Soporta Anotaciones
  • Soporta Beans Validation (JSR 349)
  • Soporta documentos embebidos
  • Soporta documentos referenciados
  • Definición sencilla de Entitys
  • Métodos para operaciones de creación, eliminación, actualización , búsquedas avanzadas.

Esta basado en: Driver Java para MongoDB, Couchbase, OrientDB
Forma de uso muy sencillo:
Definir un Entity:
@Getter
@Setter
public class Planetas {
  @Id
  private String idplaneta;
  private String planeta;
  @Ignore
  private Date fecha;
  public Planetas() {
  }
}
En el controller invocar los métodos del facade:

planetasFacade.save(planetas);
Con esto generados el documento que es almacenado en la base de datos NoSQL
Planetas{ "_id" : ObjectId("587cf876a6cca92842bf2ea9"),
"idplaneta" : "tr",
"planeta" : "Tierra"
}

AVBravo - February 01, 2017 12:57 AM
Dos interesantes Articulos sobre Java Script

En Toptal podemos encontrar dos excelentes artículos:
Gulp: A Web Developer's Secret Weapon for Maximizing Site Speed
En donde se muestra el proceso de automatización y optimización con Gulp.js

Este otro articulo

Immutability in JavaScript using Redux

Muestra el proceso de crear Actions, usar inmutables librerías.
Ambos son excelentes articulos para analizar.



AVBravo - January 25, 2017 01:09 AM
Why You Need to Upgrade to Java 8 Already

Why You Need to Upgrade to Java 8 Already, enlace https://www.toptal.com/java/why-you-need-to-upgrade-to-java-8-already

Los amigos de Toptal han publicado un interesante articulo sobre Java 8,  se tratan temas interesantes:


  • Lambda expressions.
  • Stream API for working with Collections.
  • Asynchronous task chaining with CompletableFuture.
  • Brand new Time API.

Ejemplo de implementación de  funciones 

(Integer i1, Integer i2) -> i1 % 2 - i2 % 

Descripción de métodos referenciados, Stream APi

books.stream()
.filter(book -> book.year > 2005) // filter out books published in or before 2005
.map(Book::getAuthor) // get the list of authors for the remaining books
.filter(Objects::nonNull) // remove null authors from the list
.map(Author::getName) // get the list of names for the remaining authors
.forEach(System.out::println); // print the value of each remaining element



Sin duda un excelente articulo de referencia que muestra las principales características de Java8.




AVBravo - January 13, 2017 07:27 PM
Definir un Entity Simple en JGMongo

Definir un Entity Simple en JGMongo

Un Entity representa el documento en MongoDB, por lo que debemos describir su estructura en Java.
Reglas

  •  La clase debe extender de GenericsBeans
  •  Implementar @Getter /@Setter
  •  El atributo  @SerializedName("") es opcional, lo usamos cuando los nombres de campo (key) en el documento son diferentes a los nombres de propiedades
  • @Id idenficar el PrimaryKey
  •  Crear método toDocument() para convertir de Java o Document
  •  Crear método toPojo()

Contamos con un documento llamado Pais:
{
  "_id" : ObjectId("57bc789da6cca9237822eafb"),
  "Siglas" : "1",
  "Pais" : "Name1",
  "Logo" : "--"
}
Representación visual:

Si observa el nombre de campos (key) inician con la primera letra en mayúsculas,  y nuestros Entity deben iniciar con la primera letra en minúsculas.
MongoDB("Siglas"
Java(siglas)
Por lo tanto debemos indicar cual es el nombre del campo en el documento en este caso usamos la anotación : @SerializedName( colocar el nombre del documento), si este campo inicia en minúsculas o es el mismo que el atributo en nuestra clase en java no es necesario especificarlo.
     @SerializedName("Siglas")
       private String siglas;

Llave Primaria @Id
Si es el campo que usamos como llave primaria agregamos la anotación @Id.

Crear el método toDocument() que devolverá un Documento en base al objeto Java.

 public Document toDocument(Paises paises) {
       return toDoc(paises);
 }


Crear el método toPojo que recibe un Documento y lo convierte a objeto Java

public Paises toPojo(Document doc) {
        return (Paises) toJava(doc, new Paises().getClass());
    }


Ejemplo 1: 
Nombres de campo en MongoDB diferentes a nombres de atributos de clases en Java.

import com.google.gson.annotations.SerializedName;
import com.jgmongo.anotaciones.Id;
import com.jgmongo.services.GenericBeans;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Paises extends GenericBeans {

    @Id
    @SerializedName("Siglas")
    private String siglas;
    @SerializedName("Pais")
    private String pais;
    @SerializedName("Logo")
    private String logo;

    public Document toDocument(Paises paises) {
          return toDoc(paises);
    }

    public Paises toPojo(Document doc) {
       return (Paises) toJava(doc, new Paises().getClass());
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    }
}


Ejemplo 2: 
Nombres de campo en MongoDB iguales a nombres de atributos de clases en Java. No es necesario utilizar la anotación  @SerializedName("")
Paises:
{
  "_id" : ObjectId("57bc789da6cca9237822eafe"),
  "siglas" : "2",
  "pais" : "Name2",
  "logo" : "--"

}

Representación visual

import com.google.gson.annotations.SerializedName;
import com.jgmongo.anotaciones.Id;
import com.jgmongo.services.GenericBeans;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Paises extends GenericBeans {

    @Id
    private String siglas;
    private String pais;
    private String logo;

    public Document toDocument(Paises paises) {
        return toDoc(paises);
    }

    public Paises toPojo(Document doc) {
          return (Paises) toJava(doc, new Paises().getClass());
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    }
}




AVBravo - January 10, 2017 01:51 AM
Hunting Memory Leaks in Java

Hunting Memory Leaks in Java

Un excelente articulo publicado en Toptal.com


donde se realiza un análisis profundo y incluye ejemplo del uso de  Java VisualVM

AVBravo - January 06, 2017 05:06 PM
Buggy Java Code: The Top 10 Most Common Mistakes That Java Developers Make

Buggy Java Code: The Top 10 Most Common Mistakes That Java Developers Make

es interesante articulo donde se muestran 10 de los errores más comunes al programa en Java.

Toptal hace evaluaciones interesantes sobre diversas tecnologías y en esta ocasión sobre Java.
Este es el listado:

#1: Neglecting Existing Libraries
#2: Missing the ‘break’ Keyword in a Switch-Case Block
#3: Forgetting to Free Resources

 #4: Memory Leaks

#5: Excessive Garbage Allocation
#6: Using Null References without Need

#7: Ignoring Exceptions

#8: Concurrent Modification Exception

#9: Breaking Contracts

 #10: Using Raw Type Instead of a Parameterized One

AVBravo - January 05, 2017 06:43 PM
Autoincrementable en MongoDB con findOneAndUpdate() JGMongo

Existen muchas maneras de administrar campos autoincrementables, en esta ocasión mostrare la implementación que use en JGMongo https://github.com/avbravo/jgmongo/ utilizando en metodo findOneAndUpdate().

Implementaremos el método de la clase AbstractFacade

 public T findOneAndUpdate(String key, String value,String field,Integer... incremento) 

Key : es el campo a buscar
value: el valor de ese campo
field: es el campo numérico a implementar
incremento: Opcional si no se pasa ningún valor incrementa en uno el campo
Problema 1:

Existe una colección de documentos donde se maneja un campo entero que funcionara como autoincrementable:  
Agenda{"Id":1,"evento":"A"},{"Id":2,"evento":"B"},{"Id":3,"evento":"C"}
  • Si se elimina el evento 3, 

Agenda{"Id":1,"evento":"A"},{"Id":2,"evento":"B"}
  • Cuando se desee insertar un documento  con el {"evento":"D"}, se pueden producir algunas situaciones

1. Utilizar la función count() para conocer la cantidad de documentos que tiene la colección, este devolverá 2 y al sumarle 1 tendrá el valor de 3, que ya fue usado para el {"evento":"C"}. 
Al insertarlo quedaría de la siguiente manera:
Agenda{"Id":1,"evento":"A"},{"Id":2,"evento":"B"},{"Id":3,"evento":"D"}

2. Si buscamos el ultimo documento de la colección {"Id":2,"evento":"B"} , el valor del id es 2 al sumarle 1 quedara en 3, por lo tanto al insertar el evento {"evento":"D"} a la colección este tendria el valor de 3 para el id y este ya fue usado en el {"evento" :"C"}.
Al insertarlo quedaría de la siguiente manera:
Agenda{"Id":1,"evento":"A"},{"Id":2,"evento":"B"},{"Id":3,"evento":"D"}


Utilizando findOneAndUpdate()

1- Crear una colección para que lleve el contador de los documentos y sus id que se usan en otras colecciones. Autoincrementable{"Documento":"Agenda","Valor":1}
De esta manera en la colección Agenda utilizara el valor que devuelva el campo valor de la colección Autoincrementable.
El metodo findOneAndUpdate() busca el documento que cumpla la condición y realiza el incremento automático y devuelve el documento actualizado.
  • findOneAndUpdate("Documento", "Agenda", "Valor"); // incrementa en 1 el campo Valor
  • findOneAndUpdate("Documento", "Agenda", "Valor",8); // incrementa en 8 el campo Valor, le podemos indicar el valor que deseamos de incremento

Al insertarlo quedaría de la siguiente manera:
Incrementa el campo valor y devuelve el documento actualizado
 Autoincrementable{"Documento":"Agenda","Valor":4}
y este se asigna al id de la colección Agenda
Agenda{"Id":1,"evento":"A"},{"Id":2,"evento":"B"},{"Id":4,"evento":"D"}

Código en Java
 Autoincrementable autoincrementable = new Autoincrementable();
      autoincrementable=autoincrementableFacade.findOneAndUpdate("Documento", "Agenda", "Valor");
                agenda.setIdagenda(autoincrementable.getValor());
                




AVBravo - January 04, 2017 04:44 PM
Arrays en documentos con Mongodb con JGMongo

Arrays en documentos con Mongodb con JGMongo
Un documento en MongoDB, es una estructura compuesta por pares (key, value).

En esta ocasión mostrare como manejar Arrays de documentos mediante jgmongo  https://github.com/avbravo/jgmongo  Un framework que estoy desarrollando para MongoDB




Documentos de Paises y Sedes.


Tenemos dos colecciones: paises con información como esta:
@Getter
@Setter
public class Paises extends GenericBeans {
@Id
    @SerializedName("Siglas")
    private String siglas;
    @SerializedName("Pais")
    private String pais;
    @SerializedName("Logo")
    private String logo;



y el documento sedes:
@Getter
@Setter

public class Sedes extends GenericBeans {
@Id
    @SerializedName("Idsede")
    private String idsede;
    @SerializedName("Sede")
    private String sede;
@SerializedName("Paises")
    private List<Paises> paises;


Para almacenar los datos en la colección desde Java usamos:
Agregamos el repositorio:
<repositories>
     
         <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>com.github.avbravo</groupId>
            <artifactId>jgmongo</artifactId>
            <version>0.9</version>
        </dependency>
    </dependencies>

Creamos los Entity



Paises.java


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.utica.mavenproject1q.entity;


import com.google.gson.annotations.SerializedName;
import com.jgmongo.anotaciones.Id;
import com.jgmongo.services.GenericBeans;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Paises extends GenericBeans {
    @Id
    @SerializedName("Siglas")
    private String siglas;
    @SerializedName("Pais")
    private String pais;
    @SerializedName("Logo")
    private String logo;
 

    public Document toDocument(Paises paises) {
        Document doc = new Document();
        try {                      
            doc = Document.parse(getGson().toJson(paises));
        } catch (Exception e) {
            System.out.println("toDocument() " + e.getLocalizedMessage());
        }
        return doc;
    }

    public Paises toPojo(Document doc) {
        Paises paises = new Paises();
        try {
             paises = (Paises) fromJsontoPojo(doc.toJson(), new Paises().getClass());
        } catch (Exception e) {
            System.out.println("toPojo() " + e.getLocalizedMessage());
        }
        return paises;
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    }

}



Sedes.java


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.utica.mavenproject1q.entity;


import com.google.gson.annotations.SerializedName;
import com.jgmongo.anotaciones.Id;
import com.jgmongo.services.GenericBeans;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Sedes extends GenericBeans {
    @Id
    @SerializedName("Idsede")
    private String idsede;
    @SerializedName("Sede")
    private String sede;
@SerializedName("Paises")
    private List<Paises> paises;

    public Document toDocument(Sedes sedes) {
        Document doc = new Document();
        try {                      
            doc = Document.parse(getGson().toJson(sedes));
        } catch (Exception e) {
            System.out.println("toDocument() " + e.getLocalizedMessage());
        }
        return doc;
    }

    public Sedes toPojo(Document doc) {
        Sedes sedes = new Sedes();
        try {
             sedes = (Sedes) fromJsontoPojo(doc.toJson(), new Sedes().getClass());
        } catch (Exception e) {
            System.out.println("toPojo() " + e.getLocalizedMessage());
        }
        return sedes;
    }

    @Override
    public String toString() {
        return "Sedes{" + "idsede=" + idsede + ", sede=" + sede + '}';
    }


}


Creamos los Facade

PaisesFacade.java


import com.jgmongo.persistence.AbstractFacade;
import com.mongodb.MongoClient;
import com.utica.mavenproject1q.entity.Paises;

/**
 *
 * @author avbravo
 */
public class PaisesFacade extends AbstractFacade<Paises>{

    public PaisesFacade( ){
        super(Paises.class, "fantasy", "paises");
    }

    @Override
    protected MongoClient getMongoClient() {
         MongoClient mongoClient = new MongoClient();
         return mongoClient;
    }

}


SedesFacade.java


import com.jgmongo.persistence.AbstractFacade;
import com.mongodb.MongoClient;
import com.utica.mavenproject1q.entity.Sedes;

/**
 *
 * @author avbravo
 */
public class SedesFacade extends AbstractFacade<Sedes>{

    public SedesFacade( ){
        super(Sedes.class, "fantasy", "sedes");
    }

    @Override
    protected MongoClient getMongoClient() {
         MongoClient mongoClient = new MongoClient();
         return mongoClient;
    }

}



Programa Principal

  public static void main(String[] args) {
        // TODO code application logic here
        try {

            PaisesFacade paisesFacade = new PaisesFacade();
            SedesFacade sedesFacade = new SedesFacade();
            List<Paises> list = new ArrayList<>();
            list = paisesFacade.findAll();
            if (!list.isEmpty()) {
                Sedes sedes = new Sedes();
                sedes.setIdsede("s-1");
                sedes.setSede("Sede 1");
                sedes.setPaises(list);
                sedesFacade.save(sedes);
            }

       
        } catch (Exception e) {
            System.out.println("error " + e.getLocalizedMessage());
        }

    }

Resultado



Proyecto de ejemplo que implementa la funcionalidad
https://github.com/avbravo/jgmongodesktopexample






AVBravo - November 10, 2016 08:27 PM
Aroug San Luis- Inicio del ODT 2016

Cuando mi amigo Marcelo Burgos me invito a participar del Oracle Development Tour en San Luis, y ser parte del inicio del Tour que recorrerá varios países (Argentina, Brasil,Mexico, Guatemala, Colombia , Costa Rica y Panamá),  pensé en el tema que podría ser mi conferencia y al conversar con Marcelo y Jose Preda, que por más de un mes habian estado pendiente y coordinando todos los detalles para mi asistencia al evento.
Mi tema fue sobre JGMongo (Un framework Java que desarrolle para MongoDB) con JEE8
https://github.com/avbravo/jgmongo


En especial mi agradecimiento al Ing. Ruben Espitia, que hizo todos los tramites y gestiones incluso en ocasiones que el estaba fuera del país por Universidad Tecnológica.


El evento organizado por

ArOUG Regional San Luis

http://arougsanluis.blogspot.com.ar/
Un evento de muy alta calidad, una organización impecable, un ambiente muy agradable, el trato y la cordialidad de los amigos de ArOUG, fueron de primer nivel.
La sede fue la Universidad de La Punta en San Luis, donde las instalaciones fueron excelentes.


La reunion con los participantes y demás expositores fue de mucha cordialidad y sencillez, caracterizando un evento muy bien planificado, este es el listado de los oradores que participamos del  ODT en San Luis.

La agenda del evento http://arougsanluis.blogspot.com.ar/p/odt-2016-agenda.html





Algo de mi participación, hablando un poco sobre JGMongo con Java EE8, utilizando NetBeans como IDE de referencia.


Una foto final del grupo que participo en el ODT-San Luis




En conclusiones un evento de primer nivel, que ha demostrado una estrategia organizativa excelente, y cuando organicen ArOUG un evento sin lugar a dudas sera muy exitoso, mis agradecimientos a Marcerlo, Jose, miembros de ArOUG y amigos que participamos de esta actividad.



AVBravo - September 27, 2016 09:06 PM
JGMongo con JEE7

JGMongo con JEE7

Una aplicación usando JGMongo con JEE7


AVBravo - September 13, 2016 01:40 PM
Apache NetBeans

Apache NetBeans
https://wiki.apache.org/incubator/NetBeansProposal

Si, algo que se esperaba desde hace muchos años, una liberación de NetBeans, para convertirlo en un IDE más abierto, y que permita mayor contribución de la comunidad y de otras empresas, ya inicio su primera etapa en la incubadora de la Fundación Apache.
Las implicaciones que esto conlleva son múltiples por una parte esta la evolución de NetBeans, al permitir que más contribuyentes puedan aportar a sus mejoras, también garantiza que aquellas instituciones no sientan que es una sola organización la que controla la evolución. A las comunidades les permite sentirse que participan de un proyecto con todas las garantías que ofrece la Fundación Apache.

Muchos pensaran que Oracle esta dejando morir el proyecto, la realidad es diferente, hay muchos ingenieros que están participando del proyecto en la fundación Apache.
Es una noticia excelente para los desarrolladores, instituciones, empresas que utilizan NetBeans , se estima que es utilizado por 1.5 millones de personas mensualmente, y se han creado excelentes herramientas y aplicaciones.
Entre algunos de los ejemplos:


Esta liberación de NetBeans es un paso más en la evolución del IDE, y deja de lado los temores que el mismo no seguirá evolucionando.
En las primeras conversaciones que tuve con Bruno Souza después de la compra de Sun Microsystem, por parte de Oracle , Bruno me comentaba la necesidad de liberar NetBeans llevarlo a la comunidad completamente, han pasado varios años, y hoy es una realidad.





AVBravo - August 27, 2016 04:17 PM
JPA Modeler con Angular js

JPA Modeler con Angular js esta disponible.
Mezclar lo mejor de ambos mundos Java+ Angular js muchas veces resulta algo difícil, para los iniciados en ambos mundos.
Gaurav Gupta el creador de JPA Modeler, y su equipo avanzan constantemente en el mejoramiento del mismo y ampliando el soporte a un sin numero de plataformas.
En esta ocasión con la integración para Angular js, puedes encontrar la descripción completa aqui
El uso es muy sencillo:
Requerimientos:

  1. Java 1.8
  2. NetBeans 8.1
  3. JPA Modeler 2.5.1
  4. GlassFish 4.1 / Payara 4.1
Pasos:
1. Crear un proyecto Web con NetBeans IDE

2. Crear un diagrama JPA
Desde File --> New--> Category Persistence
seleccionar JPA Modeler

luego ingrese el nombre del Model

se habilitara el diseñador

Arrastre desde la paleta el componente Entity, allí puede renombrar las propiedades y crear los atributos.


repita el mismo procedimiento y cree las otras entidades y sus relaciones

Luego como se explica en la guía oficial genere los Entity.
Luego genere los servicios del sistema, entre estos los Facade, que funcionan como una capa de abstracción para comunicar los entity con la base de datos mediante el uso de JPA.
Seleccione Rest Controller

luego se configuran los paquetes donde serán creados,  y debemos configurar la aplicación

debemos indicar el Viewer, en este caso es Angular

simplemente dar clic en Generate y se crea toda la estructura del proyecto


Esto es todo lo que necesitamos para crear nuestra aplicación , luego hacemos un deploy y ejecutamos el proyecto. algunas de los formularios generados
Realmente el tiempo de desarrollo es mínimo para lograr una excelente integración, sin duda una herramienta indispensable para los desarrolladores.


AVBravo - August 24, 2016 01:29 AM
JGMongo v0.3

JGMongo v0.3
Esta disponible JGMongo 0.3, entre las características que ofrece, nuevos métodos,  implementación de Filter, creación de Indices

<repository>

<id>jitpack.io</id>

<url>https://jitpack.io</url>

</repository>
 <dependency>

<groupId>com.github.avbravo</groupId>

<artifactId>jgmongo</artifactId>

<version>0.3</version>

</dependency>

Puedes ver todas las características en el Wiki
https://github.com/avbravo/jgmongo/wiki/

AVBravo - August 21, 2016 04:49 AM
JGMongo v0.2

Ya esta disponible la versión 0.2 de JGMongo

<repositories>

<repository>

<id>jitpack.io</id>

<url>https://jitpack.io</url>

</repository>

</repositories>


<dependencies>
<dependency>
<groupId>com.github.avbravo</groupId>
<artifactId>jgmongo</artifactId>
<version>0.2</version>
</dependency>
</dependencies>
Algunas mejoras:
1. Anotación @Id  para definir llave primaria
2. Nuevos métodos para realizar operaciones
3. Mejoras en métodos save, update búsqueda y verificación automática de llave primaria para evitar  duplicidad de documentos.
4. Los métodos toPojo() y to Document() se redefinieron, son más sencillos de usar

@Getter


@Setter


public class Paises extends GenericBeans {

@Id  

@SerializedName("Siglas")

private String siglas;

@SerializedName("Pais")

private String pais;

@SerializedName("Logo")

private String logo;

@SerializedName("Continente")

private Continente continente;


public Document toDocument(Paises paises) {

return toDoc(paises);

}

public Paises toPojo(Document doc) {

return (Paises) toJava(doc, Paises.class);

}

@Override

public String toString() {

return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';

}
}

AVBravo - August 19, 2016 07:07 PM
JGMongo + JEE8 (MongoDB)

Aunque JEE8,  debe estar terminado para el próximo año 2017, hace un tiempo publique un ejemplo usando MySQL como motor de base de datos utilizando JPA Modeler , que es una excelente herramienta grafica para crear modelos relacionados, utilizando JPA.
El creador de JPA Modeler  es  Gaurav Gupta 
Aqui puedes encontrar el tutorial anterior donde  se muestra el ejemplo usando(JPA Modeler  + GlassFish+ JEE8 +JPA + MySQL) JavaEE 8 con JPA muy fácil.

Con el desarrollo de JGMongo que es un Java Object Mapper para MongoDB, mostrare como utilizar JGMongo con JEE8. 
Al ejecutar la aplicación

Listado de países


    @GET
    @Path("list")
    @Controller
    public String findAllPaises() {

        model.put("PAISES_LIST", facade.findAll(new Document()));
        return "/view/paises/list.jsp";
    }


Crear un nuevo país

  @POST
    @Path("new")
    @Controller
    @ValidateOnExecution(type = ExecutableType.NONE)
    @CsrfValid
    public String createPaies(@Valid
            @BeanParam Paises paises) {
        if (validationResult.isFailed()) {
            return ValidationUtil.getResponse(validationResult, error);
        }
        facade.save(paises);
        return "redirect:paises/list";
    }


Vista
 @GET
    @Path("{siglas}")
    @Controller
    public String findPaises(@PathParam("siglas") String siglas) {
        model.put("PAISES", facade.find("Siglas",siglas));
        return "/view/paises/view.jsp";
    }



Usaremos la estructura de proyecto creado con JPA Modeler y haremos la implementación con JGMongo.
Pasos:
1. Crear el proyecto Maven 

2. Agregar las dependencias  (pom.xml)
  <dependencies>
       
        <dependency>
            <groupId>com.jgmongo</groupId>
            <artifactId>jgmongo</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
          <!-- Needed until Java EE 8 -->
        <dependency>
            <groupId>javax.mvc</groupId>
            <artifactId>javax.mvc-api</artifactId>
            <version>1.0-edr2</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.ozark</groupId>
            <artifactId>ozark</artifactId>
            <version>1.0.0-m02</version>
            <scope>runtime</scope>
        </dependency>

    </dependencies>

3. Crear MongoClientProvider
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MongoClientProvider {
    private MongoClient mongoClient = null;

@Lock(LockType.READ)
public MongoClient getMongoClient(){
return mongoClient;
}

@PostConstruct
public void init() {
            try {
               mongoClient = new MongoClient();
            } catch (Exception e) {
                JSFUtil.addErrorMessage("init() "+e.getLocalizedMessage());
            }
}
}

4. Crear el entity Paises

@Getter
@Setter
public class Paises extends GenericBeans {

    @Id
    @FormParam("siglas")
    @SerializedName("Siglas")
    private String siglas;
    @FormParam("pais")
    @SerializedName("Pais")
    private String pais;
    @FormParam("logo")
    @SerializedName("Logo")
    private String logo;

    public Paises() {

    }

    public Document toDocument(Paises paises) {
        Document doc = new Document();
        try {
            doc = Document.parse(getGson().toJson(paises));
        } catch (Exception e) {
            System.out.println("toDocument() " + e.getLocalizedMessage());
        }
        return doc;
    }

    public Paises toPojo(Document doc) {
        Paises paises = new Paises();
        try {
            paises = (Paises) fromJsontoPojo(doc.toJson(), new Paises().getClass());
        } catch (Exception e) {
            System.out.println("toPojo() " + e.getLocalizedMessage());
        }
        return paises;
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    }


}


5. Crear el Facade
@Stateless
@Named("paises")
public class PaisesFacade extends AbstractFacade<Paises> {
   @EJB
    MongoClientProvider mongoClientProvider;
    List<Paises> list = new ArrayList<>();
    Paises paises = new Paises();

  @Override
    protected MongoClient getMongoClient() {
        return mongoClientProvider.getMongoClient();
    }
    public PaisesFacade() {      
        super(Paises.class, "fantasy", "paises");
    }

}

6. Editar las paginas 



6.1 Editar create.jsp
 <form role="form" action="${appPath}/paises/new" method="POST">
                           <div class="form-group">
                                    <label for="siglas">Siglas</label>
                     <input class="form-control" type="text" name="siglas" path="siglas"  required="required" autofocus="autofocus"  />
                                </div>
                                <div class="form-group">
                                    <label for="pais">Pais</label>
                                    <input class="form-control" type="text" name="pais" path="pais"  />
                                </div>
                                <div class="form-group">
                                    <label for="logo">Logo</label>
                                    <input class="form-control" type="text" name="logo" path="logo"  />
                                </div>
                                
                                
                                <input type="hidden" name="${mvc.csrf.name}" value="${mvc.csrf.token}"/>
                                <button type="submit" class="btn btn-primary"><i class="fa fa-check fa-fw"></i>Submit</button>
                                <a href="${appPath}/paises/list" class="btn btn-default"><i class="fa fa-close fa-fw"></i>Cancel</a>
                            </form>

6.2 Editar list.jsp
 <c:forEach items="${PAISES_LIST}" var="PAISES">
                                    <tr>
                                        <td>${mvc.encoders.html(PAISES.siglas)}</td>

                                        <td>${mvc.encoders.html(PAISES.pais)}</td>

                                        <td>${mvc.encoders.html(PAISES.logo)}</td>


                                        <td>
                                            <div class="pull-right">
                                                <div class="btn-group">
                                                    <button type="button" class="btn btn-primary btn-xs dropdown-toggle" data-toggle="dropdown">
                                                        <i class="fa fa-gear"></i>  <span class="caret"></span>
                                                    </button>
                                                    <ul class="dropdown-menu pull-right" role="menu">
                                                        <li><a href="${PAISES.siglas}"><i class="fa fa-level-up fa-fw"></i>  View</a></li>
                                                        <li><a href="${appPath}/paises/update/${PAISES.siglas}"><i class="fa fa-edit fa-fw"></i>  Edit</a></li>
                                                        <li class="divider"></li>
                                                        <li><a data-toggle="modal" data-target="#confirm_delete_${PAISES.siglas}" href="#"  ><i class="fa fa-trash-o fa-fw"></i> Delete</a>
                                                        </li>
                                                    </ul>
                                                </div>
                                            </div>
                                            <!-- Modal -->
        <div class="modal fade" id="confirm_delete_${PAISES.siglas}" tabindex="-1" role="dialog" aria-hidden="true">
                                                <div class="modal-dialog">
                                                    <div class="modal-content">
                                                        <div class="modal-header">
           <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                                                            <h4 class="modal-title">Confirmation</h4>
                                                        </div>
                                                        <div class="modal-body">
                                                            <p>Are you sure to delete Pais ?</p>
                                                        </div>
                                                        <div class="modal-footer">
                                                            <form action="${appPath}/paises/remove/${PAISES.siglas}" method="DELETE">
                                                                <a href="#" class="btn" data-dismiss="modal">Cancel</a> <button type="submit" class="btn btn-primary">Confirm</button>
                                                            </form>
                                                        </div>
                                                    </div>
                                                    <!-- /.modal-content -->
                                                </div>
                                                <!-- /.modal-dialog -->
                                            </div>
                                            <!-- /.modal -->
                                        </td>

                                    </tr>

                                </c:forEach>


AVBravo - August 18, 2016 03:21 PM
JGMongo con JEE7 +(Primefaces+MongoDB+GlassFish)

Mostrare un ejemplo básico del uso de JGMongo, (Java Mapper Object para MongoDB), en un entorno JavaEE 7.


Desarrollaremos una simple aplicación maven Java Enterprise Edition, que utiliza la base de datos NoSQL MongoDB, NetBeans como IDE de Desarrollo, Java Server Faces como Framework en conjunto con PrimeFaces.
Es un ejemplo muy básico donde se almacena los datos de los países en una colección llama paises
La vista final sera la siguiente un formulario para captar los datos


Y una pagina donde se muestran los países almacenados en la base de datos.

Pasos previos:
1. Instalar MongoDB
2. Crear el proyecto Maven
3. Agregar la dependencia al archivo pom.xml
  <repositories>
<repository>
   <id>jitpack.io</id>
   <url>https://jitpack.io</url>
</repository>
</repositories>

    <dependency>
   <groupId>com.github.avbravo</groupId>
   <artifactId>jgmongo</artifactId>
   <version>0.1</version>
</dependency>

4. Crear el entity Paises

import com.google.gson.annotations.SerializedName;
import com.jgmongo.services.GenericBeans;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;

/**
 *
 * @author avbravo
 */
@Getter
@Setter
public class Paises extends GenericBeans {

    @SerializedName("Siglas")
    private String siglas;
    @SerializedName("Pais")
    private String pais;
    @SerializedName("Logo")
    private String logo;
    

    public Document toDocument(Paises paises) {
        Document doc = new Document();
        try {                        
            doc = Document.parse(getGson().toJson(paises));
        } catch (Exception e) {
            System.out.println("toDocument() " + e.getLocalizedMessage());
        }
        return doc;
    }

    public Paises toPojo(Document doc) {
        Paises paises = new Paises();
        try {
             paises = (Paises) fromJsontoPojo(doc.toJson(), new Paises().getClass());
        } catch (Exception e) {
            System.out.println("toPojo() " + e.getLocalizedMessage());
        }
        return paises;
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    } 
}

5. Crear MongoClientProvider para gestionar la conexión  a MongoDB

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MongoClientProvider {
    private MongoClient mongoClient = null;
@Lock(LockType.READ)
public MongoClient getMongoClient(){
return mongoClient;
}
@PostConstruct
public void init() {
            try {
                mongoClient = new MongoClient();
            } catch (Exception e) {
                JSFUtil.addErrorMessage("init() "+e.getLocalizedMessage());
            }
}
}

6. Crear al Facade

@Stateless
public class PaisesFacade extends AbstractFacade<Paises> {
   @EJB
    MongoClientProvider mongoClientProvider;
    List<Paises> list = new ArrayList<>();
    Paises paises = new Paises();

  @Override
    protected MongoClient getMongoClient() {
        return mongoClientProvider.getMongoClient();
    }
    public PaisesFacade() {      
        super(Paises.class, "mydatabase", "paises");
    }
}

7. Crear el Controller

@Named
@ViewScoped
@Getter
@Setter
public class PaisesController Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    PaisesFacade paisesFacade;
    List<Paises> paisesList = new ArrayList<>();
    Paises paises = new Paises();
    Paises selectedPaises = new Paises();


    /**
     * Creates a new instance of PaisesController
     */
    @PostConstruct
    public void init() {
            paisesList = paisesFacade.findAll(new Document());
       }

    public PaisesController() {
    }

   
    public void save() {
             paisesFacade.save(paises)) {
   }

    public String remove(Paises paises) {
        
   paisesFacade.remove(new Document("Siglas",paises.getSiglas())) ;
    }
    public String removeAll(Paises paises) {        
       paisesFacade.removeAll( );
        }
  
}


8. Pagina paises.xhtml

 <p:outputLabel for="siglas" value="#{msg.siglas}"/>
      <p:inputText id="siglas" value="#{paisesController.paises.siglas}"                                                               />

                            <p:outputLabel for="pais" value="#{msg.pais}"/>
                            <p:inputText id="pais" value="#{paisesController.paises.pais}"/>

                            <p:fileUpload   auto="true" label="Foto" fileUploadListener="#{paisesController.handleFileUpload}" style="max-width:90px;" update=":form:growl,:form:foto"/>
                            <h:graphicImage id="foto" value="/resources/fotos/paises/#{paisesController.paises.logo}" height="80" width="80"/>

                            <p:outputLabel for="btn" value=" " />
                            <p:commandButton id="btn" value="#{app['boton.save']}" icon="fa fa-edit Fs14 White"  style="max-width:150px;"
                                             update=":form:growl"
                                             action="#{paisesController.save()}"
                                             />


9. Pagina paisesdatatable.xhtml
          <p:dataTable id="paisesDataTable" var="item" value="#{paisesController.paisesList}" 
                                 selectionMode="single" 
                                 selection="#{paisesController.selectedPaises}"
                                 rowKey="#{item.siglas}"
                                 rows="10" paginator="true" paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                                 rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with given criteria" reflow="true">
                        <f:facet name="header">
                            <p:outputLabel value="#{msg.paises}"/>
                        </f:facet>

                        <p:ajax event="rowSelect" update=":form:paisesDetaill" oncomplete="PF('paisesDialog').show()" />

         <p:column headerText="#{msg.siglas}" sortBy="#{item.siglas}" footerText="#{msg.siglas}">
                            <h:outputText value="#{item.siglas}" />
          </p:column>
           
         <p:column headerText="#{msg.pais}" sortBy="#{item.pais}" footerText="#{msg.pais}">
                            <h:outputText value="#{item.pais}" />
           </p:column>
                        
                        
               <p:column>
                            <f:facet name="header">
                                   <p:outputLabel value="#{msg.logo}"/>
                            </f:facet>
               <h:graphicImage id="foto" value="/resources/fotos/paises/#{item.logo}" height="30" width="30"/>
              </p:column>
  </p:dataTable>

Si agregas el plugin de MongoDB para NetBeans puedes consultarlo desde el mismo IDE

o desde consola de MongoDB







AVBravo - August 18, 2016 02:31 AM
JGMongo

JGMongo un Java Mapper para MongoDB

Hace algún tiempo estaba interesado en la creación de un framework para trabajar
con MongoDB.
Esta versión que les presento es v0.1, permite realizar las operaciones de consultas, eliminación, ordenación, implementaciones de helpers, implementaciones Query, contadores, todo a traves de simples invocaciones de metodos Java.

El esquema general
1. Definir los beans
2. Crear un facade que herede de AbstractFacade
Con esto es todo lo que necesitas para interactuar con tu base de datos mongodb





La idea es que puedas trabajar de manera muy fácil  MongoDB desde aplicaciones Java

Los pasos son sencillos
Si usas Maven agrega al archivo  pom.xml

    <repositories>

<repository>

 <id>jitpack.io</id>

  <url>https://jitpack.io</url>

</repository>

</repositories>

   
    <dependencies>
         <dependency>
   <groupId>com.github.avbravo</groupId>
   <artifactId>jgmongo</artifactId>
   <version>0.1</version>
</dependency>
    </dependencies>


Cree los beans
Deben heredar de GenericBeans, implementar los métodos toDocument(), toPojo()

@Getter

@Setter

public class Paises extends GenericBeans  {

    @SerializedName("Siglas")
    private String siglas;
    @SerializedName("Pais")
    private String pais;
    @SerializedName("Logo")
    private String logo;
 

    public Document toDocument(Paises paises) {
        Document doc = new Document();              
        doc = Document.parse(getGson().toJson(paises));  
        return doc;
    }

    public Paises toPojo(Document doc) {
        Paises paises = new Paises();
        paises = (Paises) fromJsontoPojo(doc.toJson(), new Paises().getClass());
        return paises;
    }

    @Override
    public String toString() {
        return "Paises{" + "siglas=" + siglas + ", pais=" + pais + '}';
    }
}


Para la versión  Java Standar Edition



Crear el  Facade

public class PaisesFacade extends AbstractFacade<Paises>{

    public PaisesFacade( ){
        super(Paises.class, "mydatabase", "paises");
    }

    @Override
    protected MongoClient getMongoClient() {
         MongoClient mongoClient = new MongoClient();
         return mongoClient;
    }
 
}

Ejemplo de Uso

   PaisesFacade paisesFacade =new PaisesFacade();
     
        Paises paises = new Paises();
        paises.setSiglas("pa");
        paises.setPais("Panama");
        paises.setLogo("");
        //save document
        paisesFacade.save(paises);
        //list all document
        List<Paises> list = paisesFacade.findAll(new Document());
        list.stream().forEach((p) -> {
            System.out.println(p.toString());
        });

Para Java Enterprise Edition

Cree   MongoClientProvider 
Este  fue desarrollado por Adrian Matei en este enlace

Permite mediante un Singleton conectarse a MongoDB en aplicaciones Java Enterprise Edition

@Singleton

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)

public class MongoClientProvider {

    private MongoClient mongoClient = null;

@Lock(LockType.READ)
public MongoClient getMongoClient(){
return mongoClient;
}

@PostConstruct
public void init() {
            try {
                mongoClient = new MongoClient();
            } catch (Exception e) {
                JSFUtil.addErrorMessage("init() "+e.getLocalizedMessage());
            }

}

}

 Cree el Facade

@Stateless

public class PaisesFacade extends AbstractFacade<Paises> {


    @EJB

     MongoClientProvider mongoClientProvider;


     List<Paises> list = new ArrayList<>();

     Paises paises = new Paises();

   @Override

    protected MongoClient getMongoClient() {

         return mongoClientProvider.getMongoClient();

    }

    public PaisesFacade() {    

         super(Paises.class, "mydatabase", "paises");

    }

}


Ejemplo de Uso

@Named

@ViewScoped

public class PaisesController implements Serializable {

@Inject

PaisesFacade paisesFacade;

public Boolean save(Paises paises){

       return paisesFacade.save(paises);

}


public List<Paises> getPaises(){

      return paisesFacade.findAll(new Document());
}

AVBravo - July 14, 2016 05:29 PM
COMPILATION ERROR : error: cannot find symbol en Maven

Entre algunos errores que podemos encontrar al crear un proyecto  maven
COMPILATION ERROR :  error: cannot find symbol.
Generalmente tenemos una clase en uno de los paquetes , y esta la importamos en otro paquete pero al compilar el proyecto se genera errores como este:

Editamos el archivo pom.xml y agregamos
    <build>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>


AVBravo - July 13, 2016 03:11 AM
Un ejemplo sencillo de Refactorización y Genericos

Un ejemplo sencillo de Refactorización y Genericos

public class Refactorizador<K, V> {

    public V copyFromBeans(K k, V v) {
        try {
            Class claseK = k.getClass();
            Class claseV = v.getClass();

            Method[] metodosK = claseK.getMethods();

            for (Method method : metodosK) {
                if (isGetter(method)) {
                    Method metodoGetK = claseK.getDeclaredMethod(method.getName());
                    Method metodoSetV = claseV.getDeclaredMethod(changeGetBySet(method.getName()), method.getReturnType());
                    metodoSetV.invoke(v, metodoGetK.invoke(k));
                }

            }

        } catch (Exception e) {
            System.out.println("refactorizador() " + e.getLocalizedMessage());
        }
        return v;
    }
   
     public  boolean isGetter(Method method) {

        if (!method.getName().startsWith("get")) {
            return false;
        }
        if (method.getName().startsWith("getClass")) {
            return false;
        }

        if (method.getParameterTypes().length != 0) {
            return false;
        }
        if (void.class.equals(method.getReturnType())) {
            return false;
        }
        return true;
    }

    public  boolean isSetter(Method method) {
        if (!method.getName().startsWith("set")) {
            return false;
        }
        if (method.getParameterTypes().length != 1) {
            return false;
        }
        return true;
    }

    /**
     * cambia el metodo get por set
     *
     * @param metodo
     * @return
     */
    public String changeGetBySet(String metodo) {
        try {

            metodo = metodo.replace("get", "set");
        } catch (Exception e) {
            System.out.println("changeGetBySet()" + e.getLocalizedMessage());
        }
        return metodo;
    }
  
}
Clases:
public class Persona{
   private String nombre;

   private String direccion;
//get/set

}
public class Generales{
   private String nombre;
   private String direccion;
//get/set
}

Uso:
Copia el contenido de la clase Persona a la clase Generales
Refactorizador refactorizador = new Refactorizador();
Persona persona = new Persona();
persona.setNombre("X12");
persona.setDireccion("Panama");

 Generales generales = new Generales();
generales= (Generales) refactorizador.copyFromBeans(persona,generales);

AVBravo - June 29, 2016 02:35 PM
Entrevista a Adam Bien sobre Microprofile.io

Recientemente se han creado iniciativas para impulsar los avances en la plataforma JEE  como son Java EE Guardians (https://javaee-guardians.io/) con el propósito de impulsar la plataforma JEE8 , y en los últimos días  algunas empresas entre las que figuran (Redhat,Payara, IBM,Tomitribe, LJC) se unieron para  MicroProfile ( http://microprofile.io), para promover la implementación de Microservicios dentro de JEE.
En esta oportunidad entreviste por segunda vez a Adam Bien( http://www.adam-bien.com/), sobre algunos aspectos generales de Microprofile.



1. Do you consider that microservices is fundamental to the Java Ecosystem?

In most projects we built “microservices” for several years without knowing the term. Microservices are not fundamental, they are rather natural fit to Java EE.

2. Do you believe that there is a delay in the adoption of microservices?

No. My clients are perfectly happy with Java EE 7 full profile. It is surprisingly lean.
However, monitoring could be even more standardized (beyond JSR-77) and exposed via stock JAX-RS.

Monitoring and other non-functional requirements are not the part of the microprofile.io, but this is just the start.

3. Why does this alliance arise prior to a JCP specification?

Do you mean microprofile.io? It is just a pragmatic way to involve community. The goal is to standardize whatever possible with JCP. But we should involve the community first.


4.Will major changes in the use of microservices affect the  develop meant of business applications?
All project driven by actual requirements and not by esoteric architectures should look already surprisingly microservices compliant.

5- Was us your opinion about  Java EE Guardians  and  MicroProfile.io?
I did not created Java EE Guardians (JEG). Because of lack of time I’m watching “from outside” what they are doing. IMO The JEG try to explain Oracle that Java EE is important for business. I share their opinion: http://www.adam-bien.com/roller/abien/entry/oracle_moves_in_strange_ways

microprofile.io focusses on a minimal Enterprise Java profile. I’m not sure whether we can officially call it Java EE 8 MicroProfile.

It wouldn’t surprise me, if another Java EE related website is going to be published soon :-)






6. What recommendations  could you give us?

Write 90% business code, focus on domain, forget the fashion. Simplicity wins in long term.

Agradecido a Adam Bien por su tiempo y sus aportes.


AVBravo - June 26, 2016 07:58 PM
Funciones Year en JPA

Si deseas usar funciones SQL con JPA, podemos hacerlo mediante FUNC('funcion',nombre-columna')


public List<Recibos> findByIdentificadorAnioActividades(Identificador id, Integer anio, Actividades idactividades) {
        Query query = em.createQuery("SELECT r FROM Recibos r WHERE r.id = :id and FUNC('YEAR',r.fecha) = :anio and r.idactividades = :idactividades and r.anulado ='no'");
        query.setParameter("idactividades", idactividades);
        query.setParameter("anio", anio);
        return query.setParameter("id", id).getResultList();
    }

AVBravo - June 15, 2016 03:20 AM
JavaEE Guardians Petición


Como parte de las actividades del grupo Java EE Guardians, https://javaee-guardians.io/, se creo una petición para lograr avances en una de las plataformas de desarrollo mas robustas Java EE.
Puedes firmarla si estas de acuerdo con la propuesta en el siguiente enlace:
https://www.change.org/p/larry-ellison-tell-oracle-to-move-forward-java-ee-as-a-critical-part-of-the-global-it-industry

Hasta este momento lleva más de 800 firmas, de desarrolladores, lideres de grupos de usuarios,etc.

AVBravo - June 11, 2016 03:45 PM
JavaEE 8 con JPA muy fácil

JavaEE 8 con JPA muy fácil
Que tan fácil es programar en JavaEE8, aun no esta terminado JavaEE8, pero desde hace algún tiempo tenemos la oportunidad de ir probando  las características que implementa.
Usaremos un proyecto creado con JPA Modeler, y mostraremos lo sencillo que es implementar un nuevo modulo en este ejemplo para almacenar la información de una persona en una tabla en MySQL.
Agregamos a la pagina principal el nuevo modulo llamado persona.


Creamos un formulario con los datos de la persona

Lo mostramos en una tabla


Creamos un entity llamado Persona
@Entity
public class Persona implements Serializable {

    @Id
    @FormParam("id")
    private Long id;

    @Column(name = "nombre")
    @Basic
    @NotNull
    @Size(min = 5, max = 50, message = "El nombre debe tener entre 5 y 50 caracters")
    @FormParam("nombre")
    private String nombre;

    @Basic
    @FormParam("direccion")
    private String direccion;
//get/set
}

Creamos el facade PersonaFacade
@Stateless
@Named("persona")
public class PersonaFacade extends AbstractFacade<Persona> {

    @PersistenceContext(unitName = "DEFAULT_PU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public PersonaFacade() {
        super(Persona.class);
    }
    
}

Creamos el controller PersonaController
@Path("persona")
public class PersonaController {

    @Inject
    private Models model;
    @Inject
    private PersonaFacade facade;
    @Inject
    private BindingResult validationResult;
    @Inject
    private ErrorBean error;

    @GET
    @Path("new")
    @Controller
    public String emptyPersona() {
        return "/view/persona/create.jsp";
    }

    @POST
    @Path("new")
    @Controller
    @ValidateOnExecution(type = ExecutableType.NONE)
    @CsrfValid
    public String createPersona(@Valid
            @BeanParam Persona entity) {
        if (validationResult.isFailed()) {
            return ValidationUtil.getResponse(validationResult, error);
        }
        facade.create(entity);
        return "redirect:persona/list";
    }

    @GET
    @Path("update/{id}")
    @Controller
    public String editPersona(@PathParam("id") Long id) {
        model.put("PERSONA", facade.find(id));
        return "/view/persona/update.jsp";
    }

    @POST
    @Path("update")
    @Controller
    @ValidateOnExecution(type = ExecutableType.NONE)
    @CsrfValid
    public String updatePersona(@Valid
            @BeanParam Persona entity) {
        if (validationResult.isFailed()) {
            return ValidationUtil.getResponse(validationResult, error);
        }
        facade.edit(entity);
        return "redirect:persona/list";
    }

    @GET
    @Path("remove/{id}")
    @Controller
    public String removePersona(@PathParam("id") Long id) {
        facade.remove(facade.find(id));
        return "redirect:persona/list";
    }

    @GET
    @Path("{id}")
    @Controller
    public String findPersona(@PathParam("id") Long id) {
        model.put("PERSONA", facade.find(id));
        return "/view/persona/view.jsp";
    }

    @GET
    @Path("list")
    @Controller
    public String findAllPersona() {
        model.put("PERSONA_LIST", facade.findAll());
        return "/view/persona/list.jsp";
    }
    
}



Ejemplo del jsp