Č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:
June 23, 2018 10:03 AM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
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









AVBravo - June 08, 2016 01:37 AM
Java EE Guardians

Java EE Guardians



Después de unos meses sin escribir, ya que me encontraba en algunos proyectos que me han mantenido con un retraso en la publicación de algunas cosas sobre NetBeans , Java,JavaEE.
En esta ocasión deseo compartir con ustedes este iniciativa Java EE Guardians.
En la cual deseo agradecer a Reza  Rahman por la invitación a participar de este incitativa.

Java EE Guardians es un grupo de personas comprometidas con el futuro de Java EE, preocupados por los retrasos en los avances de JEE8 , el objetivo es preservar los intereses de la comunidad incluyendo Oracle para continuar con el éxito de JEE en el lado del servidor.
JEE es muy importante para el ecosistema de Java en general,  es usado en aplicaciones de misión critica y grandes cantidades de aplicaciones están escritas en JEE, por lo cual es fundamental la evolución de la plataforma.

Que actividades se están haciendo:

  • Evangelización de JEE, JEE8
  • Apoyo a los JSRs de Java EE 8
  • Discusiones activas con los miembros del grupo de expertos de JavaEE8
Hay muchas actividades en las que puedes participar.
Algunos enlaces de interés donde se amplían los detalles en el sitio oficial https://javaee-guardians.io/

Twitter:
JavaEE Guardian

Reza Rahman







AVBravo - December 02, 2015 02:23 AM
Web Responsive con Primefaces

Web Responsibe con Primefaces

Primefaces 5.3 soporta Web Responsive, por ejemplo



en el panelGrid indicamos la propiedad layout con el valor de grid
<p:panelGrid columns="3" layout="grid">


AVBravo - December 01, 2015 01:11 AM
Reportes con imagenes en Java Server Faces

Reportes con imagenes en Java Server Faces
Deseamos mostrar en el reporte la imagen escudonacional.gif, que está almacenada en
/resources/imagenes


En el controller que usamos para imprimir crear el metodo 
 public static String getPath() { 
        try { 
            ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance() 
                    .getExternalContext().getContext(); 
            return ctx.getRealPath("/"); 

        } catch (Exception e) { 

           JSFUtil.addErrorMessage("getPath() " + e.getLocalizedMessage()); 
   } 
        return null; 

    } 


En el método imprimir, generar el path mediante el llamado a getPath(), y colocar la 
ubicación de la imagen. 

private String imprimirGeneralIngresos(List<InformeGeneralIngresos> list, Double 
totalenviado, Double totalcomision, Double totalitbm, Double total) { 
        try { 

            String ruta = "/resources/reportes/informes/informegeneralingresos.jasper"; 
            HashMap parameters = new HashMap(); 


            ​
String path = getPath() + "resources/imagenes/escudonacional.gif"; 
                  parameters.put("P_RUTAIMAGEN", path);  


            gestorImpresion.imprimir(list, ruta, parameters); 
        } catch (Exception ex) { 
            JSFUtil.addErrorMessage("imprimirEnviados() " + ex.getLocalizedMessage()); 
        } 
        return null; 
    } 




 En el diseñador de Reporte  
Agregar el parámetro P_RUTAIMAGEN de tipo String 

Arrastrar un objeto de tipo image 

se muestra el dialogo para seleccionar la imagen 

Darle clic en Cancelar para no seleccionar ninguna imagen 

se muestra el icono que representa a la imagen 


dar clic en el image y buscar en properties , la propiedad Image Expression 

dar clic en el boton ... 

En el diálogo dar clic en Parameters y  seleccionar P_RUTAIMAGEN 

Quedaría de la siguiente manera, dar clic en Ok 


El icono que se mostraba anteriormente desaparece y queda el área de la imagen que será 
reemplaza por la que indiquemos en el controller 

Compilar el reporte 

Al ejecutar el proyecto se muestra la imagen en el reporte. 














AVBravo - November 21, 2015 04:30 AM
Usar un splitButton con datatable primefaces

En algunas ocasiones necesitamos desplegar varias opciones en un datatable, para evitar tener que definir muchas columnas, podemos utilizar un splitButton , que invoca un dialogo en base a cada opción seleccionada.


Al seleccionar la opción detalle, muestra un dialogo con el detalle de la fila seleccionada.
    <p:column style="width:40px;">  

                                    <p:fragment autoUpdate="true"> 

                                        <p:splitButton title="#{msg.opciones}"    icon="fa fa-align-left">
                                            
                                            <p:menuitem value="#{msg.detalle}" title="#{msg.detalle}" update=":form:growl,:form:datatableImpuestos   ,:form:panelcomentario" oncomplete= "PF('detalleDialogVar').show()"  icon="fa fa-file-text-o" >
                                                  <f:setPropertyActionListener value="#{item}" target="#{impuestoscontribuyentesController.selected}" />  
                                            </p:menuitem>
                                          
                                             <p:menuitem value="#{msg.pagos}" title="#{msg.pagos}" update=":form:growl,:form:datatableImpuestos   ,:form:panelpagos" oncomplete= "PF('pagosDialogVar').show()"  icon="fa fa-pinterest-p" >
                                                  <f:setPropertyActionListener value="#{item}" target="#{impuestoscontribuyentesController.selected}" />  
                                            </p:menuitem>
                                                 <p:separator />
                                            <p:menuitem value="#{msg.morosidad}" title="#{msg.morosidad}" update=":form:growl,:form:datatableImpuestos   ,:form:panelmorosidad" oncomplete= "PF('morosidadDialogVar').show()"  icon="fa fa-medium" >
                                                  <f:setPropertyActionListener value="#{item}" target="#{impuestoscontribuyentesController.selected}" />  
                                            </p:menuitem>
                                         <p:menuitem value="#{msg.recargo}" title="#{msg.recargo}" update=":form:growl,:form:datatableImpuestos   ,:form:panelrecargo" oncomplete= "PF('recargoDialogVar').show()"  icon="fa fa-bell" >
                                                  <f:setPropertyActionListener value="#{item}" target="#{impuestoscontribuyentesController.selected}" />  
                                            </p:menuitem>
                                       
                                           
                                        </p:splitButton>

                                      
                                    </p:fragment>


                                </p:column>


El dialogo
  <p:dialog  modal="false" 
                                   height="220"  width="510" draggable="true"
                                   id="pagarDialogVar"
                                   widgetVar="detalleDialogVar">

                            <b:panel id="panelcomentario2" look="primary" title="#{msg.detalle}">
                                <!--<p:panelGrid columns="2" id="panelcomentario">-->
                                <b:panelGrid id="paneldetalle" colSpans="2,10">
                                    <p:outputLabel value="#{msg.idnivel6}"/>
                                    <p:outputLabel value="#{impuestoscontribuyentesController.selected.idnivel6.idnivel6}"/>
                                    <p:outputLabel value="#{msg.nombre}"/>

                                    <p:outputLabel value="#{impuestoscontribuyentesController.selected.idnivel6.nombre}"/>


                                    <h:outputText value="#{msg.rango}"/>

                                    <h:outputText value="( #{impuestoscontribuyentesController.selected.idnivel6.minimo} a #{impuestoscontribuyentesController.selected.idnivel6.maximo} )"/>





                                    <p:commandButton 
                                        icon="ui-icon-close"
                                        update=":form:datatableImpuestos   ,:form:growl"
                                        onclick="PF('comentarioDialogVar').hide();"
                                        type="button" />


                                </b:panelGrid>


                            </b:panel>

                        </p:dialog>