Converter de Documentos Embebidos con primefaces+ JmoordbCore
Published: 2024-04-24 14:23:26

En algunas ocasiones necesitamos crear converter para una lista de documentos embebidos.
El documento almacenado en MongoDB contiene la siguiente información:

```json
{
  "_id" : ObjectId("6620299468e7bc6f78711eb8"),
  "actionHistory" : [{
      "fecha" : ISODate("2024-04-18T15:53:56.458Z"),
      "iduser" : NumberLong(8),
      "evento" : "editar",
      "clase" : "ClienteFaces",
      "metodo" : "edit"
    }, {
      "fecha" : ISODate("2024-04-19T17:25:09.473Z"),
      "iduser" : NumberLong(75),
      "evento" : "editar",
      "clase" : "ClienteFaces",
      "metodo" : "edit"
    }, {
      "fecha" : ISODate("2024-04-24T14:28:01.956Z"),
      "iduser" : NumberLong(8),
      "evento" : "editar",
      "clase" : "ClienteFaces",
      "metodo" : "edit"
    }],
  "active" : true,
  "cedularuc" : "14575222222222222222222222",
  "celular" : "8585",
  "direccion" : "La Villa de los Santos",
  "dv" : "85",
  "email" : "avb@gmail.com",
  "fax" : "adad",
  "gobierno" : false,
  "idcliente" : NumberLong(28),
  "name" : "Empresas D",
  "observacion" : "No se que mas hacer",
  "representante" : [{
      "cedula" : "8585",
      "nombre" : "juan perez",
      "dv" : "80",
      "telefono" : "djdjd",
      "email" : "ad@gmail.com",
      "active" : true
    }, {
      "cedula" : "6-9-6",
      "nombre" : "LUISA GONZALEZ",
      "dv" : "14",
      "telefono" : "966-96",
      "email" : "s@gmail.com",
      "active" : true
    }],
  "sede" : [{
      "idsede" : "A91845E7-70EA-40D7-9174-5FEF091D87B4",
      "nombre" : "LS",
      "direccion" : "Los Santos",
      "telefono" : "9685",
      "email" : "ls@gmail.com",
      "active" : true
    }, {
      "idsede" : "90C77A6C-CFAA-4507-95B9-F6800929654F",
      "nombre" : "CHITRE",
      "direccion" : "Barriada x-",
      "telefono" : "7855",
      "email" : "re@gmail.com",
      "active" : true
    }, {
      "idsede" : "634ED82C-4753-4A2A-85D2-03DD6BC80E02",
      "nombre" : "PEDASI",
      "direccion" : "PEDASI, LOS SANTOS",
      "telefono" : "96978555",
      "email" : "a@gmai.com",
      "active" : true
    }],
  "telefono" : "98755",
  "tipocliente" : "Juridico"
}

```



Por ejemplo contamos con esta entidad

```java
@Entity
public class Cliente {
      @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long idcliente;
    @Column(generateQuery = true)
    private String cedularuc;

    @Column(commentary = "natural/juridico", generateQuery = true)
    private String tipocliente;
    @Column
    private String dv;
    @Column(generateQuery = true)
    private String name;
    @Embedded
    private List<Sede> sede;

    @Embedded
    private List<Representante> representante;

    @Column
    private String direccion;
    @Column
    private String telefono;
    @Column
    private String celular;
    
    @Column
    private String fax;
    
    
    @Column
    private String email;
    @Column
    private String observacion;

   
    @Column
    private Boolean gobierno;
       
    @Column
    private Boolean active;
    
    
    @Embedded
    List<ActionHistory> actionHistory;
...
}
```


## Sede

```java
@DocumentEmbeddable
public class Sede {

    @Column
    private String idsede;
    @Column
    private String nombre;
    @Column
    private String direccion;
    @Column
    private String telefono;
    @Column
    private String email;
    @Column
    private Boolean active;
...
}
```


## Representante

```java
@DocumentEmbeddable
public class Representante {

    @Ignore
    private Long id;
    @Column
    private String cedula;
    @Column
    private String nombre;
    @Column
    private String dv;
    @Column
    private String telefono;
    @Column
    private String email;
    @Column
    private Boolean active;
...
}

```

Imaginemos que contamos con un formulario en el cual se necesita seleccionar de una lista de los embebidos Sede, Representante, mediante selectOneMenu, necesitaremos crear converter para estos elementos.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p7d03closob2ivd5b951.png)


Para ello debemos almacenar la lista obtenida

En el autocomplete que selecciona el cliente invocamos al método autocompleteSelectedEventCliente.

```
<p:autoComplete id="autocompletecliente" multiple="false" 
        value="#{proyectoFaces.clienteSelectedAutocomplete}"
        completeMethod="#{proyectoFaces.completeCliente}"
        var="cliente" itemLabel="#{cliente.name}  #{cliente.cedularuc}" 
        itemValue="#{cliente}"
        forceSelection="true"
        title="#{msg['autocomplete.minimo3caracteres']}"
        dropdown="true"
        minQueryLength="3"
        scrollHeight="250"
        converter="#{clienteConverter}"
        >
    <p:column>
        <h:outputText style="vertical-align: middle; margin-left: .5rem" value="#{cliente.name} - #{cliente.cedularuc}"/>
    </p:column>
    <p:ajax event="itemSelect"  
            listener="#{proyectoFaces.autocompleteSelectedEventCliente}"  
            update=":form:growl, autocompletecliente, outputPanelCliente" />  
    <p:ajax event="itemUnselect"  process="@this"
            listener="#{proyectoFaces.autocompleteUnselectListener}" 
            update=":form:growl, autocompletecliente, outputPanelCliente" />
</p:autoComplete>

```

Este método almacena en  JmoordbCoreContext.put("sedeConverter", clienteSelectedAutocomplete.getSede()); la lista de las sedes que serán usadas en el converter.

```java
 public void autocompleteSelectedEventCliente(SelectEvent<Cliente> event) {
        try {

            clienteSelectedAutocomplete.getIdcliente();
            proyectoSelected.setCliente(clienteSelectedAutocomplete);
            /**
             * Alamacena los valores para usar en el converter del valor
             * embebido
             */
            if (isJuridico(clienteSelectedAutocomplete)) {
                JmoordbCoreContext.put("sedeConverter", clienteSelectedAutocomplete.getSede());
                JmoordbCoreContext.put("representanteConverter", clienteSelectedAutocomplete.getRepresentante());
            }

            if (buttonNewPressed) {
                proyectoSelected.setProyecto(rf.fromMessage("label.proyectode") + ": " + clienteSelectedAutocomplete.getName());
                proyectoSelected.setDescripcion(rf.fromMessage("label.descripcionde") + ": " + clienteSelectedAutocomplete.getName());
                proyectoSelected.setDireccion(clienteSelectedAutocomplete.getDireccion());
                proyectoSelected.setTelefono(clienteSelectedAutocomplete.getTelefono());
                proyectoSelected.setEmail(clienteSelectedAutocomplete.getEmail());
                proyectoSelected.setFax(clienteSelectedAutocomplete.getFax());
                proyectoSelected.setTipocliente(clienteSelectedAutocomplete.getTipocliente());
            } else {

            }

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

```


Defina el converter

```java
import com.avbravo.jmoordbutils.ConsoleUtil;
import com.avbravo.jmoordbutils.FacesUtil;
import com.avbravo.jmoordbutils.JmoordbCoreContext;
import com.nerys.converter.services.IconoConverterServices;
import com.nerys.model.Sede;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.ConverterException;
import jakarta.faces.convert.FacesConverter;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 *
 * @author avbravo
 */

@Named
@FacesConverter(forClass = Sede.class, managed = true)
public class SedeConverter implements Converter<Sede> {

    @Inject
    IconoConverterServices iconoConverterServices;

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Sede t) {
        try {

            if (t == null) {

                return "";
            }

            if (t.getIdsede()!= null) {

                return t.getIdsede().toString();
            } else {

            }
        } catch (Exception e) {

            new FacesMessage("Error en converter  " + e.getLocalizedMessage());
        }

        return "";
    }

    @Override
    public Sede getAsObject(FacesContext fc, UIComponent uic, String submittedValue) {
      Sede a = new Sede();
        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            Optional<Sede> optional =Optional.empty();
            List<Sede> sedes = (ArrayList<Sede>)JmoordbCoreContext.get("sedeConverter");
            if(sedes == null || sedes.isEmpty()){
                  
            }else{
                for(Sede s:sedes){
                    if(s.getIdsede().equals(submittedValue)){
                       optional = Optional.of(s);
                    }
                }
             
           }            

            if (!optional.isEmpty()) {

               return optional.get();
            }
            
        } catch (Exception e) {

            
            ConsoleUtil.error("\t " + FacesUtil.nameOfClassAndMethod() + " submittedValue " + submittedValue);
            
            throw new ConverterException(new FacesMessage(submittedValue + " is not a valid selecction from Converter"), e);
        }
        return a;
    }

   

}

```


Ahora en el formulario xthtml

```
<p:selectOneMenu  
       value="#{proyectoFaces.proyectoSelected.sede}"
      var="item" autoWidth="false">
    <f:selectItems 
           value="#{proyectoFaces.clienteSelectedAutocomplete.sede}"  
           var="item" 
           itemLabel="#{item.nombre}"
           itemValue="#{item}" />
    <p:column> #{item.nombre} 
    </p:column>


</p:selectOneMenu>
```


Con este proceso se realiza la conversión al valor deseado.