GNU Classpath (0.95) | |
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: if (environmentMap == null) 550: { 551: List<String> environ = (List<String>)VMSystem.environ(); 552: Map<String,String> variables = new EnvironmentMap(); 553: for (String pair : environ) 554: { 555: String[] parts = pair.split("="); 556: if (parts.length == 2) 557: variables.put(parts[0], parts[1]); 558: else 559: variables.put(parts[0], ""); 560: } 561: environmentMap = Collections.unmodifiableMap(variables); 562: } 563: return environmentMap; 564: } 565: 566: /** 567: * Terminate the Virtual Machine. This just calls 568: * <code>Runtime.getRuntime().exit(status)</code>, and never returns. 569: * Obviously, a security check is in order, <code>checkExit</code>. 570: * 571: * @param status the exit status; by convention non-zero is abnormal 572: * @throws SecurityException if permission is denied 573: * @see Runtime#exit(int) 574: */ 575: public static void exit(int status) 576: { 577: Runtime.getRuntime().exit(status); 578: } 579: 580: /** 581: * Calls the garbage collector. This is only a hint, and it is up to the 582: * implementation what this hint suggests, but it usually causes a 583: * best-effort attempt to reclaim unused memory from discarded objects. 584: * This calls <code>Runtime.getRuntime().gc()</code>. 585: * 586: * @see Runtime#gc() 587: */ 588: public static void gc() 589: { 590: Runtime.getRuntime().gc(); 591: } 592: 593: /** 594: * Runs object finalization on pending objects. This is only a hint, and 595: * it is up to the implementation what this hint suggests, but it usually 596: * causes a best-effort attempt to run finalizers on all objects ready 597: * to be reclaimed. This calls 598: * <code>Runtime.getRuntime().runFinalization()</code>. 599: * 600: * @see Runtime#runFinalization() 601: */ 602: public static void runFinalization() 603: { 604: Runtime.getRuntime().runFinalization(); 605: } 606: 607: /** 608: * Tell the Runtime whether to run finalization before exiting the 609: * JVM. This is inherently unsafe in multi-threaded applications, 610: * since it can force initialization on objects which are still in use 611: * by live threads, leading to deadlock; therefore this is disabled by 612: * default. There may be a security check, <code>checkExit(0)</code>. This 613: * calls <code>Runtime.runFinalizersOnExit()</code>. 614: * 615: * @param finalizeOnExit whether to run finalizers on exit 616: * @throws SecurityException if permission is denied 617: * @see Runtime#runFinalizersOnExit(boolean) 618: * @since 1.1 619: * @deprecated never rely on finalizers to do a clean, thread-safe, 620: * mop-up from your code 621: */ 622: public static void runFinalizersOnExit(boolean finalizeOnExit) 623: { 624: Runtime.runFinalizersOnExit(finalizeOnExit); 625: } 626: 627: /** 628: * Load a code file using its explicit system-dependent filename. A security 629: * check may be performed, <code>checkLink</code>. This just calls 630: * <code>Runtime.getRuntime().load(filename)</code>. 631: * 632: * <p> 633: * The library is loaded using the class loader associated with the 634: * class associated with the invoking method. 635: * 636: * @param filename the code file to load 637: * @throws SecurityException if permission is denied 638: * @throws UnsatisfiedLinkError if the file cannot be loaded 639: * @see Runtime#load(String) 640: */ 641: public static void load(String filename) 642: { 643: Runtime.getRuntime().load(filename, VMStackWalker.getCallingClassLoader()); 644: } 645: 646: /** 647: * Load a library using its explicit system-dependent filename. A security 648: * check may be performed, <code>checkLink</code>. This just calls 649: * <code>Runtime.getRuntime().load(filename)</code>. 650: * 651: * <p> 652: * The library is loaded using the class loader associated with the 653: * class associated with the invoking method. 654: * 655: * @param libname the library file to load 656: * @throws SecurityException if permission is denied 657: * @throws UnsatisfiedLinkError if the file cannot be loaded 658: * @see Runtime#load(String) 659: */ 660: public static void loadLibrary(String libname) 661: { 662: Runtime.getRuntime().loadLibrary(libname, 663: VMStackWalker.getCallingClassLoader()); 664: } 665: 666: /** 667: * Convert a library name to its platform-specific variant. 668: * 669: * @param libname the library name, as used in <code>loadLibrary</code> 670: * @return the platform-specific mangling of the name 671: * @since 1.2 672: */ 673: public static String mapLibraryName(String libname) 674: { 675: return VMRuntime.mapLibraryName(libname); 676: } 677: 678: /** 679: * Returns the inherited channel of the VM. 680: * 681: * This wraps the inheritedChannel() call of the system's default 682: * {@link SelectorProvider}. 683: * 684: * @return the inherited channel of the VM 685: * 686: * @throws IOException If an I/O error occurs 687: * @throws SecurityException If an installed security manager denies access 688: * to RuntimePermission("inheritedChannel") 689: * 690: * @since 1.5 691: */ 692: public static Channel inheritedChannel() 693: throws IOException 694: { 695: return SelectorProvider.provider().inheritedChannel(); 696: } 697: 698: /** 699: * This is a specialised <code>Collection</code>, providing 700: * the necessary provisions for the collections used by the 701: * environment variable map. Namely, it prevents 702: * querying anything but <code>String</code>s. 703: * 704: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 705: */ 706: private static class EnvironmentCollection 707: extends AbstractCollection<String> 708: { 709: 710: /** 711: * The wrapped collection. 712: */ 713: protected Collection<String> c; 714: 715: /** 716: * Constructs a new environment collection, which 717: * wraps the elements of the supplied collection. 718: * 719: * @param coll the collection to use as a base for 720: * this collection. 721: */ 722: public EnvironmentCollection(Collection<String> coll) 723: { 724: c = coll; 725: } 726: 727: /** 728: * Blocks queries containing a null object or an object which 729: * isn't of type <code>String</code>. All other queries 730: * are forwarded to the underlying collection. 731: * 732: * @param obj the object to look for. 733: * @return true if the object exists in the collection. 734: * @throws NullPointerException if the specified object is null. 735: * @throws ClassCastException if the specified object is not a String. 736: */ 737: public boolean contains(Object obj) 738: { 739: if (obj == null) 740: throw new 741: NullPointerException("This collection does not support " + 742: "null values."); 743: if (!(obj instanceof String)) 744: throw new 745: ClassCastException("This collection only supports Strings."); 746: return c.contains(obj); 747: } 748: 749: /** 750: * Blocks queries where the collection contains a null object or 751: * an object which isn't of type <code>String</code>. All other 752: * queries are forwarded to the underlying collection. 753: * 754: * @param coll the collection of objects to look for. 755: * @return true if the collection contains all elements in the collection. 756: * @throws NullPointerException if the collection is null. 757: * @throws NullPointerException if any collection entry is null. 758: * @throws ClassCastException if any collection entry is not a String. 759: */ 760: public boolean containsAll(Collection<?> coll) 761: { 762: for (Object o: coll) 763: { 764: if (o == null) 765: throw new 766: NullPointerException("This collection does not support " + 767: "null values."); 768: if (!(o instanceof String)) 769: throw new 770: ClassCastException("This collection only supports Strings."); 771: } 772: return c.containsAll(coll); 773: } 774: 775: /** 776: * This returns an iterator over the map elements, with the 777: * same provisions as for the collection and underlying map. 778: * 779: * @return an iterator over the map elements. 780: */ 781: public Iterator<String> iterator() 782: { 783: return c.iterator(); 784: } 785: 786: /** 787: * Blocks the removal of elements from the collection. 788: * 789: * @return true if the removal was sucessful. 790: * @throws NullPointerException if the collection is null. 791: * @throws NullPointerException if any collection entry is null. 792: * @throws ClassCastException if any collection entry is not a String. 793: */ 794: public boolean remove(Object key) 795: { 796: if (key == null) 797: throw new 798: NullPointerException("This collection does not support " + 799: "null values."); 800: if (!(key instanceof String)) 801: throw new 802: ClassCastException("This collection only supports Strings."); 803: return c.contains(key); 804: } 805: 806: /** 807: * Blocks the removal of all elements in the specified 808: * collection from the collection. 809: * 810: * @param coll the collection of elements to remove. 811: * @return true if the elements were removed. 812: * @throws NullPointerException if the collection is null. 813: * @throws NullPointerException if any collection entry is null. 814: * @throws ClassCastException if any collection entry is not a String. 815: */ 816: public boolean removeAll(Collection<?> coll) 817: { 818: for (Object o: coll) 819: { 820: if (o == null) 821: throw new 822: NullPointerException("This collection does not support " + 823: "null values."); 824: if (!(o instanceof String)) 825: throw new 826: ClassCastException("This collection only supports Strings."); 827: } 828: return c.removeAll(coll); 829: } 830: 831: /** 832: * Blocks the retention of all elements in the specified 833: * collection from the collection. 834: * 835: * @param c the collection of elements to retain. 836: * @return true if the other elements were removed. 837: * @throws NullPointerException if the collection is null. 838: * @throws NullPointerException if any collection entry is null. 839: * @throws ClassCastException if any collection entry is not a String. 840: */ 841: public boolean retainAll(Collection<?> coll) 842: { 843: for (Object o: coll) 844: { 845: if (o == null) 846: throw new 847: NullPointerException("This collection does not support " + 848: "null values."); 849: if (!(o instanceof String)) 850: throw new 851: ClassCastException("This collection only supports Strings."); 852: } 853: return c.containsAll(coll); 854: } 855: 856: /** 857: * This simply calls the same method on the wrapped 858: * collection. 859: * 860: * @return the size of the underlying collection. 861: */ 862: public int size() 863: { 864: return c.size(); 865: } 866: 867: } // class EnvironmentCollection<String> 868: 869: /** 870: * This is a specialised <code>HashMap</code>, which 871: * prevents the addition or querying of anything other than 872: * <code>String</code> objects. 873: * 874: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 875: */ 876: static class EnvironmentMap 877: extends HashMap<String,String> 878: { 879: 880: /** 881: * Cache the entry set. 882: */ 883: private transient Set<Map.Entry<String,String>> entries; 884: 885: /** 886: * Cache the key set. 887: */ 888: private transient Set<String> keys; 889: 890: /** 891: * Cache the value collection. 892: */ 893: private transient Collection<String> values; 894: 895: /** 896: * Constructs a new empty <code>EnvironmentMap</code>. 897: */ 898: EnvironmentMap() 899: { 900: super(); 901: } 902: 903: /** 904: * Constructs a new <code>EnvironmentMap</code> containing 905: * the contents of the specified map. 906: * 907: * @param m the map to be added to this. 908: * @throws NullPointerException if a key or value is null. 909: * @throws ClassCastException if a key or value is not a String. 910: */ 911: EnvironmentMap(Map<String,String> m) 912: { 913: super(m); 914: } 915: 916: /** 917: * Blocks queries containing a null key or one which is not 918: * of type <code>String</code>. All other queries 919: * are forwarded to the superclass. 920: * 921: * @param key the key to look for in the map. 922: * @return true if the key exists in the map. 923: * @throws NullPointerException if the specified key is null. 924: */ 925: public boolean containsKey(Object key) 926: { 927: if (key == null) 928: throw new 929: NullPointerException("This map does not support null keys."); 930: if (!(key instanceof String)) 931: throw new 932: ClassCastException("This map only allows queries using Strings."); 933: return super.containsKey(key); 934: } 935: 936: /** 937: * Blocks queries using a null or non-<code>String</code> value. 938: * All other queries are forwarded to the superclass. 939: * 940: * @param value the value to look for in the map. 941: * @return true if the value exists in the map. 942: * @throws NullPointerException if the specified value is null. 943: */ 944: public boolean containsValue(Object value) 945: { 946: if (value == null) 947: throw new 948: NullPointerException("This map does not support null values."); 949: if (!(value instanceof String)) 950: throw new 951: ClassCastException("This map only allows queries using Strings."); 952: return super.containsValue(value); 953: } 954: 955: /** 956: * Returns a set view of the map entries, with the same 957: * provisions as for the underlying map. 958: * 959: * @return a set containing the map entries. 960: */ 961: public Set<Map.Entry<String,String>> entrySet() 962: { 963: if (entries == null) 964: entries = super.entrySet(); 965: return entries; 966: } 967: 968: /** 969: * Blocks queries containing a null or non-<code>String</code> key. 970: * All other queries are passed on to the superclass. 971: * 972: * @param key the key to retrieve the value for. 973: * @return the value associated with the given key. 974: * @throws NullPointerException if the specified key is null. 975: * @throws ClassCastException if the specified key is not a String. 976: */ 977: public String get(Object key) 978: { 979: if (key == null) 980: throw new 981: NullPointerException("This map does not support null keys."); 982: if (!(key instanceof String)) 983: throw new 984: ClassCastException("This map only allows queries using Strings."); 985: return super.get(key); 986: } 987: 988: /** 989: * Returns a set view of the keys, with the same 990: * provisions as for the underlying map. 991: * 992: * @return a set containing the keys. 993: */ 994: public Set<String> keySet() 995: { 996: if (keys == null) 997: keys = new EnvironmentSet(super.keySet()); 998: return keys; 999: } 1000: 1001: /** 1002: * Associates the given key to the given value. If the 1003: * map already contains the key, its value is replaced. 1004: * The map does not accept null keys or values, or keys 1005: * and values not of type {@link String}. 1006: * 1007: * @param key the key to map. 1008: * @param value the value to be mapped. 1009: * @return the previous value of the key, or null if there was no mapping 1010: * @throws NullPointerException if a key or value is null. 1011: * @throws ClassCastException if a key or value is not a String. 1012: */ 1013: public String put(String key, String value) 1014: { 1015: if (key == null) 1016: throw new NullPointerException("A new key is null."); 1017: if (value == null) 1018: throw new NullPointerException("A new value is null."); 1019: if (!(key instanceof String)) 1020: throw new ClassCastException("A new key is not a String."); 1021: if (!(value instanceof String)) 1022: throw new ClassCastException("A new value is not a String."); 1023: return super.put(key, value); 1024: } 1025: 1026: /** 1027: * Removes a key-value pair from the map. The queried key may not 1028: * be null or of a type other than a <code>String</code>. 1029: * 1030: * @param key the key of the entry to remove. 1031: * @return the removed value. 1032: * @throws NullPointerException if the specified key is null. 1033: * @throws ClassCastException if the specified key is not a String. 1034: */ 1035: public String remove(Object key) 1036: { 1037: if (key == null) 1038: throw new 1039: NullPointerException("This map does not support null keys."); 1040: if (!(key instanceof String)) 1041: throw new 1042: ClassCastException("This map only allows queries using Strings."); 1043: return super.remove(key); 1044: } 1045: 1046: /** 1047: * Returns a collection view of the values, with the same 1048: * provisions as for the underlying map. 1049: * 1050: * @return a collection containing the values. 1051: */ 1052: public Collection<String> values() 1053: { 1054: if (values == null) 1055: values = new EnvironmentCollection(super.values()); 1056: return values; 1057: } 1058: 1059: } 1060: 1061: /** 1062: * This is a specialised <code>Set</code>, providing 1063: * the necessary provisions for the collections used by the 1064: * environment variable map. Namely, it prevents 1065: * modifications and the use of queries with null 1066: * or non-<code>String</code> values. 1067: * 1068: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 1069: */ 1070: private static class EnvironmentSet 1071: extends EnvironmentCollection 1072: implements Set<String> 1073: { 1074: 1075: /** 1076: * Constructs a new environment set, which 1077: * wraps the elements of the supplied set. 1078: * 1079: * @param set the set to use as a base for 1080: * this set. 1081: */ 1082: public EnvironmentSet(Set<String> set) 1083: { 1084: super(set); 1085: } 1086: 1087: /** 1088: * This simply calls the same method on the wrapped 1089: * collection. 1090: * 1091: * @param obj the object to compare with. 1092: * @return true if the two objects are equal. 1093: */ 1094: public boolean equals(Object obj) 1095: { 1096: return c.equals(obj); 1097: } 1098: 1099: /** 1100: * This simply calls the same method on the wrapped 1101: * collection. 1102: * 1103: * @return the hashcode of the collection. 1104: */ 1105: public int hashCode() 1106: { 1107: return c.hashCode(); 1108: } 1109: 1110: } // class EnvironmentSet<String> 1111: 1112: } // class System
GNU Classpath (0.95) |