001/*
002 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved.
003 *
004 * http://www.izforge.com/izpack/
005 * http://developer.berlios.de/projects/izpack/
006 *
007 * Copyright 2002 Jan Blok
008 *
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *     http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 */
021package com.izforge.izpack.util;
022
023import com.izforge.izpack.installer.Installer;
024
025import java.io.BufferedWriter;
026import java.io.File;
027import java.io.FileOutputStream;
028import java.io.OutputStreamWriter;
029import java.io.PrintWriter;
030
031import java.util.Date;
032import java.util.Enumeration;
033import java.util.Properties;
034
035
036/**
037 * This class is for debug purposes. It is highly recommended to use it on critical or
038 * experimental code places. To enable the debug mode of IzPack, just start the
039 * installer  with the java parameter -DTRACE=true or -DSTACKTRACE=true to enable
040 * extendend output of the internal status of critical objects. <br>
041 * How to use it as IzPack Setup Developer: <br>
042 * Just import this class and use one of the methods:
043 * 
044 * <dl>
045 * <dt>
046 * Debug.trace( aCriticalObject )
047 * </dt>
048 * <dd>
049 * - to print the status on console
050 * </dd>
051 * <dt>
052 * Debug.error( aCriticalObject )
053 * </dt>
054 * <dd>
055 * - to print the status on console and<br>
056 * print the stacktrace of a supressed Exception.
057 * </dd>
058 * <dt>
059 * Additionally:
060 * </dt>
061 * <dd>
062 * if -DLOG is given the output will be written in the File see #LOGFILENAME in the users
063 * Home directory.
064 * </dd>
065 * </dl>
066 * 
067 *
068 * @author Julien Ponge, Klaus Bartz, Marc Eppelmann
069 * @version $Revision: 1.8 $ ($Id: Debug.java,v 1.8 2005/08/26 08:28:47 eppelman Exp $)
070 */
071public class Debug
072{
073  //~ Static fields/initializers *********************************************************
074
075  /**
076   * Parameter for public javacall "java -jar izpack.jar -DLOG" (Class.internal.variable:
077   * (DLOG = "LOG"))
078   */
079  public static final String DLOG = "LOG";
080
081  /**
082   * Parameter for public javacall "java -jar izpack.jar -DSTACKTRACE"
083   * (Class.internal.variable: (DSTACKTRACE = "STACKTRACE"))
084   */
085  public static final String DSTACKTRACE = "STACKTRACE";
086
087  /**
088   * Parameter for public javacall "java -jar izpack.jar -DTRACE"
089   * (Class.internal.variable: (DTRACE = "TRACE"))
090   */
091  public static final String DTRACE = "TRACE";
092
093  /** System.Property Key: IZPACK_LOGFILE = "izpack.logfile" */
094  public static final String IZPACK_LOGFILE = "izpack.logfile";
095
096  /** internally initial unintialized TRACE-flag */
097  private static boolean TRACE;
098
099  /** internal initial unintialized STACKTRACE-flag */
100  private static boolean STACKTRACE;
101
102  /** internal initial unintialized LOG-flag */
103  private static boolean LOG;
104
105  /** LOGFILE_PREFIX = "IzPack_Logfile_at_" */
106  public static String LOGFILE_PREFIX = "IzPack_Logfile_at_";
107
108  /** LOGFILE_EXTENSION = ".txt" */
109  public static String LOGFILE_EXTENSION = ".txt";
110
111  /** LOGFILENAME = LOGFILE_PREFIX + System.currentTimeMillis() + LOGFILE_EXTENSION */
112  public static String LOGFILENAME = LOGFILE_PREFIX + System.currentTimeMillis(  ) +
113                                     LOGFILE_EXTENSION;
114
115  /** internal used File writer */
116  private static BufferedWriter fw;
117
118  /** internal used Printfile writer */
119  private static PrintWriter logfile;
120
121  /**
122   * The log initializion bloc.
123   */
124  static
125  {
126    boolean st = false;
127
128    try
129    {
130      st = Boolean.getBoolean( DSTACKTRACE );
131    }
132    catch( Exception ex )
133    {
134      // ignore
135    }
136
137    STACKTRACE = st;
138
139    boolean log = false;
140
141    try
142    {
143      log = Boolean.getBoolean( DLOG );
144    }
145    catch( Exception ex )
146    {
147      // ignore
148    }
149
150    LOG = log;
151
152    boolean t = false;
153
154    try
155    {
156      if( STACKTRACE )
157      {
158        t = true;
159      }
160      else
161      {
162        t = Boolean.getBoolean( DTRACE );
163      }
164    }
165    catch( Exception ex )
166    {
167      // ignore
168    }
169
170    TRACE = t;
171
172    if( LOG )
173    {
174      System.out.println( DLOG + " enabled." );
175      logfile = createLogFile(  );
176
177      Debug.log( Installer.class.getName(  ) + " LogFile created at " +
178                 new Date( System.currentTimeMillis(  ) ) );
179
180      //** write some runtime system properties into the logfile **
181      Debug.log( "System.Properties:" );
182
183      Properties  sysProps = System.getProperties(  );
184
185      Enumeration spe = sysProps.keys(  );
186
187      while( spe.hasMoreElements(  ) )
188      {
189        String aKey = (String) spe.nextElement(  );
190        Debug.log( aKey + "  =  " + sysProps.getProperty( aKey ) );
191      }
192      Debug.log( "\n==========================================\n" );
193      Debug.log( "\n " + Installer.class.getName(  )+ " installs on: \n" );
194      Debug.log( OsVersion.getOsDetails() );
195      Debug.log( "\n==========================================\n" );
196    }
197
198    if( TRACE )
199    {
200      System.out.println( DTRACE + " enabled." );
201    }
202
203    if( STACKTRACE )
204    {
205      System.out.println( DSTACKTRACE + " enabled." );
206    }
207  }
208
209  //~ Methods ****************************************************************************
210
211  /** 
212   * Traces the internal status of the given Object
213   *
214   * @param s
215   */
216  public static void trace( Object s )
217  {
218    if( TRACE )
219    {
220      // console.println(s.toString());
221      System.out.println( s );
222
223      if( STACKTRACE && ( s instanceof Throwable ) )
224      {
225        // StringWriter sw = new StringWriter();
226        // PrintWriter pw = new PrintWriter(sw);
227        // ((Throwable)s).printStackTrace(pw);
228        // console.println(sw.toString());
229        ( (Throwable) s ).printStackTrace(  );
230      }
231
232      System.out.flush(  );
233    }
234  }
235
236  /** 
237   * Traces the given object and additional write their status in the LOGFILE.
238   *
239   * @param s
240   */
241  public static void error( Object s )
242  {
243    trace( s );
244    System.err.println( s );
245    System.err.flush(  );
246    log( s );
247  }
248
249  /** 
250   * Logs the given Object in the created Logfile if -DLOG=true was given on commandline
251   * i.e: java -DLOG=true -jar izpack-installer.jar
252   *
253   * @param o The Object to log
254   */
255  public static void log( Object o )
256  {
257    //if LOG was given 
258    if( LOG == true )
259    {
260      if( ( logfile = getLogFile(  ) ) == null )
261      {
262        logfile = createLogFile(  );
263      }
264
265      if( logfile != null )
266      {
267        if( o == null )
268        {
269          o = "null";
270        }
271
272        logfile.println( o );
273
274        if( o instanceof Throwable )
275        {
276          ( (Throwable) o ).printStackTrace( logfile );
277        }
278
279        logfile.flush(  );
280
281        //logfile.close();
282        //logFile = null;
283      }
284      else
285      {
286        System.err.println( "Cannot write into logfile: (" + logfile + ") <- '" + o +
287                            "'" );
288      }
289    }
290  }
291
292  /** 
293   * Creates the logfile to write log-infos into.
294   *
295   * @return The writer object instance
296   */
297  private static PrintWriter createLogFile(  )
298  {
299    String tempDir = System.getProperty( "java.io.tmpdir" );
300
301    File   tempDirFile = new File( tempDir );
302
303    try
304    {
305      tempDirFile.mkdirs(  );
306    }
307    catch( RuntimeException e1 )
308    {
309      e1.printStackTrace(  );
310    }
311
312    String logfilename = LOGFILENAME;
313    System.out.println( "creating Logfile: '" + logfilename + "' in: '" + tempDir + "'" );
314
315    File out = new File( tempDir, logfilename );
316
317    if( tempDirFile.canWrite(  ) )
318    {
319      try
320      {
321        fw      = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( out ),
322                                                              "UTF-8" ) );
323        logfile = setLogFile( new PrintWriter( fw ) );
324      }
325      catch( Exception e )
326      {
327        logfile = null;
328        e.printStackTrace(  );
329      }
330    }
331    else
332    {
333      logfile = null;
334      System.err.println( "Fatal: cannot write File: '" + logfilename + "' into: " +
335                          tempDirFile );
336    }
337
338    return logfile;
339  }
340
341  /** 
342   * Indicates if debug is tracing
343   *
344   * @return true if tracing otherwise false
345   */
346  public static boolean tracing(  )
347  {
348    return TRACE;
349  }
350
351  /** 
352   * Indicates if debug is stacktracing
353   *
354   * @return true if stacktracing otherwise false
355   */
356  public static boolean stackTracing(  )
357  {
358    return STACKTRACE;
359  }
360
361  /** 
362   * Returns the LOG flag.
363   *
364   * @return Returns the LOG flag.
365   */
366  public static boolean isLOG(  )
367  {
368    return LOG;
369  }
370
371  /** 
372   * Sets The LOG like the given value
373   *
374   * @param aFlag The LOG status to set to or not.
375   */
376  public static void setLOG( boolean aFlag )
377  {
378    System.out.println( DLOG + " = " + aFlag );
379    LOG = aFlag;
380  }
381
382  /** 
383   * Returns the current STACKTRACE flag
384   *
385   * @return Returns the STACKTRACE.
386   */
387  public static boolean isSTACKTRACE(  )
388  {
389    return STACKTRACE;
390  }
391
392  /** 
393   * Sets the STACKTRACE like the given value
394   *
395   * @param aFlag The STACKTRACE to set / unset.
396   */
397  public static void setSTACKTRACE( boolean aFlag )
398  {
399    System.out.println( DSTACKTRACE + " = " + aFlag );
400    STACKTRACE = aFlag;
401  }
402
403  /** 
404   * Gets the current TRACE flag
405   *
406   * @return Returns the TRACE.
407   */
408  public static boolean isTRACE(  )
409  {
410    return TRACE;
411  }
412
413  /** 
414   * Sets the TRACE flag like the given value
415   *
416   * @param aFlag The TRACE to set / unset.
417   */
418  public static void setTRACE( boolean aFlag )
419  {
420    System.out.println( DTRACE + " = " + aFlag );
421    TRACE = aFlag;
422  }
423
424  /** 
425   * Get the Logfile
426   *
427   * @return Returns the logFile.
428   */
429  public static PrintWriter getLogFile(  )
430  {
431    logfile = (PrintWriter) System.getProperties(  ).get( IZPACK_LOGFILE );
432
433    return logfile;
434  }
435
436  /** 
437   * Sets the Logfile
438   *
439   * @param aLogFile The logFile to set.   * 
440   * @return The logfile to write into
441   */
442  public static synchronized PrintWriter setLogFile( PrintWriter aLogFile )
443  {
444    System.getProperties(  ).put( IZPACK_LOGFILE, aLogFile );
445
446    logfile = (PrintWriter) System.getProperties(  ).get( IZPACK_LOGFILE );
447
448    if( logfile == null )
449    {
450      System.err.println( "Set::logfile == null" );
451    }
452
453    return logfile;
454  }
455}