1 /* 2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt; 27 28 import java.io.*; 29 30 import java.util.*; 31 import sun.util.logging.PlatformLogger; 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 */ 74 public final class DebugSettings { 75 private static final PlatformLogger log = PlatformLogger.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 final DebugSettings instance = new DebugSettings(); 91 92 private final Properties props = new Properties(); 93 94 static synchronized void init() { 95 if (!instance.props.isEmpty()) { 96 return; 97 } 98 NativeLibLoader.loadLibraries(); 99 instance.loadProperties(); 100 instance.loadNativeSettings(); 101 } 102 103 public static DebugSettings getInstance() { 104 return instance; 105 } 106 107 /* 108 * Load debug properties from file, then override 109 * with any command line specified properties 110 */ 111 private synchronized void loadProperties() { 112 // setup initial properties 113 java.security.AccessController.doPrivileged( 114 new java.security.PrivilegedAction<Void>() { 115 public Void run() { 116 loadDefaultProperties(); 117 loadFileProperties(); 118 loadSystemProperties(); 119 return null; 120 } 121 }); 122 123 // echo the initial property settings to stdout 124 if (log.isLoggable(PlatformLogger.Level.FINE)) { 125 log.fine("DebugSettings:\n{0}", this); 126 } 127 } 128 129 public String toString() { 130 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 131 PrintStream pout = new PrintStream(bout); 132 for (String key : props.stringPropertyNames()) { 133 String value = props.getProperty(key, ""); 134 pout.println(key + " = " + value); 135 } 136 return new String(bout.toByteArray()); 137 } 138 139 /* 140 * Sets up default property values 141 */ 142 @SuppressWarnings("deprecation") 143 private void loadDefaultProperties() { 144 // is there a more inefficient way to setup default properties? 145 // maybe, but this has got to be close to 100% non-optimal 146 try { 147 for ( int nprop = 0; nprop < DEFAULT_PROPS.length; nprop++ ) { 148 StringBufferInputStream in = new StringBufferInputStream(DEFAULT_PROPS[nprop]); 149 props.load(in); 150 in.close(); 151 } 152 } catch(IOException ioe) { 153 } 154 } 155 156 /* 157 * load properties from file, overriding defaults 158 */ 159 private void loadFileProperties() { 160 String propPath; 161 Properties fileProps; 162 163 // check if the user specified a particular settings file 164 propPath = System.getProperty(PREFIX + "." + PROP_FILE, ""); 165 if (propPath.equals("")) { 166 // otherwise get it from the user's home directory 167 propPath = System.getProperty("user.home", "") + 168 File.separator + 169 PREFIX + "." + PROP_FILE; 170 } 171 172 File propFile = new File(propPath); 173 try { 174 println("Reading debug settings from '" + propFile.getCanonicalPath() + "'..."); 175 FileInputStream fin = new FileInputStream(propFile); 176 props.load(fin); 177 fin.close(); 178 } catch ( FileNotFoundException fne ) { 179 println("Did not find settings file."); 180 } catch ( IOException ioe ) { 181 println("Problem reading settings, IOException: " + ioe.getMessage()); 182 } 183 } 184 185 /* 186 * load properties from system props (command line spec'd usually), 187 * overriding default or file properties 188 */ 189 private void loadSystemProperties() { 190 // override file properties with system properties 191 Properties sysProps = System.getProperties(); 192 for (String key : sysProps.stringPropertyNames()) { 193 String value = sysProps.getProperty(key,""); 194 // copy any "awtdebug" properties over 195 if ( key.startsWith(PREFIX) ) { 196 props.setProperty(key, value); 197 } 198 } 199 } 200 201 /** 202 * Gets named boolean property 203 * @param key Name of property 204 * @param defval Default value if property does not exist 205 * @return boolean value of the named property 206 */ 207 public synchronized boolean getBoolean(String key, boolean defval) { 208 String value = getString(key, String.valueOf(defval)); 209 return value.equalsIgnoreCase("true"); 210 } 211 212 /** 213 * Gets named integer property 214 * @param key Name of property 215 * @param defval Default value if property does not exist 216 * @return integer value of the named property 217 */ 218 public synchronized int getInt(String key, int defval) { 219 String value = getString(key, String.valueOf(defval)); 220 return Integer.parseInt(value); 221 } 222 223 /** 224 * Gets named String property 225 * @param key Name of property 226 * @param defval Default value if property does not exist 227 * @return string value of the named property 228 */ 229 public synchronized String getString(String key, String defval) { 230 String actualKeyName = PREFIX + "." + key; 231 String value = props.getProperty(actualKeyName, defval); 232 //println(actualKeyName+"="+value); 233 return value; 234 } 235 236 private synchronized List<String> getPropertyNames() { 237 List<String> propNames = new LinkedList<>(); 238 // remove global prefix from property names 239 for (String propName : props.stringPropertyNames()) { 240 propName = propName.substring(PREFIX.length()+1); 241 propNames.add(propName); 242 } 243 return propNames; 244 } 245 246 private void println(Object object) { 247 if (log.isLoggable(PlatformLogger.Level.FINER)) { 248 log.finer(object.toString()); 249 } 250 } 251 252 private static final String PROP_CTRACE = "ctrace"; 253 private static final int PROP_CTRACE_LEN = PROP_CTRACE.length(); 254 255 private native synchronized void setCTracingOn(boolean enabled); 256 private native synchronized void setCTracingOn(boolean enabled, String file); 257 private native synchronized void setCTracingOn(boolean enabled, String file, int line); 258 259 private void loadNativeSettings() { 260 boolean ctracingOn; 261 262 ctracingOn = getBoolean(PROP_CTRACE, false); 263 setCTracingOn(ctracingOn); 264 265 // 266 // Filter out file/line ctrace properties from debug settings 267 // 268 List<String> traces = new LinkedList<>(); 269 270 for (String key : getPropertyNames()) { 271 if (key.startsWith(PROP_CTRACE) && key.length() > PROP_CTRACE_LEN) { 272 traces.add(key); 273 } 274 } 275 276 // sort traces list so file-level traces will be before line-level ones 277 Collections.sort(traces); 278 279 // 280 // Setup the trace points 281 // 282 for (String key : traces) { 283 String trace = key.substring(PROP_CTRACE_LEN+1); 284 String filespec; 285 String linespec; 286 int delim= trace.indexOf('@'); 287 boolean enabled; 288 289 // parse out the filename and linenumber from the property name 290 filespec = delim != -1 ? trace.substring(0, delim) : trace; 291 linespec = delim != -1 ? trace.substring(delim+1) : ""; 292 enabled = getBoolean(key, false); 293 //System.out.println("Key="+key+", File="+filespec+", Line="+linespec+", Enabled="+enabled); 294 295 if ( linespec.length() == 0 ) { 296 // set file specific trace setting 297 setCTracingOn(enabled, filespec); 298 } else { 299 // set line specific trace setting 300 int linenum = Integer.parseInt(linespec, 10); 301 setCTracingOn(enabled, filespec, linenum); 302 } 303 } 304 } 305 }