1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.util; 25 26 import java.io.BufferedWriter; 27 import java.io.IOException; 28 import java.io.FileWriter; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.io.OutputStreamWriter; 32 import java.io.PrintWriter; 33 import java.io.Writer; 34 import java.text.DateFormat; 35 import java.util.Date; 36 import java.util.Calendar; 37 import java.util.Properties; 38 39 /** 40 * This class is used for logging debug messages. 41 * Currently, there are three types of logging: {@link #INFO}, 42 * {@link #TRACE} & {@link #ERROR}. Use the Debug.properties 43 * file to set or unset each type. Also use Debug.properties 44 * to set the writer to either <code>System.out</code>, 45 * <code>System.err</code>, or to a file. 46 * 47 * @author Herbie Ong 48 */ 49 public final class Debug { 50 51 /** Informational messages. */ 52 public final static int INFO = 0x0001; 53 /** Error messages. */ 54 public final static int ERROR = 0x0002; 55 /** Trace messages. */ 56 public final static int TRACE = 0x0004; 57 58 /** To set a flag. */ 59 public final static boolean SET = true; 60 /** To unset a flag. */ 61 public final static boolean UNSET = false; 62 63 private static int flags = 0; 64 private static PrintWriter writer = null; 65 66 static { 67 68 try { 69 70 Class c = new Debug().getClass(); 71 InputStream is = c.getResourceAsStream("Debug.properties"); 72 Properties props = new Properties(); 73 props.load(is); 74 75 String info = props.getProperty("debug.info", "false"); 76 info = info.toLowerCase(); 77 78 if (info.equals("true")) { setFlags(Debug.INFO, Debug.SET)79 setFlags(Debug.INFO, Debug.SET); 80 } 81 82 String trace = props.getProperty("debug.trace", "false"); 83 trace = trace.toLowerCase(); 84 85 if (trace.equals("true")) { setFlags(Debug.TRACE, Debug.SET)86 setFlags(Debug.TRACE, Debug.SET); 87 } 88 89 String error = props.getProperty("debug.error", "false"); 90 error = error.toLowerCase(); 91 92 if (error.equals("true")) { setFlags(Debug.ERROR, Debug.SET)93 setFlags(Debug.ERROR, Debug.SET); 94 } 95 96 String w = props.getProperty("debug.output", "System.out"); 97 setOutput(w); 98 99 } catch (Throwable ex) { 100 101 ex.printStackTrace(System.err); 102 } 103 } 104 105 106 /** 107 * Private constructor so as not to allow any instances 108 * of this class. This serves as a singleton class. 109 */ Debug()110 private Debug() { 111 } 112 113 114 /** 115 * Set the output to the specified argument. 116 * This method is only used internally to prevent 117 * invalid string parameters. 118 * 119 * @param str Output specifier. 120 */ setOutput(String str)121 private static void setOutput(String str) { 122 123 if (writer == null) { 124 125 if (str.equals("System.out")) { 126 127 setOutput(System.out); 128 129 } else if (str.equals("System.err")) { 130 131 setOutput(System.err); 132 133 } else { 134 135 try { 136 137 setOutput(new FileWriter(str)); 138 139 } catch (IOException e) { 140 141 e.printStackTrace(System.err); 142 } 143 } 144 } 145 } 146 147 148 /** 149 * Set the output to an <code>OutputStream</code> object. 150 * 151 * @param stream OutputStream object. 152 */ setOutput(OutputStream stream)153 private static void setOutput(OutputStream stream) { 154 155 setOutput(new OutputStreamWriter(stream)); 156 } 157 158 159 /** 160 * Set the <code>Writer</code> object to manage the output. 161 * 162 * @param w <code>Writer</code> object to write out. 163 */ setOutput(Writer w)164 private static void setOutput(Writer w) { 165 166 if (writer != null) { 167 168 writer.close(); 169 } 170 171 writer = new PrintWriter(new BufferedWriter(w), true); 172 } 173 174 175 /** 176 * <p> 177 * This method sets the levels for debugging logs. 178 * Example calls: 179 * </p> 180 * 181 * <blockquote><pre><code> 182 * Debug.setFlags( Debug.INFO, Debug.SET ) 183 * Debug.setFlags( Debug.TRACE, Debug.SET ) 184 * Debug.setFlags( Debug.INFO | Debug.TRACE, Debug.SET ) 185 * Debug.setFlags( Debug.ERROR, Debug.UNSET ) 186 * </code></pre></blockquote> 187 * 188 * @param f Debug flag 189 * @param set Use Debug.SET to set, and Debug.UNSET to unset 190 * the given flag. 191 */ setFlags(int f, boolean set)192 private static void setFlags(int f, boolean set) { 193 194 if (set) { 195 flags |= f; 196 } else { 197 flags &= ~f; 198 } 199 } 200 201 202 /** 203 * Prints out information regarding platform. 204 */ logSystemInfo()205 public static void logSystemInfo() { 206 207 if (writer != null) { 208 209 writer.println(); 210 writer.println("Platform Information:"); 211 writer.println("OS : " + System.getProperty("os.name")); 212 writer.println("Version : " + System.getProperty("os.version")); 213 writer.println("Platform : " + System.getProperty("os.arch")); 214 writer.println("JDK Version : " + System.getProperty("java.version")); 215 writer.println("JDK Vendor : " + System.getProperty("java.vendor")); 216 writer.println(); 217 } 218 } 219 220 221 /** 222 * Prints out timestamp. 223 */ logTime()224 public static void logTime() { 225 226 if (writer != null) { 227 228 Date time = Calendar.getInstance().getTime(); 229 DateFormat dt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); 230 writer.println(dt.format(time)); 231 } 232 } 233 234 235 /** 236 * Checks if flag is set. 237 * 238 * @return true if info logging is on, otherwise false 239 */ isFlagSet(int f)240 public static boolean isFlagSet(int f) { 241 242 return ((flags & f) != 0); 243 } 244 245 246 /** 247 * <p>Log message based on the flag type.</p> 248 * 249 * <p>Example 1:</p> 250 * 251 * <blockquote><pre><code> 252 * Debug.log(Debug.INFO, "info string here"); 253 * </code></pre></blockquote> 254 * 255 * <p>This logs the message during runtime if 256 * <code>debug.info</code> in the properties file is 257 * set to true.</p> 258 * 259 * <p>Example 2:</p> 260 * 261 * <blockquote><pre><code> 262 * Debug.log(Debug.INFO | Debug.TRACE, "info string here"); 263 * </code></pre></blockquote> 264 * 265 * <p>This logs the message during runtime if debug.info or debug.trace 266 * in the properties file is set to true.</p> 267 * 268 * @param flag Log type, one of the Debug constants 269 * {@link #INFO}, {@link #TRACE}, {@link #ERROR} 270 * or a combination of which or'ed together. 271 * @param msg The message. 272 */ log(int flag, String msg)273 public static void log(int flag, String msg) { 274 275 if (isFlagSet(flag)) { 276 277 if (writer != null) { 278 279 writer.println(msg); 280 } 281 } 282 } 283 284 285 /** 286 * Log message based on flag type plus print out stack trace 287 * of the exception passed in. Refer to the other log method 288 * for description. 289 * 290 * @param flag Log type, one of the Debug constants 291 * {@link #INFO}, {@link #TRACE}, {@link #ERROR} 292 * or a combination of which or'ed together. 293 * @param msg The message. 294 * @param e Throwable object. 295 */ log(int flag, String msg, Throwable e)296 public static void log(int flag, String msg, Throwable e) { 297 298 if (isFlagSet(flag)) { 299 300 if (writer != null) { 301 302 writer.println(msg); 303 if (e != null) 304 e.printStackTrace(writer); 305 } 306 } 307 } 308 309 310 /** 311 * Converts the given bytes to a <code>String</code> of 312 * Hex digits. 313 * 314 * @param bytes <code>byte</code> array. 315 * 316 * @return Hex representation in a <code>String</code>. 317 */ byteArrayToHexString(byte bytes[])318 public static String byteArrayToHexString(byte bytes[]) { 319 320 StringBuffer buff = new StringBuffer(); 321 322 for (int i = 0; i < bytes.length; i++) { 323 324 int ch = ((int) bytes[i] & 0xff); 325 String str = Integer.toHexString(ch); 326 if (str.length() < 2) 327 buff.append('0'); 328 buff.append(str); 329 buff.append(' '); 330 } 331 332 return buff.toString(); 333 } 334 } 335 336