/*
 * Fichero:     FicheroLog.java
 * Fecha:       20/10/06
 * Autor:       Alvaro Sarmiento Losada
 * Asignatura:  Proyecto Fin de Carrera
 * Descripción: Contiene la clase FicheroLog, que implementa una bitácora
 *              sobre un archivo.
 *
 * Este fichero pertenece al proyecto fin de carrera del autor,
 * consistente en el estudio de JXTA y su aplicación al comercio 
 * electrónico b2b.
 */

package com.pfc.lib.utiles;

import java.io.FileWriter;
import java.io.IOException;

/**
 * Clase que implementa un "log" o bitácora de propósito general. Puede ser útil
 * para anotar sucesos o eventos ocurridos en la ejecución de una aplicación 
 * y el posterior análisis de dichos eventos,  La extensión del archivo 
 * resultante es implícitamente ".log"<br><br>
 * <b>Nota:</b>
 * <i>Un objeto de esta clase puede ser usado por varios hilos o aplicaciones 
 * a la vez, pudiendo usarse un mismo objeto <code>FicheroLog</code> para 
 * varios métodos de una misma aplicación, por ejemplo.</i>
 *
 * @author  Alvaro Sarmiento Losada
 */
public class Log extends Object {
    
    /** El nombre (ruta) del archivo log */
    private String nombreFichero;
    
    /** 
     * Constante que indica la extensión del archivo usado como log. En esta
     * implementación se usa ".log" . 
     */
    private final String EXTENSION = ".log";
    
    /**
     * Constructor de la clase. Inicializa un objeto de la clase que representa
     * un log o bitácora y usa un archivo para escribir las anotaciones 
     * especificado por el nombre o ruta.
     *
     * @param nombre  el nombre del archivo (sin extensión) que se desea usar
     *                como log. El archivo se creará en el directorio de 
     *                trabajo. Se puede especificar una ruta.
     */ 
    public Log(String nombre) {
        nombreFichero = nombre + EXTENSION;
    }
    
    /**
     * Devuelve el nombre (ruta) del archivo usado como log de este objeto 
     * incluyendo la extensión del archivo.
     *
     * @return el nombre (ruta) del archivo usado para las anotaciones.
     */
    public String getNombreArchivo() {
        return nombreFichero;
    }
    
    /**
     * Realiza una anotación en el log a modo de apertura o "nueva página", 
     * delimitado por una línea de caracteres "*" y la fecha y hora de la
     * apertura en formato ISO8601.
     */
    public void iniciar() {
        escribir("\n\n*****************************************************\n");
        escribir("Log abierto en:" + FechaISO8601.fechaISO() + "\n");
    }
    
    /**
     * Realiza una anotación en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     * @param error el fallo que se ha producido 
     */
    public void apuntar(String error) {
        escribir( FechaISO8601.fechaISO() + ": " + error + "\n");
    }
    
    /**
     * Realiza una anotación de registro en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void registra() {
        escribir( FechaISO8601.fechaISO() + ": se ha registrado un objeto" + "\n");
    }
    
    /**
     * Realiza una anotación de búsqueda en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void busqueda() {
        escribir( FechaISO8601.fechaISO() + ": se ha realizado una busqueda en la base de datos" + "\n");
    }
    
    /**
     * Realiza una anotación de eliminación en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void elimina() {
        escribir( FechaISO8601.fechaISO() + ": se ha eliminado un elemento de la base de datos" + "\n");
    }
    
    /**
     * Realiza una anotación de eliminación en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void peticionNoRealizada() {
        escribir( FechaISO8601.fechaISO() + ": no ha podido realizarse la petición" + "\n");
    }
    
    /**
     * Realiza una anotación de compra en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void compra() {
        escribir( FechaISO8601.fechaISO() + ": se ha realizado la compra de un producto" + "\n");
    }
    
    /**
     * Realiza una anotación de venta en la bitácora, que será precedida de la fecha 
     * y hora en formato ISO8601. Cada nueva anotación se hace automáticamente
     * en una nueva línea del fichero usado como log.
     *
     */
    public void venta() {
        escribir( FechaISO8601.fechaISO() + ": se ha ejecutado la venta de un producto" + "\n");
    }
    
    /**
     * Escribe en el fichero usado como log un texto dado por 
     * <code>anotacion</code>. Este método permite que varios hilos puedan
     * escribir sobre un mismo objeto <code>FicheroLog</code> simultáneamente.
     *
     * @param anotacion el texto que se quiere apuntar en la bitacora.
     */
    protected synchronized void escribir(String anotacion) {
        /*
         * Para evitar que dos o más hilos lleguen a esta zona crítica
         * simultáneamente, se ha declarado este método como 
         * <code>synchronized</code>.
         */
        try {
            //Se abre un flujo asociado al fichero de log
            FileWriter flujo = new FileWriter(nombreFichero, true);
            //Se escribe el mensaje en el archivo
            flujo.write(anotacion);
            /* 
             * Se cierra el flujo asociado al fichero de log. Esto permite
             * que el archivo pueda ser utilizado por otros hilos a la vez.
             */
            flujo.close();
        } catch (IOException ioe) { }        
    }
    
}