GNU Classpath (0.98) | |
Frames | No Frames |
1: /* System.java -- useful methods to interface with the system 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.lang; 41: 42: import gnu.classpath.SystemProperties; 43: import gnu.classpath.VMStackWalker; 44: 45: import java.io.IOException; 46: import java.io.InputStream; 47: import java.io.PrintStream; 48: import java.nio.channels.Channel; 49: import java.nio.channels.spi.SelectorProvider; 50: import java.util.AbstractCollection; 51: import java.util.Collection; 52: import java.util.Collections; 53: import java.util.HashMap; 54: import java.util.Iterator; 55: import java.util.List; 56: import java.util.Map; 57: import java.util.Set; 58: import java.util.Properties; 59: import java.util.PropertyPermission; 60: 61: /** 62: * System represents system-wide resources; things that represent the 63: * general environment. As such, all methods are static. 64: * 65: * @author John Keiser 66: * @author Eric Blake (ebb9@email.byu.edu) 67: * @since 1.0 68: * @status still missing 1.4 functionality 69: */ 70: public final class System 71: { 72: // WARNING: System is a CORE class in the bootstrap cycle. See the comments 73: // in vm/reference/java/lang/Runtime for implications of this fact. 74: 75: /** 76: * The standard InputStream. This is assigned at startup and starts its 77: * life perfectly valid. Although it is marked final, you can change it 78: * using {@link #setIn(InputStream)} through some hefty VM magic. 79: * 80: * <p>This corresponds to the C stdin and C++ cin variables, which 81: * typically input from the keyboard, but may be used to pipe input from 82: * other processes or files. That should all be transparent to you, 83: * however. 84: */ 85: public static final InputStream in = VMSystem.makeStandardInputStream(); 86: 87: /** 88: * The standard output PrintStream. This is assigned at startup and 89: * starts its life perfectly valid. Although it is marked final, you can 90: * change it using {@link #setOut(PrintStream)} through some hefty VM magic. 91: * 92: * <p>This corresponds to the C stdout and C++ cout variables, which 93: * typically output normal messages to the screen, but may be used to pipe 94: * output to other processes or files. That should all be transparent to 95: * you, however. 96: */ 97: public static final PrintStream out = VMSystem.makeStandardOutputStream(); 98: 99: /** 100: * The standard output PrintStream. This is assigned at startup and 101: * starts its life perfectly valid. Although it is marked final, you can 102: * change it using {@link #setErr(PrintStream)} through some hefty VM magic. 103: * 104: * <p>This corresponds to the C stderr and C++ cerr variables, which 105: * typically output error messages to the screen, but may be used to pipe 106: * output to other processes or files. That should all be transparent to 107: * you, however. 108: */ 109: public static final PrintStream err = VMSystem.makeStandardErrorStream(); 110: 111: /** 112: * A cached copy of the environment variable map. 113: */ 114: private static Map<String,String> environmentMap; 115: 116: /** 117: * This class is uninstantiable. 118: */ 119: private System() 120: { 121: } 122: 123: /** 124: * Set {@link #in} to a new InputStream. This uses some VM magic to change 125: * a "final" variable, so naturally there is a security check, 126: * <code>RuntimePermission("setIO")</code>. 127: * 128: * @param in the new InputStream 129: * @throws SecurityException if permission is denied 130: * @since 1.1 131: */ 132: public static void setIn(InputStream in) 133: { 134: SecurityManager sm = SecurityManager.current; // Be thread-safe. 135: if (sm != null) 136: sm.checkPermission(new RuntimePermission("setIO")); 137: 138: VMSystem.setIn(in); 139: } 140: 141: /** 142: * Set {@link #out} to a new PrintStream. This uses some VM magic to change 143: * a "final" variable, so naturally there is a security check, 144: * <code>RuntimePermission("setIO")</code>. 145: * 146: * @param out the new PrintStream 147: * @throws SecurityException if permission is denied 148: * @since 1.1 149: */ 150: public static void setOut(PrintStream out) 151: { 152: SecurityManager sm = SecurityManager.current; // Be thread-safe. 153: if (sm != null) 154: sm.checkPermission(new RuntimePermission("setIO")); 155: VMSystem.setOut(out); 156: } 157: 158: /** 159: * Set {@link #err} to a new PrintStream. This uses some VM magic to change 160: * a "final" variable, so naturally there is a security check, 161: * <code>RuntimePermission("setIO")</code>. 162: * 163: * @param err the new PrintStream 164: * @throws SecurityException if permission is denied 165: * @since 1.1 166: */ 167: public static void setErr(PrintStream err) 168: { 169: SecurityManager sm = SecurityManager.current; // Be thread-safe. 170: if (sm != null) 171: sm.checkPermission(new RuntimePermission("setIO")); 172: VMSystem.setErr(err); 173: } 174: 175: /** 176: * Set the current SecurityManager. If a security manager already exists, 177: * then <code>RuntimePermission("setSecurityManager")</code> is checked 178: * first. Since this permission is denied by the default security manager, 179: * setting the security manager is often an irreversible action. 180: * 181: * <STRONG>Spec Note:</STRONG> Don't ask me, I didn't write it. It looks 182: * pretty vulnerable; whoever gets to the gate first gets to set the policy. 183: * There is probably some way to set the original security manager as a 184: * command line argument to the VM, but I don't know it. 185: * 186: * @param sm the new SecurityManager 187: * @throws SecurityException if permission is denied 188: */ 189: public static synchronized void setSecurityManager(SecurityManager sm) 190: { 191: // Implementation note: the field lives in SecurityManager because of 192: // bootstrap initialization issues. This method is synchronized so that 193: // no other thread changes it to null before this thread makes the change. 194: if (SecurityManager.current != null) 195: SecurityManager.current.checkPermission 196: (new RuntimePermission("setSecurityManager")); 197: 198: // java.security.Security's class initialiser loads and parses the 199: // policy files. If it hasn't been run already it will be run 200: // during the first permission check. That initialisation will 201: // fail if a very restrictive security manager is in force, so we 202: // preload it here. 203: if (SecurityManager.current == null) 204: { 205: try 206: { 207: Class.forName("java.security.Security"); 208: } 209: catch (ClassNotFoundException e) 210: { 211: } 212: } 213: 214: SecurityManager.current = sm; 215: } 216: 217: /** 218: * Get the current SecurityManager. If the SecurityManager has not been 219: * set yet, then this method returns null. 220: * 221: * @return the current SecurityManager, or null 222: */ 223: public static SecurityManager getSecurityManager() 224: { 225: return SecurityManager.current; 226: } 227: 228: /** 229: * Get the current time, measured in the number of milliseconds from the 230: * beginning of Jan. 1, 1970. This is gathered from the system clock, with 231: * any attendant incorrectness (it may be timezone dependent). 232: * 233: * @return the current time 234: * @see java.util.Date 235: */ 236: public static long currentTimeMillis() 237: { 238: return VMSystem.currentTimeMillis(); 239: } 240: 241: /** 242: * <p> 243: * Returns the current value of a nanosecond-precise system timer. 244: * The value of the timer is an offset relative to some arbitrary fixed 245: * time, which may be in the future (making the value negative). This 246: * method is useful for timing events where nanosecond precision is 247: * required. This is achieved by calling this method before and after the 248: * event, and taking the difference betweent the two times: 249: * </p> 250: * <p> 251: * <code>long startTime = System.nanoTime();</code><br /> 252: * <code>... <emph>event code</emph> ...</code><br /> 253: * <code>long endTime = System.nanoTime();</code><br /> 254: * <code>long duration = endTime - startTime;</code><br /> 255: * </p> 256: * <p> 257: * Note that the value is only nanosecond-precise, and not accurate; there 258: * is no guarantee that the difference between two values is really a 259: * nanosecond. Also, the value is prone to overflow if the offset 260: * exceeds 2^63. 261: * </p> 262: * 263: * @return the time of a system timer in nanoseconds. 264: * @since 1.5 265: */ 266: public static long nanoTime() 267: { 268: return VMSystem.nanoTime(); 269: } 270: 271: /** 272: * Copy one array onto another from <code>src[srcStart]</code> ... 273: * <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ... 274: * <code>dest[destStart+len-1]</code>. First, the arguments are validated: 275: * neither array may be null, they must be of compatible types, and the 276: * start and length must fit within both arrays. Then the copying starts, 277: * and proceeds through increasing slots. If src and dest are the same 278: * array, this will appear to copy the data to a temporary location first. 279: * An ArrayStoreException in the middle of copying will leave earlier 280: * elements copied, but later elements unchanged. 281: * 282: * @param src the array to copy elements from 283: * @param srcStart the starting position in src 284: * @param dest the array to copy elements to 285: * @param destStart the starting position in dest 286: * @param len the number of elements to copy 287: * @throws NullPointerException if src or dest is null 288: * @throws ArrayStoreException if src or dest is not an array, if they are 289: * not compatible array types, or if an incompatible runtime type 290: * is stored in dest 291: * @throws IndexOutOfBoundsException if len is negative, or if the start or 292: * end copy position in either array is out of bounds 293: */ 294: public static void arraycopy(Object src, int srcStart, 295: Object dest, int destStart, int len) 296: { 297: VMSystem.arraycopy(src, srcStart, dest, destStart, len); 298: } 299: 300: /** 301: * Get a hash code computed by the VM for the Object. This hash code will 302: * be the same as Object's hashCode() method. It is usually some 303: * convolution of the pointer to the Object internal to the VM. It 304: * follows standard hash code rules, in that it will remain the same for a 305: * given Object for the lifetime of that Object. 306: * 307: * @param o the Object to get the hash code for 308: * @return the VM-dependent hash code for this Object 309: * @since 1.1 310: */ 311: public static int identityHashCode(Object o) 312: { 313: return VMSystem.identityHashCode(o); 314: } 315: 316: /** 317: * Get all the system properties at once. A security check may be performed, 318: * <code>checkPropertiesAccess</code>. Note that a security manager may 319: * allow getting a single property, but not the entire group. 320: * 321: * <p>The required properties include: 322: * <dl> 323: * <dt>java.version</dt> <dd>Java version number</dd> 324: * <dt>java.vendor</dt> <dd>Java vendor specific string</dd> 325: * <dt>java.vendor.url</dt> <dd>Java vendor URL</dd> 326: * <dt>java.home</dt> <dd>Java installation directory</dd> 327: * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd> 328: * <dt>java.vm.specification.vendor</dt> <dd>VM Spec vendor</dd> 329: * <dt>java.vm.specification.name</dt> <dd>VM Spec name</dd> 330: * <dt>java.vm.version</dt> <dd>VM implementation version</dd> 331: * <dt>java.vm.vendor</dt> <dd>VM implementation vendor</dd> 332: * <dt>java.vm.name</dt> <dd>VM implementation name</dd> 333: * <dt>java.specification.version</dt> <dd>Java Runtime Environment version</dd> 334: * <dt>java.specification.vendor</dt> <dd>Java Runtime Environment vendor</dd> 335: * <dt>java.specification.name</dt> <dd>Java Runtime Environment name</dd> 336: * <dt>java.class.version</dt> <dd>Java class version number</dd> 337: * <dt>java.class.path</dt> <dd>Java classpath</dd> 338: * <dt>java.library.path</dt> <dd>Path for finding Java libraries</dd> 339: * <dt>java.io.tmpdir</dt> <dd>Default temp file path</dd> 340: * <dt>java.compiler</dt> <dd>Name of JIT to use</dd> 341: * <dt>java.ext.dirs</dt> <dd>Java extension path</dd> 342: * <dt>os.name</dt> <dd>Operating System Name</dd> 343: * <dt>os.arch</dt> <dd>Operating System Architecture</dd> 344: * <dt>os.version</dt> <dd>Operating System Version</dd> 345: * <dt>file.separator</dt> <dd>File separator ("/" on Unix)</dd> 346: * <dt>path.separator</dt> <dd>Path separator (":" on Unix)</dd> 347: * <dt>line.separator</dt> <dd>Line separator ("\n" on Unix)</dd> 348: * <dt>user.name</dt> <dd>User account name</dd> 349: * <dt>user.home</dt> <dd>User home directory</dd> 350: * <dt>user.dir</dt> <dd>User's current working directory</dd> 351: * </dl> 352: * 353: * In addition, gnu defines several other properties, where ? stands for 354: * each character in '0' through '9': 355: * <dl> 356: * <dt>gnu.classpath.home</dt> <dd>Path to the classpath libraries.</dd> 357: * <dt>gnu.classpath.version</dt> <dd>Version of the classpath libraries.</dd> 358: * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name; 359: * used for finding property files in file system</dd> 360: * <dt>gnu.classpath.home.url</dt> <dd> Base URL; used for finding 361: * property files in file system</dd> 362: * <dt>gnu.cpu.endian</dt> <dd>big or little</dd> 363: * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt> <dd>8859_?</dd> 364: * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt> <dd>8859_?</dd> 365: * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd> 366: * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd> 367: * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd> 368: * <dt>gnu.java.util.zoneinfo.dir</dt> <dd>Root of zoneinfo tree</dd> 369: * <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd> 370: * </dl> 371: * 372: * @return the system properties, will never be null 373: * @throws SecurityException if permission is denied 374: */ 375: public static Properties getProperties() 376: { 377: SecurityManager sm = SecurityManager.current; // Be thread-safe. 378: if (sm != null) 379: sm.checkPropertiesAccess(); 380: return SystemProperties.getProperties(); 381: } 382: 383: /** 384: * Set all the system properties at once. A security check may be performed, 385: * <code>checkPropertiesAccess</code>. Note that a security manager may 386: * allow setting a single property, but not the entire group. An argument 387: * of null resets the properties to the startup default. 388: * 389: * @param properties the new set of system properties 390: * @throws SecurityException if permission is denied 391: */ 392: public static void setProperties(Properties properties) 393: { 394: SecurityManager sm = SecurityManager.current; // Be thread-safe. 395: if (sm != null) 396: sm.checkPropertiesAccess(); 397: SystemProperties.setProperties(properties); 398: } 399: 400: /** 401: * Get a single system property by name. A security check may be performed, 402: * <code>checkPropertyAccess(key)</code>. 403: * 404: * @param key the name of the system property to get 405: * @return the property, or null if not found 406: * @throws SecurityException if permission is denied 407: * @throws NullPointerException if key is null 408: * @throws IllegalArgumentException if key is "" 409: */ 410: public static String getProperty(String key) 411: { 412: SecurityManager sm = SecurityManager.current; // Be thread-safe. 413: if (sm != null) 414: sm.checkPropertyAccess(key); 415: if (key.length() == 0) 416: throw new IllegalArgumentException("key can't be empty"); 417: return SystemProperties.getProperty(key); 418: } 419: 420: /** 421: * Get a single system property by name. A security check may be performed, 422: * <code>checkPropertyAccess(key)</code>. 423: * 424: * @param key the name of the system property to get 425: * @param def the default 426: * @return the property, or def if not found 427: * @throws SecurityException if permission is denied 428: * @throws NullPointerException if key is null 429: * @throws IllegalArgumentException if key is "" 430: */ 431: public static String getProperty(String key, String def) 432: { 433: SecurityManager sm = SecurityManager.current; // Be thread-safe. 434: if (sm != null) 435: sm.checkPropertyAccess(key); 436: // This handles both the null pointer exception and the illegal 437: // argument exception. 438: if (key.length() == 0) 439: throw new IllegalArgumentException("key can't be empty"); 440: return SystemProperties.getProperty(key, def); 441: } 442: 443: /** 444: * Set a single system property by name. A security check may be performed, 445: * <code>checkPropertyAccess(key, "write")</code>. 446: * 447: * @param key the name of the system property to set 448: * @param value the new value 449: * @return the previous value, or null 450: * @throws SecurityException if permission is denied 451: * @throws NullPointerException if key is null 452: * @throws IllegalArgumentException if key is "" 453: * @since 1.2 454: */ 455: public static String setProperty(String key, String value) 456: { 457: SecurityManager sm = SecurityManager.current; // Be thread-safe. 458: if (sm != null) 459: sm.checkPermission(new PropertyPermission(key, "write")); 460: // This handles both the null pointer exception and the illegal 461: // argument exception. 462: if (key.length() == 0) 463: throw new IllegalArgumentException("key can't be empty"); 464: return SystemProperties.setProperty(key, value); 465: } 466: 467: /** 468: * Remove a single system property by name. A security check may be 469: * performed, <code>checkPropertyAccess(key, "write")</code>. 470: * 471: * @param key the name of the system property to remove 472: * @return the previous value, or null 473: * @throws SecurityException if permission is denied 474: * @throws NullPointerException if key is null 475: * @throws IllegalArgumentException if key is "" 476: * @since 1.5 477: */ 478: public static String clearProperty(String key) 479: { 480: SecurityManager sm = SecurityManager.current; // Be thread-safe. 481: if (sm != null) 482: sm.checkPermission(new PropertyPermission(key, "write")); 483: // This handles both the null pointer exception and the illegal 484: // argument exception. 485: if (key.length() == 0) 486: throw new IllegalArgumentException("key can't be empty"); 487: return SystemProperties.remove(key); 488: } 489: 490: /** 491: * Gets the value of an environment variable. 492: * 493: * @param name the name of the environment variable 494: * @return the string value of the variable or null when the 495: * environment variable is not defined. 496: * @throws NullPointerException 497: * @throws SecurityException if permission is denied 498: * @since 1.5 499: * @specnote This method was deprecated in some JDK releases, but 500: * was restored in 1.5. 501: */ 502: public static String getenv(String name) 503: { 504: if (name == null) 505: throw new NullPointerException(); 506: SecurityManager sm = SecurityManager.current; // Be thread-safe. 507: if (sm != null) 508: sm.checkPermission(new RuntimePermission("getenv." + name)); 509: return VMSystem.getenv(name); 510: } 511: 512: /** 513: * <p> 514: * Returns an unmodifiable view of the system environment variables. 515: * If the underlying system does not support environment variables, 516: * an empty map is returned. 517: * </p> 518: * <p> 519: * The returned map is read-only and does not accept queries using 520: * null keys or values, or those of a type other than <code>String</code>. 521: * Attempts to modify the map will throw an 522: * <code>UnsupportedOperationException</code>, while attempts 523: * to pass in a null value will throw a 524: * <code>NullPointerException</code>. Types other than <code>String</code> 525: * throw a <code>ClassCastException</code>. 526: * </p> 527: * <p> 528: * As the returned map is generated using data from the underlying 529: * platform, it may not comply with the <code>equals()</code> 530: * and <code>hashCode()</code> contracts. It is also likely that 531: * the keys of this map will be case-sensitive. 532: * </p> 533: * <p> 534: * Use of this method may require a security check for the 535: * RuntimePermission "getenv.*". 536: * </p> 537: * 538: * @return a map of the system environment variables. 539: * @throws SecurityException if the checkPermission method of 540: * an installed security manager prevents access to 541: * the system environment variables. 542: * @since 1.5 543: */ 544: public static Map<String, String> getenv() 545: { 546: SecurityManager sm = SecurityManager.current; // Be thread-safe. 547: if (sm != null) 548: sm.checkPermission(new RuntimePermission("getenv.*")); 549: 550: if (environmentMap == null) 551: { 552: Map<String,String> variables = new EnvironmentMap(); 553: List<String> environ = (List<String>)VMSystem.environ(); 554: for (String envEntry : environ) 555: { 556: // avoid broken and null entries 557: if (envEntry != null && !envEntry.endsWith("=")) 558: { 559: // it's perfectly legal that some entries may be in the form 560: // key=value=value=value 561: int equalSignIndex = envEntry.indexOf('='); 562: String key = envEntry.substring(0, equalSignIndex); 563: String value = envEntry.substring(equalSignIndex + 1); 564: variables.put(key, value); 565: } 566: } 567: 568: environmentMap = Collections.unmodifiableMap(variables); 569: } 570: 571: return environmentMap; 572: } 573: 574: /** 575: * Terminate the Virtual Machine. This just calls 576: * <code>Runtime.getRuntime().exit(status)</code>, and never returns. 577: * Obviously, a security check is in order, <code>checkExit</code>. 578: * 579: * @param status the exit status; by convention non-zero is abnormal 580: * @throws SecurityException if permission is denied 581: * @see Runtime#exit(int) 582: */ 583: public static void exit(int status) 584: { 585: Runtime.getRuntime().exit(status); 586: } 587: 588: /** 589: * Calls the garbage collector. This is only a hint, and it is up to the 590: * implementation what this hint suggests, but it usually causes a 591: * best-effort attempt to reclaim unused memory from discarded objects. 592: * This calls <code>Runtime.getRuntime().gc()</code>. 593: * 594: * @see Runtime#gc() 595: */ 596: public static void gc() 597: { 598: Runtime.getRuntime().gc(); 599: } 600: 601: /** 602: * Runs object finalization on pending objects. This is only a hint, and 603: * it is up to the implementation what this hint suggests, but it usually 604: * causes a best-effort attempt to run finalizers on all objects ready 605: * to be reclaimed. This calls 606: * <code>Runtime.getRuntime().runFinalization()</code>. 607: * 608: * @see Runtime#runFinalization() 609: */ 610: public static void runFinalization() 611: { 612: Runtime.getRuntime().runFinalization(); 613: } 614: 615: /** 616: * Tell the Runtime whether to run finalization before exiting the 617: * JVM. This is inherently unsafe in multi-threaded applications, 618: * since it can force initialization on objects which are still in use 619: * by live threads, leading to deadlock; therefore this is disabled by 620: * default. There may be a security check, <code>checkExit(0)</code>. This 621: * calls <code>Runtime.runFinalizersOnExit()</code>. 622: * 623: * @param finalizeOnExit whether to run finalizers on exit 624: * @throws SecurityException if permission is denied 625: * @see Runtime#runFinalizersOnExit(boolean) 626: * @since 1.1 627: * @deprecated never rely on finalizers to do a clean, thread-safe, 628: * mop-up from your code 629: */ 630: public static void runFinalizersOnExit(boolean finalizeOnExit) 631: { 632: Runtime.runFinalizersOnExit(finalizeOnExit); 633: } 634: 635: /** 636: * Load a code file using its explicit system-dependent filename. A security 637: * check may be performed, <code>checkLink</code>. This just calls 638: * <code>Runtime.getRuntime().load(filename)</code>. 639: * 640: * <p> 641: * The library is loaded using the class loader associated with the 642: * class associated with the invoking method. 643: * 644: * @param filename the code file to load 645: * @throws SecurityException if permission is denied 646: * @throws UnsatisfiedLinkError if the file cannot be loaded 647: * @see Runtime#load(String) 648: */ 649: public static void load(String filename) 650: { 651: Runtime.getRuntime().load(filename, VMStackWalker.getCallingClassLoader()); 652: } 653: 654: /** 655: * Load a library using its explicit system-dependent filename. A security 656: * check may be performed, <code>checkLink</code>. This just calls 657: * <code>Runtime.getRuntime().load(filename)</code>. 658: * 659: * <p> 660: * The library is loaded using the class loader associated with the 661: * class associated with the invoking method. 662: * 663: * @param libname the library file to load 664: * @throws SecurityException if permission is denied 665: * @throws UnsatisfiedLinkError if the file cannot be loaded 666: * @see Runtime#load(String) 667: */ 668: public static void loadLibrary(String libname) 669: { 670: Runtime.getRuntime().loadLibrary(libname, 671: VMStackWalker.getCallingClassLoader()); 672: } 673: 674: /** 675: * Convert a library name to its platform-specific variant. 676: * 677: * @param libname the library name, as used in <code>loadLibrary</code> 678: * @return the platform-specific mangling of the name 679: * @since 1.2 680: */ 681: public static String mapLibraryName(String libname) 682: { 683: return VMRuntime.mapLibraryName(libname); 684: } 685: 686: /** 687: * Returns the inherited channel of the VM. 688: * 689: * This wraps the inheritedChannel() call of the system's default 690: * {@link SelectorProvider}. 691: * 692: * @return the inherited channel of the VM 693: * 694: * @throws IOException If an I/O error occurs 695: * @throws SecurityException If an installed security manager denies access 696: * to RuntimePermission("inheritedChannel") 697: * 698: * @since 1.5 699: */ 700: public static Channel inheritedChannel() 701: throws IOException 702: { 703: return SelectorProvider.provider().inheritedChannel(); 704: } 705: 706: /** 707: * This is a specialised <code>Collection</code>, providing 708: * the necessary provisions for the collections used by the 709: * environment variable map. Namely, it prevents 710: * querying anything but <code>String</code>s. 711: * 712: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 713: */ 714: private static class EnvironmentCollection 715: extends AbstractCollection<String> 716: { 717: 718: /** 719: * The wrapped collection. 720: */ 721: protected Collection<String> c; 722: 723: /** 724: * Constructs a new environment collection, which 725: * wraps the elements of the supplied collection. 726: * 727: * @param coll the collection to use as a base for 728: * this collection. 729: */ 730: public EnvironmentCollection(Collection<String> coll) 731: { 732: c = coll; 733: } 734: 735: /** 736: * Blocks queries containing a null object or an object which 737: * isn't of type <code>String</code>. All other queries 738: * are forwarded to the underlying collection. 739: * 740: * @param obj the object to look for. 741: * @return true if the object exists in the collection. 742: * @throws NullPointerException if the specified object is null. 743: * @throws ClassCastException if the specified object is not a String. 744: */ 745: public boolean contains(Object obj) 746: { 747: if (obj == null) 748: throw new 749: NullPointerException("This collection does not support " + 750: "null values."); 751: if (!(obj instanceof String)) 752: throw new 753: ClassCastException("This collection only supports Strings."); 754: return c.contains(obj); 755: } 756: 757: /** 758: * Blocks queries where the collection contains a null object or 759: * an object which isn't of type <code>String</code>. All other 760: * queries are forwarded to the underlying collection. 761: * 762: * @param coll the collection of objects to look for. 763: * @return true if the collection contains all elements in the collection. 764: * @throws NullPointerException if the collection is null. 765: * @throws NullPointerException if any collection entry is null. 766: * @throws ClassCastException if any collection entry is not a String. 767: */ 768: public boolean containsAll(Collection<?> coll) 769: { 770: for (Object o: coll) 771: { 772: if (o == null) 773: throw new 774: NullPointerException("This collection does not support " + 775: "null values."); 776: if (!(o instanceof String)) 777: throw new 778: ClassCastException("This collection only supports Strings."); 779: } 780: return c.containsAll(coll); 781: } 782: 783: /** 784: * This returns an iterator over the map elements, with the 785: * same provisions as for the collection and underlying map. 786: * 787: * @return an iterator over the map elements. 788: */ 789: public Iterator<String> iterator() 790: { 791: return c.iterator(); 792: } 793: 794: /** 795: * Blocks the removal of elements from the collection. 796: * 797: * @return true if the removal was sucessful. 798: * @throws NullPointerException if the collection is null. 799: * @throws NullPointerException if any collection entry is null. 800: * @throws ClassCastException if any collection entry is not a String. 801: */ 802: public boolean remove(Object key) 803: { 804: if (key == null) 805: throw new 806: NullPointerException("This collection does not support " + 807: "null values."); 808: if (!(key instanceof String)) 809: throw new 810: ClassCastException("This collection only supports Strings."); 811: return c.contains(key); 812: } 813: 814: /** 815: * Blocks the removal of all elements in the specified 816: * collection from the collection. 817: * 818: * @param coll the collection of elements to remove. 819: * @return true if the elements were removed. 820: * @throws NullPointerException if the collection is null. 821: * @throws NullPointerException if any collection entry is null. 822: * @throws ClassCastException if any collection entry is not a String. 823: */ 824: public boolean removeAll(Collection<?> coll) 825: { 826: for (Object o: coll) 827: { 828: if (o == null) 829: throw new 830: NullPointerException("This collection does not support " + 831: "null values."); 832: if (!(o instanceof String)) 833: throw new 834: ClassCastException("This collection only supports Strings."); 835: } 836: return c.removeAll(coll); 837: } 838: 839: /** 840: * Blocks the retention of all elements in the specified 841: * collection from the collection. 842: * 843: * @param coll the collection of elements to retain. 844: * @return true if the other elements were removed. 845: * @throws NullPointerException if the collection is null. 846: * @throws NullPointerException if any collection entry is null. 847: * @throws ClassCastException if any collection entry is not a String. 848: */ 849: public boolean retainAll(Collection<?> coll) 850: { 851: for (Object o: coll) 852: { 853: if (o == null) 854: throw new 855: NullPointerException("This collection does not support " + 856: "null values."); 857: if (!(o instanceof String)) 858: throw new 859: ClassCastException("This collection only supports Strings."); 860: } 861: return c.containsAll(coll); 862: } 863: 864: /** 865: * This simply calls the same method on the wrapped 866: * collection. 867: * 868: * @return the size of the underlying collection. 869: */ 870: public int size() 871: { 872: return c.size(); 873: } 874: 875: } // class EnvironmentCollection<String> 876: 877: /** 878: * This is a specialised <code>HashMap</code>, which 879: * prevents the addition or querying of anything other than 880: * <code>String</code> objects. 881: * 882: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 883: */ 884: static class EnvironmentMap 885: extends HashMap<String,String> 886: { 887: 888: /** 889: * Cache the entry set. 890: */ 891: private transient Set<Map.Entry<String,String>> entries; 892: 893: /** 894: * Cache the key set. 895: */ 896: private transient Set<String> keys; 897: 898: /** 899: * Cache the value collection. 900: */ 901: private transient Collection<String> values; 902: 903: /** 904: * Constructs a new empty <code>EnvironmentMap</code>. 905: */ 906: EnvironmentMap() 907: { 908: super(); 909: } 910: 911: /** 912: * Constructs a new <code>EnvironmentMap</code> containing 913: * the contents of the specified map. 914: * 915: * @param m the map to be added to this. 916: * @throws NullPointerException if a key or value is null. 917: * @throws ClassCastException if a key or value is not a String. 918: */ 919: EnvironmentMap(Map<String,String> m) 920: { 921: super(m); 922: } 923: 924: /** 925: * Blocks queries containing a null key or one which is not 926: * of type <code>String</code>. All other queries 927: * are forwarded to the superclass. 928: * 929: * @param key the key to look for in the map. 930: * @return true if the key exists in the map. 931: * @throws NullPointerException if the specified key is null. 932: */ 933: public boolean containsKey(Object key) 934: { 935: if (key == null) 936: throw new 937: NullPointerException("This map does not support null keys."); 938: if (!(key instanceof String)) 939: throw new 940: ClassCastException("This map only allows queries using Strings."); 941: return super.containsKey(key); 942: } 943: 944: /** 945: * Blocks queries using a null or non-<code>String</code> value. 946: * All other queries are forwarded to the superclass. 947: * 948: * @param value the value to look for in the map. 949: * @return true if the value exists in the map. 950: * @throws NullPointerException if the specified value is null. 951: */ 952: public boolean containsValue(Object value) 953: { 954: if (value == null) 955: throw new 956: NullPointerException("This map does not support null values."); 957: if (!(value instanceof String)) 958: throw new 959: ClassCastException("This map only allows queries using Strings."); 960: return super.containsValue(value); 961: } 962: 963: /** 964: * Returns a set view of the map entries, with the same 965: * provisions as for the underlying map. 966: * 967: * @return a set containing the map entries. 968: */ 969: public Set<Map.Entry<String,String>> entrySet() 970: { 971: if (entries == null) 972: entries = super.entrySet(); 973: return entries; 974: } 975: 976: /** 977: * Blocks queries containing a null or non-<code>String</code> key. 978: * All other queries are passed on to the superclass. 979: * 980: * @param key the key to retrieve the value for. 981: * @return the value associated with the given key. 982: * @throws NullPointerException if the specified key is null. 983: * @throws ClassCastException if the specified key is not a String. 984: */ 985: public String get(Object key) 986: { 987: if (key == null) 988: throw new 989: NullPointerException("This map does not support null keys."); 990: if (!(key instanceof String)) 991: throw new 992: ClassCastException("This map only allows queries using Strings."); 993: return super.get(key); 994: } 995: 996: /** 997: * Returns a set view of the keys, with the same 998: * provisions as for the underlying map. 999: * 1000: * @return a set containing the keys. 1001: */ 1002: public Set<String> keySet() 1003: { 1004: if (keys == null) 1005: keys = new EnvironmentSet(super.keySet()); 1006: return keys; 1007: } 1008: 1009: /** 1010: * Associates the given key to the given value. If the 1011: * map already contains the key, its value is replaced. 1012: * The map does not accept null keys or values, or keys 1013: * and values not of type {@link String}. 1014: * 1015: * @param key the key to map. 1016: * @param value the value to be mapped. 1017: * @return the previous value of the key, or null if there was no mapping 1018: * @throws NullPointerException if a key or value is null. 1019: * @throws ClassCastException if a key or value is not a String. 1020: */ 1021: public String put(String key, String value) 1022: { 1023: if (key == null) 1024: throw new NullPointerException("A new key is null."); 1025: if (value == null) 1026: throw new NullPointerException("A new value is null."); 1027: if (!(key instanceof String)) 1028: throw new ClassCastException("A new key is not a String."); 1029: if (!(value instanceof String)) 1030: throw new ClassCastException("A new value is not a String."); 1031: return super.put(key, value); 1032: } 1033: 1034: /** 1035: * Removes a key-value pair from the map. The queried key may not 1036: * be null or of a type other than a <code>String</code>. 1037: * 1038: * @param key the key of the entry to remove. 1039: * @return the removed value. 1040: * @throws NullPointerException if the specified key is null. 1041: * @throws ClassCastException if the specified key is not a String. 1042: */ 1043: public String remove(Object key) 1044: { 1045: if (key == null) 1046: throw new 1047: NullPointerException("This map does not support null keys."); 1048: if (!(key instanceof String)) 1049: throw new 1050: ClassCastException("This map only allows queries using Strings."); 1051: return super.remove(key); 1052: } 1053: 1054: /** 1055: * Returns a collection view of the values, with the same 1056: * provisions as for the underlying map. 1057: * 1058: * @return a collection containing the values. 1059: */ 1060: public Collection<String> values() 1061: { 1062: if (values == null) 1063: values = new EnvironmentCollection(super.values()); 1064: return values; 1065: } 1066: 1067: } 1068: 1069: /** 1070: * This is a specialised <code>Set</code>, providing 1071: * the necessary provisions for the collections used by the 1072: * environment variable map. Namely, it prevents 1073: * modifications and the use of queries with null 1074: * or non-<code>String</code> values. 1075: * 1076: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 1077: */ 1078: private static class EnvironmentSet 1079: extends EnvironmentCollection 1080: implements Set<String> 1081: { 1082: 1083: /** 1084: * Constructs a new environment set, which 1085: * wraps the elements of the supplied set. 1086: * 1087: * @param set the set to use as a base for 1088: * this set. 1089: */ 1090: public EnvironmentSet(Set<String> set) 1091: { 1092: super(set); 1093: } 1094: 1095: /** 1096: * This simply calls the same method on the wrapped 1097: * collection. 1098: * 1099: * @param obj the object to compare with. 1100: * @return true if the two objects are equal. 1101: */ 1102: public boolean equals(Object obj) 1103: { 1104: return c.equals(obj); 1105: } 1106: 1107: /** 1108: * This simply calls the same method on the wrapped 1109: * collection. 1110: * 1111: * @return the hashcode of the collection. 1112: */ 1113: public int hashCode() 1114: { 1115: return c.hashCode(); 1116: } 1117: 1118: } // class EnvironmentSet<String> 1119: 1120: } // class System
GNU Classpath (0.98) |