/* * Copyright (C) 2000 - 2008 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ */ package com.nary; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.io.Serializable; import java.io.StringWriter; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import java.util.zip.Deflater; import java.util.zip.Inflater; import javax.servlet.ServletContext; import org.apache.commons.vfs.FileObject; import com.naryx.tagfusion.cfm.engine.cfEngine; /** * This is a simple Debugging class that can be used to generate a log file of all * errors. Currently it logs to a file called debug.txt, from where ever the Java * application is run from. */ public final class Debug extends Object implements Serializable{ private static final long serialVersionUID = 1L; private RandomAccessFile OutFile = null; private boolean bOn = true; private boolean bSystemOut = true; private boolean bFile = true; private String filename = "debug.txt"; private static Debug newInstance = null; private ServletContext servletContext = null; private long logFileSize = 0; private long maxLogFileSize = 25000000; //- default to 25MB private Debug(){} /** * This method sets file name to a specifed file name. * * @param _file The specified file name */ public static void setFilename( String _file ){ checkCurrentInstance(); newInstance.intSetFilename( _file ); } private void intSetFilename( String _file ){ filename = _file; try{ if ( OutFile != null ) OutFile.close(); }catch(Exception E){} OutFile = null; } /** * Sets a flag to true to indecate a active status. */ public static void On(){ checkCurrentInstance(); newInstance.bOn=true; } /** * Sets a flag to false to indecate a idel status. */ public static void Off(){ checkCurrentInstance(); newInstance.bOn=false; } /** * Sets flag to true to show that the system is active. */ public static void SystemOn(){ checkCurrentInstance(); newInstance.bSystemOut=true; } /** * Sets the flag to false to show the system is closed. */ public static void SystemOff(){ checkCurrentInstance(); newInstance.bSystemOut=false; } /** * Set the flag to true to show the file is open or exists. */ public static void FileOn(){ checkCurrentInstance(); newInstance.bFile = true; } /** * Sets the flag to false to show that the file is closed or not exist. */ public static void FileOff(){ checkCurrentInstance(); newInstance.bFile = false; } public static void setServletLogging( ServletContext _servletContext ){ checkCurrentInstance(); newInstance.servletContext = _servletContext; } public static void setRotationSize( long maxLogFileSize ){ checkCurrentInstance(); newInstance.maxLogFileSize = maxLogFileSize; } /** * This method open the system for printing, after finish printing, set system to close status. * * @param t * @param Line */ public static void println( boolean t, String Line ){ checkCurrentInstance(); newInstance.intPrintln( t, Line ); } private void intPrintln( boolean t, String Line ){ bSystemOut = true; intPrintln( Line ); bSystemOut = false; } public static void println( boolean t, Exception E ){ checkCurrentInstance(); newInstance.intPrintln( t, E ); } private void intPrintln( boolean t, Exception E ){ bSystemOut = true; intPrintln( E.toString() ); bSystemOut = false; } /** * print out error message. * * @param E */ public static void println( Exception E ){ checkCurrentInstance(); newInstance.intPrintln( E.toString() ); } /** * This method takes in a Throwable object, and print out stack trace for this object. * * @param E The specified object */ public static void printStackTrace( Throwable t ){ checkCurrentInstance(); newInstance.intPrintStackTrace( t ); } public static String getStackTraceAsString( Throwable t ){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); t.printStackTrace(pw); pw.close(); return sw.toString(); } /** * This method generates and prints a stack trace. */ public static void printStackTrace( ){ try{ throw new Exception(); }catch(Exception e ){ printStackTrace( e ); } } private void intPrintStackTrace( Throwable E ){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); E.printStackTrace(pw); pw.close(); intPrintln( sw.toString() ); } /** * Instead print debug message to the debug.txt file, this method allows to print out debug message * to a specified file. * * @ _logFile The file name that you want to print message to. * @ _Line The message that you want to print to the file. */ public static void println( Object _object ){ checkCurrentInstance(); if ( _object != null ) newInstance.intPrintln( _object.toString() ); } /** * This method prints all the elements in a Hashtable printing each * key:value pair on a new line * * @param _hashtable The Hashtable to go through */ public static void println( Hashtable _hashtable ){ checkCurrentInstance(); if ( _hashtable == null ) return; Enumeration E = _hashtable.keys(); while ( E.hasMoreElements() ){ String key = (String)E.nextElement(); Debug.println( "KEY=[" + key + "] DATA=[" + _hashtable.get( key ) + "]" ); } } /** * This method prints all the elements in a Vector marking each with * the index it's at. * * @param _vector The Vector to go through */ public static void println( Vector<Object> _vector ){ checkCurrentInstance(); if ( _vector == null ) return; Enumeration<Object> E = _vector.elements(); int x = 0; while ( E.hasMoreElements() ){ newInstance.intPrintln( "element[" + (x++) + "]=" + E.nextElement() ); } } /** * This method prints an array of ints, marking each array element with * the index it's at. * * @param _array The array of ints to print */ public static void println( int [] _array ){ checkCurrentInstance(); if ( _array == null ) return; for ( int x = 0; x < _array.length; x++ ) newInstance.intPrintln("index[" + x + "]=" + _array[x] ); } /** * This method prints an array of chars, marking each array element with * the index it's at. * * @param _array The array of chars to print */ public static void println( char [] _array ){ checkCurrentInstance(); if ( _array == null ) return; for ( int x = 0; x < _array.length; x++ ) newInstance.intPrintln("index[" + x + "]:" + _array[x] ); } /** * This method prints an array of bytes, marking each array element with * the index it's at. * * @param _array The array of bytes to print */ public static void println( byte [] _array ){ checkCurrentInstance(); if ( _array == null ) return; for ( int x = 0; x < _array.length; x++ ) newInstance.intPrintln("index[" + x + "]=" + _array[x] ); } /** * This method print debug record to consoel, speecifed file and to client. * All of the above methods eventually call this method * * @param Line The string needs to be print out. */ public synchronized static void println( String Line ){ checkCurrentInstance(); newInstance.intPrintln( Line ); } private void intPrintln( String Line ){ if ( !bOn ) return; String D = com.nary.util.Date.formatNow( "dd/MM/yy HH:mm.ss: " ) + Line; //--[ Write it out to the System Console if ( bSystemOut ) System.out.println( D ); //--[ Write it out to the Servlet Log if ( servletContext != null ) servletContext.log( Line ); D += "\r\n"; //--[ Write it out to file if ( bFile ){ try{ if ( OutFile == null ){ //-- Log file is closed; lets open it up if ( filename == null ) { return; // we're screwed--give up } OutFile = new RandomAccessFile( filename, "rw" ); logFileSize = OutFile.length(); OutFile.seek( logFileSize ); OutFile.writeBytes( "\r\n]--- Logging Started ------[\r\n" ); } //-- Write out the line to the logfile OutFile.writeBytes( D ); logFileSize += D.length(); if ( logFileSize > maxLogFileSize ) rotateLogFile(); }catch(IOException E){ if ( OutFile != null ){ try{ OutFile.close(); } catch(IOException ignore){} } OutFile = null; } } } /** * This method will rotate the log file, renaming it to another */ private void rotateLogFile() { try{ OutFile.writeBytes( "\r\n\r\n--- Log file rotated ---" ); OutFile.close(); //- rename the old file to a new one int x = 1; File newFile = new File( filename + "." + x ); while ( newFile.exists() ){ newFile = new File( filename + "." + (x++) ); } //- Rename the old file new File( filename ).renameTo( newFile ); //- Delete the old one new File( filename ).delete(); }catch(IOException ignoreException){ //- the rotation failed; so lets just reset the current file } OutFile = null; } public static void saveClass( String _filename, Object _class ){ saveClass( _filename, _class, false ); } public static void saveClass( String _filename, Object _class, boolean _compress ){ BufferedOutputStream FS = null; try{ FS = new BufferedOutputStream( cfEngine.thisPlatform.getFileIO().getFileOutputStream( new File(_filename) ), 32000 ); saveClass( FS, _class, _compress ); }catch(Throwable E){ }finally{ try{ if ( FS != null ) FS.close(); }catch( IOException ignored ){} } } public static void saveClass( OutputStream _out, Object _class, boolean _compress ) throws IOException{ if ( _compress ){ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream OOS = new ObjectOutputStream(bos); OOS.writeObject( _class ); byte [] dataArray = bos.toByteArray(); byte [] test = new byte[ dataArray.length ]; // this is where the byte array gets compressed to Deflater def = new Deflater( Deflater.BEST_COMPRESSION ); def.setInput( dataArray ); def.finish(); def.deflate( test ); _out.write( test, 0, def.getTotalOut() ); }else{ ObjectOutputStream OS = new ObjectOutputStream(_out); OS.writeObject( _class ); } } /** * This method read a specified class object from a specifed file * and return this object. * * @param _filename the spcifed file */ public static Object loadClass(FileObject fileobject) { InputStream fis = null; try{ fis = fileobject.getContent().getInputStream(); return loadClass( fis, false ); }catch(Exception E){ return null; }finally{ try{ if ( fis != null ) fis.close(); }catch( Exception ignored ){} } } public static Object loadClass( String _filename ){ return loadClass( _filename, false); } public static Object loadClass( String _filename, boolean _uncompress ){ FileInputStream fis = null; try{ fis = new FileInputStream( _filename ); return loadClass( fis, _uncompress ); }catch(Exception E){ return null; }finally{ try{ if ( fis != null ) fis.close(); }catch( Exception ignored ){} } } public static Object loadClass( InputStream _inStream ){ return loadClass( _inStream, false ); } public static Object loadClass( InputStream _inStream, boolean _uncompress ){ ObjectInputStream ois; try{ if ( _uncompress ){ // we need to get the input as a byte [] so we can decompress (inflate) it. Inflater inflater = new Inflater(); ByteArrayOutputStream bos; int bytesAvail = _inStream.available(); if ( bytesAvail > 0 ){ bos = new ByteArrayOutputStream( bytesAvail ); }else{ bos = new ByteArrayOutputStream(); } byte [] buffer = new byte[1024]; int read = _inStream.read( buffer ); while( read > 0 ){ bos.write( buffer, 0, read ); read = _inStream.read( buffer ); } bos.flush(); inflater.setInput( bos.toByteArray() ); bos.reset(); buffer = new byte[1024]; int inflated = inflater.inflate( buffer ); while( inflated > 0 ){ bos.write( buffer, 0, inflated ); inflated = inflater.inflate( buffer ); } bos.flush(); ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() ); ois = new ObjectInputStream( bis ); }else{ ois = new ObjectInputStream(_inStream); } return ois.readObject(); }catch(Exception E){ return null; }finally{ try{_inStream.close();}catch(Exception ioe){} } } private static void checkCurrentInstance(){ if ( newInstance != null ) return; newInstance = new Debug(); } }