Filtro en J2ME

Iniciado por mgc, 26 Febrero 2015, 10:37 AM

0 Miembros y 1 Visitante están viendo este tema.

mgc

Hola,
Tengo que buscar un cliente determinado en un RecordStore, y lo quiero hacer con un filtro así:

import javax.microedition.rms.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;

public class ExampleSearch
{

private RecordStore recordstore = null;
private RecordEnumeration recordEnum= null;
private Filter filter = null;

// get the record store
public void getRecStore(){
recordstore= RecordStore.openRecordStore("myRec",true);
}
//
public boolean login(String userName,String password){
getRecStore();
filter = new Filter(userName+"#"+password); // create a filter on the search text
recordEnum= recordstore.enumerateRecords(filter, null, false);
if (recordEnum.numRecords() > 0)
{
return true;
}else{
return false;
}
}

}


/*
*    This class is used as a filter for this example which is exetnding the RecordFilter
*
*
*/
class Filter implements RecordFilter{
private String search = null;
private ByteArrayInputStream inputstream = null;
private DataInputStream datainputstream = null;
public Filter(String search)
{
this.search = search.toLowerCase();
}
public boolean matches(byte[] suspect)
{
String string = new String(suspect).toLowerCase();
if (string!= null && string.indexOf(search) != -1)
return true;
else
return false;
}
public void filterClose()
{
try
{
if (inputstream != null)
{
inputstream.close();
}
if (datainputstream != null)
{
datainputstream.close();
}
}
catch ( Exception error)
{
}
}
}


Lo que no se, es cómo llevarlo a cabo, porque si utilizo el método public boolean login(String userName,String password), me devuelve true, pero yo lo que quiero mostrar es el detalle de los datos del cliente.
¿Alguien me puede decir cómo hacerlo?

Gracias de antemano y un saludo.

Usuario Invitado

  • ¿Por cuál clase está representada tu entidad Cliente?
  • ¿Qué representa RecordStore?

    Puedes usar una clase llamada Cliente que sea la abstracción de un cliente en la realidad. Ésto se llama entidad o clase de dominio. Los pasos serían:

    1) Registrar un cliente como un Objeto Cliente:

    Código (java) [Seleccionar]
    Client someClient = new Client("nombre", "apellido", fechaNac, "dirección");


    2) En tu condición, buscas por el objeto cliente:

    Código (java) [Seleccionar]
    public Client login(String userName,String password){
        getRecStore();
        filter = new Filter(userName+"#"+password); // create a filter on the search text
        recordEnum= recordstore.enumerateRecords(filter, null, false);
        if (recordEnum.numRecords() > 0)
        {
            // buscas el cliente y si existe lo devuelves
        }else{
            // retorna null para indicar que no se han encontrando resultados
        }
    }


    No sé si será posible usar JPA con Java ME, sería muy útil en éstos casos, ya que buscarías un registro de la siguiente manera:

    Código (java) [Seleccionar]
    TypedQuery<Client> query = em.createQuery("SELECT * FROM Clients c WHERE c.username = :username");
    query.setParameter("username", clientUsername);
    Client client = query.getSingleResult(); // retorna el cliente buscado



    Básicamente la idea es que hagas la consulta a la BBDD buscando por el usuario actual y lo devuelvas. Puedes hacer un método para ésto también:

    Código (java) [Seleccionar]
    public Client buildClientFromCredentials(String username, String password) {
    Client client = null;
    try(PreparedStatement ps = connection.prepareStatement
    ("SELECT * FROM clients WHERE username = ? AND password = ?") {
    ps.setString(1, username);
    ps.setString(2, password);

    try(ResultSet rs = ps.executeQuery()) {
    while(rs.next()) {
    client = new Client();
    client.setId(rs.getInt("id"));
    client.setUsername(rs.getString("username"));
    client.setPassword(rs.getString("password"));
    }
    }
    } catch(SQLException ex) {
    logger.info("Error: "+ex.getMessage());
    throw new RuntimeException("Something was wromg, see the log for more details");
    }
    return client;
    }


    Y desde tu método lo llamas:

    Código (java) [Seleccionar]
    public Client login(String userName,String password){
        getRecStore();
        filter = new Filter(userName+"#"+password); // create a filter on the search text
        recordEnum= recordstore.enumerateRecords(filter, null, false);
        if (recordEnum.numRecords() > 0)
        {
            return buildClientFromCredentials(username, password);
        }else{
            return null;
        }
    }


    Así retornas el todos los datos del cliente en un objeto para trabajar más fácil con él. Por su puesto, si estás trabajando con listas para simular BBDD, la metodología es la misma.

    Salu2.
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

mgc

Te especifico algo más mi caso, porque yo las consultas no las hago a una base de datos, si no al propio RecordStore que es quien me almacena los registros.
Cada registro del RecordStore, será un cliente con su nombre y password.
Los clientes los muestro en una lista por su nombre, y seleccionándolos puedo ver el detalle (nombre y contraseña).
El constructor de la clase sería:
public bdClientes(String nombre){
       super(nombre,List.IMPLICIT);
   }


Cada registro tendrá será un String de esta forma nombre:password
El método que muestra la lista por pantalla sería este:
public void listarClientes(){
       //super.deleteAll();
       try {
           almacen= RecordStore.openRecordStore("Clientes", true);
           enumeracion=almacen.enumerateRecords(null, null, true);
           int numRegistros=0;
           
           //recorremos los registros con el enumerador
           while(enumeracion.hasNextElement()){
              // int id=enumeracion.nextRecordId();
               String registro=new String(enumeracion.nextRecord());
               numRegistros++;

               int separador=registro.indexOf(":");

               String nombre=registro.substring(0, separador);

               String password=registro.substring(separador+1);

               super.append(nombre, null);
           }
         
           //cerramos el almacen de registros
           almacen.closeRecordStore();
       } catch (RecordStoreException ex) {
           ex.printStackTrace();
       }
   }


Lo que quiero es mostrar los datos del Cliente seleccionado de esta lista.

El registro seleccionado de la lista sería este:

String registroLista=super.getString(super.getSelectedIndex());


Mi idea es buscar en el RecordStore el registro que coincide con registroLista.

Espero que esté claro al menos, mis intenciones. Mi problema es que no se llevar a cabo el Filter, en este caso.

Gracias y saludos.

Usuario Invitado

#3
No he tocado en mi vida Java ME :xD, pero por lógica viendo el código y lo que me has enseñado (gracias ^^), obtendría los detalles del cliente seleccionado así:

Código (java) [Seleccionar]
public String getClientDetails(String name) {
try {
           stock = RecordStore.openRecordStore("Clientes", true);
           enumeracion=almacen.enumerateRecords(null, null, true);
           int clients = 0;
           
           while(enumeracion.hasNextElement()){
              // int id=enumeracion.nextRecordId();
               String client =new String(enumeracion.nextRecord());
String[] clientData = client.split(":");
if(clientData[0].equals(name)) {
return client;
}
               clients++;

           }
         
       } catch (RecordStoreException ex) {
           ex.printStackTrace();
       } finally {
           almacen.closeRecordStore();
}

}


Donde:

  • String[] clientData = client.split(":") -> Divide el texto obenido desde el enumerador por medio del separador ":". Es decir, que busca el separador ":" y parte el texto anterior al separador y posterior. Por lo que:

    Si el cliente actual es por ejemplo: "Pepito:12345", el método split devuelve:

    Código (java) [Seleccionar]
    clientData[0] = "Pepito";
    clientData[1] = "12345";


  • Teniendo el nombre, lo comparo con el nombre proporcionado:

    Código (java) [Seleccionar]
    if(clientData[0].equals(name))

    Si hay match es porque se ha encontrado al usuario y se devuelve al método encargado de mostrar los detalles.

    NOTA: Siempre se debe cerrar las conexiones en el finally ya que, si ocurre alguna excepción nunca se cerrará la conexión. Todo lo que se coloca en el finally se ejecuta sí o sí.

    Salu2.
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

mgc

¿Es posible que split no se pueda utilizar en j2me?
Te adjunto captura.



Muchas gracias, saludos.

Usuario Invitado

Por lo visto JavaME no soporta el método split de String. Pero siempre podemos improvisar ;)

Código (java) [Seleccionar]
int separator = client.indexOf(":");
    String username = client.substring(0,separator);
    String password = client.substring(separator+1);
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

mgc

Tras hacer los cambios este sería el código,
Utilizo un método para devolver el nombre y otro para devolver el password, que debo insertarlos en campos diferentes en el display.

¿Cómo lo ves?

    public String getClientPass(String name) throws RecordStoreException {
        String pass="";
        try {
            almacen = RecordStore.openRecordStore("Clientes", true);
            enumeracion = almacen.enumerateRecords(null, null, true);
            int clients = 0;

            while (enumeracion.hasNextElement()) {
                // int id=enumeracion.nextRecordId();
                String client = new String(enumeracion.nextRecord());
                int separator = client.indexOf(":");
                String username = client.substring(0, separator);
                String password = client.substring(separator + 1);
                //String[] clientData = client.split(":");
                if (username.equals(name)) {
                    // muestras los detalles del cliente
                    pass = password;
                }
                clients++;
            }

        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } finally {
            almacen.closeRecordStore();
        }
        return pass;
    }

Usuario Invitado

#7
Eso ya depende de tu lógica de negocio ^^. Sólo una observación, sería más lógico inicializar pass en null, cosa que luego comparamos if(getClientPass(username) == null) para saber si se ha encontrado el cliente, en lugar de if(getClientPass(username).isEmpty()).

El resto, lo veo bien. Si fui de ayuda y resolviste tu problema, por favor marca el título del tema con un check verde. ¡Un saludo!
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein

mgc

Muchas gracias por todo, yo creo que si está resuelto, ahora me queda ponerlo todo en su sitio y que funcione... Estoy iniciándome en esto, y todo me cuesta un mundo.

Saludos.