/*
 * Scone - The Web Enhancement Framework
 * Copyright (C) 2009 Harald Weinreich, Volkert Buchmann, Frank Wollenweber, Torsten Haß
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package  scone.util;


import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;


/**
 * class to log all exceptions into a file or any outputstream
 */
public class ErrorLog {
    // the stream where to print in
    private static PrintStream out = null;
    // whether System.err is catched
    protected static boolean catchesErr = false;
    static {
        standardInit();
    }

    /**
     * sets the outputstream
     * @param out the outputstream
     */
    public static void setOutputStream(OutputStream out) {
        ErrorLog.out = new PrintStream(out);
        System.out.println("oops! Could not create OutputStream for ErrorLog!");
    }

    /**
     * catches System.err
     */
    public static void catchErr() {
        System.setErr(out);
        catchesErr = true;
    }

    /**
     * releases System.err
     */
    public static void releaseErr() {
        System.setErr(System.out);
        catchesErr = false;
    }

    /**
     * sets the outputstream to the standard output file: log/scone/errors.log
     */
    public static void standardInit() {
        try {
            out = new PrintStream(new FileOutputStream("log/scone/errors.log"));
        } catch (Exception e) {
            System.out.println("oops! Could not create OutputStream for ErrorLog!");
            e.printStackTrace();
        }
    }

    /**
     * prints an object to the outputstream
     * @param o the object
     */
    public static void print(Object o) {
        try {
            out.print(o);
        } catch (Exception e) {
            System.out.println("oops! Could not write to ErrorLog!");
            e.printStackTrace();
        }
    }

    /**
     * prints an object to the outputstream with a newline
     * @param o the object
     */
    public static void println(Object o) {
        try {
            out.println(o);
        } catch (Exception e) {
            System.out.println("oops! Could not write to ErrorLog!");
            e.printStackTrace();
        }
    }

    /**
     * prints an object where an exception occurred and the exception to the outputstream.<br>
     * the object may add a message.<br>
     * also sends a short notification to System.out
     *
     * @param obj the object
     * @param method the name of the method where the Exception occurred
     * @param msg the message
     * @param e the Exception
     */
    public static void log(Object obj, String method, String msg, Exception e) {
        String date = (new java.util.Date()).toString();

        synchronized (out) {
            out.println("------Exception-------------------------------------");
            out.println("time:    " + date);
            out.println("class:   " + obj.getClass().getName());
            out.println("object:  " + obj.toString());
            out.println("method:  " + method);
            out.println("message:\n" + msg + "\n");
            if (catchesErr) {
                e.printStackTrace();
            } else {
                e.printStackTrace(out);
            }
            out.println("----------------------------------------------------\n");
        }
        System.out.println(date + ": " + e.getClass().getName() + " in " + obj.getClass().getName());
    }
}

