martes, 3 de agosto de 2010

Renombrar ficheros desde Java

Hoy tuve que hacer un programita muy tonto pero que me quitó muchas horas
de trabajo de monos, así que os dejo el código por si a alguien le sirve
del mismo modo que a mí.

El programa lo que hace es renombrar todos los ficheros de un directorio
desde java. Este directorio estaba lleno de imagenes en formato png y lo
que tuve que hacer es añadir al final del nombre la coletilla "_thumb" que
viene de thumbnail.

Código


package renombradodeficheros;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
*
* @author Jorge
*/
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        
        String path = "resources/directory/";

        File directory = new File(path);
        String[] files = directory.list();
        File f1,f2;
        String filename, filenameModif;
        int cutindex;
        for (int i = 0; i < files.length; i++) {

            filename = files[i];
            f1 = new File(path+"/"+filename);
            cutindex = filename.indexOf(".png");
            if (cutindex != -1)
            {
                filenameModif = filename.substring(0, cutindex)+"_thumb.png";
                f2 = new File(path+"/"+filenameModif);
                if (f1.renameTo(f2))
                    System.out.println("Renombrado");
                else
                    System.out.println("Fallo al renombrar");
            }
        }
    }
}

Trabajar con XML y C#

Hola a todos,

Hace tiempo que no escribo en el blog pero es que últimamente ando muy muy liado con los diferentes proyectos que estamos desarrollando en Syderis. Hoy os pongo un pequeño ejemplo de como leer y escribir XML con la API de .NET framework y C#.

Dado el xml:

<?xml version="1.0" encoding="utf-8" ?>
<sample>
<equipments>
   <equipment type="tipo1">
     <point x="1900" y="1000">
       <title>Titulo</title>
       <image >DSCN2903</image>
       <description>Esta es la descripción del primer punto</description>    
     </point>
     <point x="1000" y="2300">
       <title>Titulo</title>
       <image />DSCN2903
       <description>mirador2</description>    
     </point>
   </equipment>
</equipments>
</sample>



Código del lector:


public void Read(string filename)
       {
           XmlDocument xml = new XmlDocument();
           try
           {
               xml.Load(filename);
               XmlNodeList nodeEquipments = xml.GetElementsByTagName("Equipments");

               //Equipamientos
               XmlNodeList equipmentsNodes = ((XmlElement)nodeEquipments[0]).GetElementsByTagName("equipment");
               string sfilename;
               string stitle;
               string sdescription;
               string sx, sy;
               foreach (XmlElement equipment in equipmentsNodes)
               {
                   string stype = equipment.GetAttribute("type");
                   XmlNodeList pointsNodes = equipment.GetElementsByTagName("point");
                            
                          
                   foreach (XmlElement pointNode in pointsNodes)
                   {
                       sx = pointNode.GetAttribute("x");
                       sy = pointNode.GetAttribute("y");
                       stitle = pointNode.GetElementsByTagName("title")[0].InnerText;
                       sfilename = pointNode.GetElementsByTagName("image")[0].InnerText;
                       sdescription = pointNode.GetElementsByTagName("description")[0].InnerText;                      
                       Console.Writeline("type:"+stype+" coord:"+sx+sy+" filename"+sfilename+" title:"stitle+" description:"+sdescription);

                   }
              
               }
          
           }
           catch (XmlException e)
           {
               Console.WriteLine("XML file load Failure." + e.ToString());
           }
}




Código escritor:


public void Write(string filename)
       {
           XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
           xmlWriter.Formatting = Formatting.Indented;
           xmlWriter.WriteStartDocument();

           xmlWriter.WriteStartElement("Sample");

           //Equipments
           xmlWriter.WriteStartElement("Equipments");

           foreach (string etype in equipments.keys)
           {
               xmlWriter.WriteStartElement("equipment");
               xmlWriter.WriteAttributeString("type", etype);

               foreach (Equipment e in equipments[etype])
               {
                   //<point x="100" y="100">
                   xmlWriter.WriteStartElement("point");
                   xmlWriter.WriteAttributeString("x", e.Point.X.ToString());
                   xmlWriter.WriteAttributeString("y", e.Point.Y.ToString());

                   xmlWriter.WriteStartElement("title");
                   xmlWriter.WriteString(e.Title);
                   xmlWriter.WriteEndElement();

                   //<image />filename
                   xmlWriter.WriteStartElement("image");
                   xmlWriter.WriteString(e.Image);
                   xmlWriter.WriteEndElement();

                   //<description>mirador</description>
                   xmlWriter.WriteStartElement("description");
                   xmlWriter.WriteString(e.Description);
                   xmlWriter.WriteEndElement();

                   xmlWriter.WriteEndElement(); // End point
               }
               xmlWriter.WriteEndElement(); //End equipment
           }

           xmlWriter.WriteEndElement(); //End Equipments

           xmlWriter.WriteEndElement(); //End Sample

           xmlWriter.Flush();
           xmlWriter.Close();

       }

martes, 2 de febrero de 2010

Conectarse con el puerto Serie/paralelo desde Java

Bien pues para esta tarea existe una librería llamada Java Comunication API. Pero hay que tener en cuenta que para comunicarte a través de algo físico de la máquina Java nos proporciona una fachada de métodos que por debajo se conectan con diferentes drivers según si estamos corriendo el programa en un windows, macos o linux. Esto quiere decir que además de tener la máquina virtual de java instalada tendrás que instalar un driver en el sistema operativo. Yo empece a trabajar con la implementación de Sun pero me dió muchos problemas y no conseguía que me detectara los drivers instalados, así que finalmente opte por usar una implementación de Java Comunication API open source llamada RXTX. Con ella fue todo rodado por lo que os recomiendo que la useís.

Su página web es http://rxtx.qbang.org/

La instalación es muy simple os bajais la librería en la que os viene:

- RXTXcomm.jar (librería que implementa la especificación de Java Comunication API)
- Directorio con drivers para Linux
- Directorio con drivers para Solaris
- Directorio con drivers para Mac_OS_X
- Directorio con drivers para Windows


Añadis RXTXcomm.jar como librería a vuestro proyecto java y el driver lo meteis en la instalación del jre\bin

Ahora la implementación de una conexión al puerto serie.


public class EjemploRXTX {
    static CommPortIdentifier portId;
    static CommPortIdentifier saveportId;
    static Enumeration  portList;
    static InputStream inputStream;
    static OutputStream outputStream;
    static BufferedInputStream bufferedInputStream;
    static SerialPort  serialPort;
   
   
    public static void main(String[] args){
        boolean gotPort = false;
        String port;
        portList = CommPortIdentifier.getPortIdentifiers();
       
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement(); //get next port to check
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                if ( portId.getName().equals("COM4") ) {
                    port = portId.getName();
                    gotPort = true;
                }
               
                if (gotPort == true) {
                    try {
                        serialPort = (SerialPort)portId.open("SMSSender", 2000);
                    } catch (PortInUseException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        outputStream = serialPort.getOutputStream();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        serialPort.setSerialPortParams(19200,
                                SerialPort.DATABITS_8,
                                SerialPort.STOPBITS_2,
                                SerialPort.PARITY_NONE
                                );
                    } catch (UnsupportedCommOperationException ex) {
                        ex.printStackTrace();
                    }
                   
                    try {
                        inputStream = serialPort.getInputStream();
                        bufferedInputStream = new BufferedInputStream(inputStream);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                   
                    serialPort.notifyOnDataAvailable(true);
                }
            }
        }
       
       //Escribir en el puerto serie
       try {
            if (!(outputStream == null))
                outputStream.write("array de váis que queremos enviar");
           
            byte[] readBuffer = new byte[1];
            boolean read = false;
            while(!read) {
                try {
                    String getInfo = "";
                    Thread.sleep(100);
                    while (bufferedInputStream.available() > 0) {
                        int numBytes = bufferedInputStream.read(readBuffer);
                        getInfo += new String(readBuffer);
                        read = true;
                    }
                    feedback += getInfo;
                    int length = getInfo.length();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        } catch (IOException e){
            e.printStackTrace();
        }
    }



En este ejemplo se usa por debajo una plataforma windows como podéis ver en el nombre del puerto "COM4" en un linux por ejemplo este sería algo como "/dev/ttyS0".

Tambíen para cada caso teneis que tener en cuenta que los datos de conexión con el dispositivo son particulares a cada dispositivo:


serialPort.setSerialPortParams(19200,
                                SerialPort.DATABITS_8,
                                SerialPort.STOPBITS_2,
                                SerialPort.PARITY_NONE
                                );


El dispositivo de este ejemplo trabajaba a 19200 baudios, tamaño de mensaje 8 bits, sin paridad y con el bit de parada 2.

Si ajustais estas cosas ya os debe funcionar para cualquier dispositivo.

Enviar email desde Java 2º parte

Para usar el SMTP de google y nuestra cuenta de gmail tendremos que modificar el ejemplo anterior ya que google usa encriptación por SSL para la autenticación. A continuación el como se haría:


public class Main {
    
    private static final String SMTP_HOST_NAME = "smtp.gmail.com";
    private static final String SMTP_PORT = "465";
    private static final String emailMsgTxt = "Esto sería el mensaje";
    private static final String emailSubjectTxt = "Aqui el asunto";
    private static final String emailFromAddress = "micuenta@gmail.com";
    private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private static final String[] sendTo = { "Email destino"};
    
    
    public static void main(String args[]) throws Exception {
        
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        
        new Main().sendSSLMessage(sendTo, emailSubjectTxt,emailMsgTxt, emailFromAddress);
        System.out.println("Sucessfully Sent mail to All Users");
    }
    
    public void sendSSLMessage(String recipients[], String subject,String message, String from) throws MessagingException {
        boolean debug = true;
        
        Properties props = new Properties();
        props.put("mail.smtp.host", SMTP_HOST_NAME);
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.put("mail.smtp.socketFactory.fallback", "false");
        
        Session session = Session.getDefaultInstance(props,new javax.mail.Authenticator() {
            
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("micuenta@gmail.com", "micontraseñadegmail");
            }
        });
        
        session.setDebug(debug);
        
        Message msg = new MimeMessage(session);
        InternetAddress addressFrom = new InternetAddress(from);
        msg.setFrom(addressFrom);
        
        InternetAddress[] addressTo = new InternetAddress[recipients.length];
        for (int i = 0; i < recipients.length; i++) {
            addressTo[i] = new InternetAddress(recipients[i]);
        }
        msg.setRecipients(Message.RecipientType.TO, addressTo);
        
        
        msg.setSubject(subject);
        
        msg.setText(message);
        Transport.send(msg);
    }
}

Como enviar emails desde Java

Hace ya un tiempo que no escribo en el blog, pero es que últimamente he estado muy muy liado, lo bueno es que he tenido que trabajar en muchos proyectos lo cuál me permitirá escribir unos cuantos tutoriales este més.

Para este primer tutorial he decidido poner un ejemplo de algo que puede parecer una tontería "enviar un correo electrónico desde Java" pero si no encuentra un buen ejemplo en la red puedes pegarte un buen rato.

Lo primero debemos bajarnos la librería JavaMail.jar y activation.jar y añadirlos a nuestro proyecto.


Nota. No preocuparse son dos jar de poco peso.


En principio creamos una clase para el envío de emails:



public class SendMail {
    
    private String from;
    private String to;
    private String subject;
    private String text;
    private ITracer tracer;
    
    public SendMail(String from, String to, String subject, String text){
        this.from = from;
        this.to = to;
        this.subject = subject;
        this.text = text;
        tracer = FileTracer.getInstance();
    }
    
    public void send(){
        
        Properties props = new Properties();
        props.put("mail.smtp.host", "ServidorSMTP");
        props.put("mail.smtp.port", "25"); //Suele ser este puerto
        props.put("mail.smtp.auth", "true");
                
        Session mailSession = Session.getDefaultInstance(props,new javax.mail.Authenticator() {
            
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("UsuarioSMTP",
                                                  "PasswordSMTP");
            }
        });
        
        Message simpleMessage = new MimeMessage(mailSession);
        
        InternetAddress fromAddress = null;
        InternetAddress toAddress = null;
        try {
            fromAddress = new InternetAddress(from);
            toAddress = new InternetAddress(to);
        } catch (AddressException e) {
            tracer.send(ITracer.INFO,e.getMessage());
        }
        
        try {
            simpleMessage.setFrom(fromAddress);
            simpleMessage.setRecipient(RecipientType.TO, toAddress);
            simpleMessage.setSubject(subject);
            simpleMessage.setText(text);
            
            Transport.send(simpleMessage);
            
            tracer.send(ITracer.INFO,"Email enviado a "+toAddress);
        } catch (MessagingException e) {
            tracer.send(ITracer.INFO,e.getMessage());
        }
    }
    
    public void setSubject(String subject)
    {
        this.subject = subject;
    }
    
    public void setText(String message)
    {
        this.text = message;
    }
}



Y por último sólo nos queda usarlo:



SendMail mail = new SendMail("FromEmail",
                                             "ToEmail",
                                             "Asunto",
                                             "Mensaje");
mail.send();



Un saludo y espero que os sea útil ;)

domingo, 27 de septiembre de 2009

Obtener objetos de la session en JSF

Otro de los descubrimientos que he realizado tras trabajar en el último proyecto sobre JSF ha sido obtener instancias de objetos o variables creadas por el contenedor web. Como sabéis todos las clases java que utilices para trabajar con JSF (Backing bean, JavaBean...) deben estar dadas de alta en el faces-config.xml y deben de tener un constructor público sin argumentos. Esto es debido a que el contenedor de aplicaciones web (Tomcat, Glassfish ...) crearán instancias de estas clases para cada session (según el ambito especificado en faces-config.xml), esto plantea algunos problemas al querer usar singleton o simplemente al querer comunicar estas instancias de objetos ya que no existen referencias entre estas clases.

Bien pues desde cualquier clase java puedes escribir las siguientes líneas y obtendrás el valor de los atributos de otra instancia de las clases creadas por el contenedor.

FacesContext fc = FacesContext.getCurrentInstance();

String usr_id = (String)fc.getApplication().createValueBidding("#SessionScope.usr_id").getValue(fc);


Espero que os sea de utilidad a mi me ha venido de perlas.

viernes, 25 de septiembre de 2009

Validator en JSF

Este último més he estado trabajando en una aplicación sobre JSF, una tecnología que bajo mi punto de vista todavía le queda para ser madura, sobre todo por la cantidad de framework que puedes usar pero que luego mezclarlos es un verdadero dolor de cabezas. Despues de investigar ICEFace el cual me gustó mucho, ahora tenías que usar tiles para poder incluyectarle trozos y poder crear plantilla. Total que al final uso MyFaces (implementación de Apache de JSF) con Tomahawk que parece ser el más tolerante.


Entonces he descubierto muchas de las bondades de JSF entre ellas los validadores, unas clases java que te sirven para la validación de campos en los formularios, pudiendote olvidar del javascript. Esto me ha gustado mucho pero me encontre un escoyo que me gustaría ilustrar. Tenía un campo Año que quería validar. Bien pues cree el validador correspondiente:


public void validate(FacesContext facesContext, UIComponent uiComponent, Object object) throws ValidatorException {

try {

int anio = Integer.parseInt(object.toString());

if (anio < 1960 || anio > 2050) {



FacesMessage message = new FacesMessage();

message.setSummary("Año "+anio+" no válido");

throw new ValidatorException(message);

}

} catch (Exception e) {


FacesMessage message = new FacesMessage();

message.setSummary("Año "+object.toString()+" no válido");

throw new ValidatorException(message);

}

}



Y lo dí de alta en el faces-config.xml

<validator>

<validator-id>ValidaAnio</validator-id>

<validator-class>Validadores.ValidaAnio</validator-class>

</validator>

Ahora el problema es que al validar un campo:

<t:outputText id="Anyo" value="Año(aaaa):"/>

<t:inputText id="iAnyo" size="4" maxlength="4" value="#{ActasBusquedaBB.anyo}">

<f:validator validatorId="ValidaAnio"/>

</t:inputText>



pues el campo dentro del formulario se quedaba relleno con el valor erroreo.

Por ejemplo, si en el input anterior introduzco "abcd" como no es un año este falla en el validador
al hacer el casting a entero y sale el mensaje de "Año abcd no válido", pero no se borra el campo del formulario.

La pregunta es ¿ Como hacer desde la clase java ValidaAnio que el campo del formulario se borre si el valor es incorrecto?

Bien pues se hace en 2 lineas pero encontrarlas me costo sangre y por eso la pongo aquí.

public void validate(FacesContext facesContext, UIComponent uiComponent, Object object) throws ValidatorException {

try {

int anio = Integer.parseInt(object.toString());

if (anio < 1960 || anio > 2050) {

if (uiComponent instanceof UIInput)

((UIInput)uiComponent).setSubmittedValue("");

FacesMessage message = new FacesMessage();

message.setSummary("Año "+anio+" no válido");

throw new ValidatorException(message);

}

} catch (Exception e) {

if (uiComponent instanceof UIInput)

((UIInput)uiComponent).setSubmittedValue("");

FacesMessage message = new FacesMessage();

message.setSummary("Año "+object.toString()+" no válido");

throw new ValidatorException(message);

}

}



Espero que os sirva ;)