Source for java.lang.System

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