blob: 0d2aaaf62519e90d5412487271f891ea33ae22fd [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt;
27
28import java.io.*;
29
30import java.util.*;
31import java.util.logging.*;
32
33/*
34 * Internal class that manages sun.awt.Debug settings.
35 * Settings can be specified on a global, per-package,
36 * or per-class level.
37 *
38 * Properties affecting the behaviour of the Debug class are
39 * loaded from the awtdebug.properties file at class load
40 * time. The properties file is assumed to be in the
41 * user.home directory. A different file can be used
42 * by setting the awtdebug.properties system property.
43 * e.g. java -Dawtdebug.properties=foo.properties
44 *
45 * Only properties beginning with 'awtdebug' have any
46 * meaning-- all other properties are ignored.
47 *
48 * You can override the properties file by specifying
49 * 'awtdebug' props as system properties on the command line.
50 * e.g. java -Dawtdebug.trace=true
51 * Properties specific to a package or a class can be set
52 * by qualifying the property names as follows:
53 * awtdebug.<property name>.<class or package name>
54 * So for example, turning on tracing in the com.acme.Fubar
55 * class would be done as follows:
56 * awtdebug.trace.com.acme.Fubar=true
57 *
58 * Class settings always override package settings, which in
59 * turn override global settings.
60 *
61 * Addition from July, 2007.
62 *
63 * After the fix for 4638447 all the usage of DebugHelper
64 * classes in Java code are replaced with the corresponding
65 * Java Logging API calls. This file is now used only to
66 * control native logging.
67 *
68 * To enable native logging you should set the following
69 * system property to 'true': sun.awt.nativedebug. After
70 * the native logging is enabled, the actual debug settings
71 * are read the same way as described above (as before
72 * the fix for 4638447).
73 */
74final class DebugSettings {
75 private static final Logger log = Logger.getLogger("sun.awt.debug.DebugSettings");
76
77 /* standard debug property key names */
78 static final String PREFIX = "awtdebug";
79 static final String PROP_FILE = "properties";
80
81 /* default property settings */
82 private static final String DEFAULT_PROPS[] = {
83 "awtdebug.assert=true",
84 "awtdebug.trace=false",
85 "awtdebug.on=true",
86 "awtdebug.ctrace=false"
87 };
88
89 /* global instance of the settings object */
90 private static DebugSettings instance = null;
91
92 private Properties props = new Properties();
93
94 static void init() {
95 if (instance != null) {
96 return;
97 }
98
99 NativeLibLoader.loadLibraries();
100 instance = new DebugSettings();
101 instance.loadNativeSettings();
102 }
103
104 private DebugSettings() {
105 new java.security.PrivilegedAction() {
106 public Object run() {
107 loadProperties();
108 return null;
109 }
110 }.run();
111 }
112
113 /*
114 * Load debug properties from file, then override
115 * with any command line specified properties
116 */
117 private synchronized void loadProperties() {
118 // setup initial properties
119 java.security.AccessController.doPrivileged(
120 new java.security.PrivilegedAction()
121 {
122 public Object run() {
123 loadDefaultProperties();
124 loadFileProperties();
125 loadSystemProperties();
126 return null;
127 }
128 });
129
130 // echo the initial property settings to stdout
131 if (log.isLoggable(Level.FINE)) {
132 log.log(Level.FINE, "DebugSettings:\n{0}", this);
133 }
134 }
135
136 public String toString() {
137 Enumeration enum_ = props.propertyNames();
138 ByteArrayOutputStream bout = new ByteArrayOutputStream();
139 PrintStream pout = new PrintStream(bout);
140
141 while (enum_.hasMoreElements()) {
142 String key = (String)enum_.nextElement();
143 String value = props.getProperty(key, "");
144 pout.println(key + " = " + value);
145 }
146 return new String(bout.toByteArray());
147 }
148
149 /*
150 * Sets up default property values
151 */
152 private void loadDefaultProperties() {
153 // is there a more inefficient way to setup default properties?
154 // maybe, but this has got to be close to 100% non-optimal
155 try {
156 for ( int nprop = 0; nprop < DEFAULT_PROPS.length; nprop++ ) {
157 StringBufferInputStream in = new StringBufferInputStream(DEFAULT_PROPS[nprop]);
158 props.load(in);
159 in.close();
160 }
161 } catch(IOException ioe) {
162 }
163 }
164
165 /*
166 * load properties from file, overriding defaults
167 */
168 private void loadFileProperties() {
169 String propPath;
170 Properties fileProps;
171
172 // check if the user specified a particular settings file
173 propPath = System.getProperty(PREFIX + "." + PROP_FILE, "");
174 if (propPath.equals("")) {
175 // otherwise get it from the user's home directory
176 propPath = System.getProperty("user.home", "") +
177 File.separator +
178 PREFIX + "." + PROP_FILE;
179 }
180
181 File propFile = new File(propPath);
182 try {
183 println("Reading debug settings from '" + propFile.getCanonicalPath() + "'...");
184 FileInputStream fin = new FileInputStream(propFile);
185 props.load(fin);
186 fin.close();
187 } catch ( FileNotFoundException fne ) {
188 println("Did not find settings file.");
189 } catch ( IOException ioe ) {
190 println("Problem reading settings, IOException: " + ioe.getMessage());
191 }
192 }
193
194 /*
195 * load properties from system props (command line spec'd usually),
196 * overriding default or file properties
197 */
198 private void loadSystemProperties() {
199 // override file properties with system properties
200 Properties sysProps = System.getProperties();
201 Enumeration enum_ = sysProps.propertyNames();
202 while ( enum_.hasMoreElements() ) {
203 String key = (String)enum_.nextElement();
204 String value = sysProps.getProperty(key,"");
205 // copy any "awtdebug" properties over
206 if ( key.startsWith(PREFIX) ) {
207 props.setProperty(key, value);
208 }
209 }
210 }
211
212 /**
213 * Gets named boolean property
214 * @param key Name of property
215 * @param defval Default value if property does not exist
216 * @return boolean value of the named property
217 */
218 public synchronized boolean getBoolean(String key, boolean defval) {
219 String value = getString(key, String.valueOf(defval));
220 return value.equalsIgnoreCase("true");
221 }
222
223 /**
224 * Gets named integer property
225 * @param key Name of property
226 * @param defval Default value if property does not exist
227 * @return integer value of the named property
228 */
229 public synchronized int getInt(String key, int defval) {
230 String value = getString(key, String.valueOf(defval));
231 return Integer.parseInt(value);
232 }
233
234 /**
235 * Gets named String property
236 * @param key Name of property
237 * @param defval Default value if property does not exist
238 * @return string value of the named property
239 */
240 public synchronized String getString(String key, String defval) {
241 String actualKeyName = PREFIX + "." + key;
242 String value = props.getProperty(actualKeyName, defval);
243 //println(actualKeyName+"="+value);
244 return value;
245 }
246
247 public synchronized Enumeration getPropertyNames() {
248 Vector propNames = new Vector();
249 Enumeration enum_ = props.propertyNames();
250
251 // remove global prefix from property names
252 while ( enum_.hasMoreElements() ) {
253 String propName = (String)enum_.nextElement();
254 propName = propName.substring(PREFIX.length()+1);
255 propNames.addElement(propName);
256 }
257 return propNames.elements();
258 }
259
260 private void println(Object object) {
261 if (log.isLoggable(Level.FINER)) {
262 log.log(Level.FINER, object.toString());
263 }
264 }
265
266 private static final String PROP_CTRACE = "ctrace";
267 private static final int PROP_CTRACE_LEN = PROP_CTRACE.length();
268
269 private native synchronized void setCTracingOn(boolean enabled);
270 private native synchronized void setCTracingOn(boolean enabled, String file);
271 private native synchronized void setCTracingOn(boolean enabled, String file, int line);
272
273 private void loadNativeSettings() {
274 boolean ctracingOn;
275
276 ctracingOn = getBoolean(PROP_CTRACE, false);
277 setCTracingOn(ctracingOn);
278
279 //
280 // Filter out file/line ctrace properties from debug settings
281 //
282 Vector traces = new Vector();
283 Enumeration enum_ = getPropertyNames();
284
285 while ( enum_.hasMoreElements() ) {
286 String key = (String)enum_.nextElement();
287 if ( key.startsWith(PROP_CTRACE) && key.length() > PROP_CTRACE_LEN ) {
288 traces.addElement(key);
289 }
290 }
291
292 // sort traces list so file-level traces will be before line-level ones
293 Collections.sort(traces);
294
295 //
296 // Setup the trace points
297 //
298 Enumeration enumTraces = traces.elements();
299
300 while ( enumTraces.hasMoreElements() ) {
301 String key = (String)enumTraces.nextElement();
302 String trace = key.substring(PROP_CTRACE_LEN+1);
303 String filespec;
304 String linespec;
305 int delim= trace.indexOf('@');
306 boolean enabled;
307
308 // parse out the filename and linenumber from the property name
309 filespec = delim != -1 ? trace.substring(0, delim) : trace;
310 linespec = delim != -1 ? trace.substring(delim+1) : "";
311 enabled = getBoolean(key, false);
312 //System.out.println("Key="+key+", File="+filespec+", Line="+linespec+", Enabled="+enabled);
313
314 if ( linespec.length() == 0 ) {
315 // set file specific trace setting
316 setCTracingOn(enabled, filespec);
317 } else {
318 // set line specific trace setting
319 int linenum = Integer.parseInt(linespec, 10);
320 setCTracingOn(enabled, filespec, linenum);
321 }
322 }
323 }
324}