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