a1906e8bbf
2012-12-19 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (20121202). * Regenerate class and header files. * Regenerate auto* files. * sources.am, gcj/javaprims.h: Regenerate. * gnu/java/nio/FileLockImpl.java (close): New override. From-SVN: r194618
1142 lines
39 KiB
Java
1142 lines
39 KiB
Java
/* System.java -- useful methods to interface with the system
|
|
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2012
|
|
Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Classpath.
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Classpath is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
|
|
Linking this library statically or dynamically with other modules is
|
|
making a combined work based on this library. Thus, the terms and
|
|
conditions of the GNU General Public License cover the whole
|
|
combination.
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent
|
|
modules, and to copy and distribute the resulting executable under
|
|
terms of your choice, provided that you also meet, for each linked
|
|
independent module, the terms and conditions of the license of that
|
|
module. An independent module is a module which is not derived from
|
|
or based on this library. If you modify this library, you may extend
|
|
this exception to your version of the library, but you are not
|
|
obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version. */
|
|
|
|
|
|
package java.lang;
|
|
|
|
import gnu.classpath.SystemProperties;
|
|
import gnu.classpath.VMStackWalker;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.PrintStream;
|
|
import java.io.Console;
|
|
import java.nio.channels.Channel;
|
|
import java.nio.channels.spi.SelectorProvider;
|
|
import java.util.AbstractCollection;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.Properties;
|
|
import java.util.PropertyPermission;
|
|
|
|
/**
|
|
* System represents system-wide resources; things that represent the
|
|
* general environment. As such, all methods are static.
|
|
*
|
|
* @author John Keiser
|
|
* @author Eric Blake (ebb9@email.byu.edu)
|
|
* @since 1.0
|
|
* @status still missing 1.4 functionality
|
|
*/
|
|
public final class System
|
|
{
|
|
// WARNING: System is a CORE class in the bootstrap cycle. See the comments
|
|
// in vm/reference/java/lang/Runtime for implications of this fact.
|
|
|
|
/**
|
|
* The standard InputStream. This is assigned at startup and starts its
|
|
* life perfectly valid. Although it is marked final, you can change it
|
|
* using {@link #setIn(InputStream)} through some hefty VM magic.
|
|
*
|
|
* <p>This corresponds to the C stdin and C++ cin variables, which
|
|
* typically input from the keyboard, but may be used to pipe input from
|
|
* other processes or files. That should all be transparent to you,
|
|
* however.
|
|
*/
|
|
public static final InputStream in = VMSystem.makeStandardInputStream();
|
|
|
|
/**
|
|
* The standard output PrintStream. This is assigned at startup and
|
|
* starts its life perfectly valid. Although it is marked final, you can
|
|
* change it using {@link #setOut(PrintStream)} through some hefty VM magic.
|
|
*
|
|
* <p>This corresponds to the C stdout and C++ cout variables, which
|
|
* typically output normal messages to the screen, but may be used to pipe
|
|
* output to other processes or files. That should all be transparent to
|
|
* you, however.
|
|
*/
|
|
public static final PrintStream out = VMSystem.makeStandardOutputStream();
|
|
|
|
private static final String LINE_SEPARATOR = SystemProperties.getProperty("line.separator");
|
|
|
|
/**
|
|
* The standard output PrintStream. This is assigned at startup and
|
|
* starts its life perfectly valid. Although it is marked final, you can
|
|
* change it using {@link #setErr(PrintStream)} through some hefty VM magic.
|
|
*
|
|
* <p>This corresponds to the C stderr and C++ cerr variables, which
|
|
* typically output error messages to the screen, but may be used to pipe
|
|
* output to other processes or files. That should all be transparent to
|
|
* you, however.
|
|
*/
|
|
public static final PrintStream err = VMSystem.makeStandardErrorStream();
|
|
|
|
/**
|
|
* A cached copy of the environment variable map.
|
|
*/
|
|
private static Map<String,String> environmentMap;
|
|
|
|
/**
|
|
* This class is uninstantiable.
|
|
*/
|
|
private System()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Set {@link #in} to a new InputStream. This uses some VM magic to change
|
|
* a "final" variable, so naturally there is a security check,
|
|
* <code>RuntimePermission("setIO")</code>.
|
|
*
|
|
* @param in the new InputStream
|
|
* @throws SecurityException if permission is denied
|
|
* @since 1.1
|
|
*/
|
|
public static void setIn(InputStream in)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new RuntimePermission("setIO"));
|
|
|
|
VMSystem.setIn(in);
|
|
}
|
|
|
|
/**
|
|
* Set {@link #out} to a new PrintStream. This uses some VM magic to change
|
|
* a "final" variable, so naturally there is a security check,
|
|
* <code>RuntimePermission("setIO")</code>.
|
|
*
|
|
* @param out the new PrintStream
|
|
* @throws SecurityException if permission is denied
|
|
* @since 1.1
|
|
*/
|
|
public static void setOut(PrintStream out)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new RuntimePermission("setIO"));
|
|
VMSystem.setOut(out);
|
|
}
|
|
|
|
/**
|
|
* Set {@link #err} to a new PrintStream. This uses some VM magic to change
|
|
* a "final" variable, so naturally there is a security check,
|
|
* <code>RuntimePermission("setIO")</code>.
|
|
*
|
|
* @param err the new PrintStream
|
|
* @throws SecurityException if permission is denied
|
|
* @since 1.1
|
|
*/
|
|
public static void setErr(PrintStream err)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new RuntimePermission("setIO"));
|
|
VMSystem.setErr(err);
|
|
}
|
|
|
|
/**
|
|
* Set the current SecurityManager. If a security manager already exists,
|
|
* then <code>RuntimePermission("setSecurityManager")</code> is checked
|
|
* first. Since this permission is denied by the default security manager,
|
|
* setting the security manager is often an irreversible action.
|
|
*
|
|
* <STRONG>Spec Note:</STRONG> Don't ask me, I didn't write it. It looks
|
|
* pretty vulnerable; whoever gets to the gate first gets to set the policy.
|
|
* There is probably some way to set the original security manager as a
|
|
* command line argument to the VM, but I don't know it.
|
|
*
|
|
* @param sm the new SecurityManager
|
|
* @throws SecurityException if permission is denied
|
|
*/
|
|
public static synchronized void setSecurityManager(SecurityManager sm)
|
|
{
|
|
// Implementation note: the field lives in SecurityManager because of
|
|
// bootstrap initialization issues. This method is synchronized so that
|
|
// no other thread changes it to null before this thread makes the change.
|
|
if (SecurityManager.current != null)
|
|
SecurityManager.current.checkPermission
|
|
(new RuntimePermission("setSecurityManager"));
|
|
|
|
// java.security.Security's class initialiser loads and parses the
|
|
// policy files. If it hasn't been run already it will be run
|
|
// during the first permission check. That initialisation will
|
|
// fail if a very restrictive security manager is in force, so we
|
|
// preload it here.
|
|
if (SecurityManager.current == null)
|
|
{
|
|
try
|
|
{
|
|
Class.forName("java.security.Security");
|
|
}
|
|
catch (ClassNotFoundException e)
|
|
{
|
|
}
|
|
}
|
|
|
|
SecurityManager.current = sm;
|
|
}
|
|
|
|
/**
|
|
* Get the current SecurityManager. If the SecurityManager has not been
|
|
* set yet, then this method returns null.
|
|
*
|
|
* @return the current SecurityManager, or null
|
|
*/
|
|
public static SecurityManager getSecurityManager()
|
|
{
|
|
return SecurityManager.current;
|
|
}
|
|
|
|
/**
|
|
* Get the current time, measured in the number of milliseconds from the
|
|
* beginning of Jan. 1, 1970. This is gathered from the system clock, with
|
|
* any attendant incorrectness (it may be timezone dependent).
|
|
*
|
|
* @return the current time
|
|
* @see java.util.Date
|
|
*/
|
|
public static long currentTimeMillis()
|
|
{
|
|
return VMSystem.currentTimeMillis();
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns the current value of a nanosecond-precise system timer.
|
|
* The value of the timer is an offset relative to some arbitrary fixed
|
|
* time, which may be in the future (making the value negative). This
|
|
* method is useful for timing events where nanosecond precision is
|
|
* required. This is achieved by calling this method before and after the
|
|
* event, and taking the difference betweent the two times:
|
|
* </p>
|
|
* <p>
|
|
* <code>long startTime = System.nanoTime();</code><br />
|
|
* <code>... <emph>event code</emph> ...</code><br />
|
|
* <code>long endTime = System.nanoTime();</code><br />
|
|
* <code>long duration = endTime - startTime;</code><br />
|
|
* </p>
|
|
* <p>
|
|
* Note that the value is only nanosecond-precise, and not accurate; there
|
|
* is no guarantee that the difference between two values is really a
|
|
* nanosecond. Also, the value is prone to overflow if the offset
|
|
* exceeds 2^63.
|
|
* </p>
|
|
*
|
|
* @return the time of a system timer in nanoseconds.
|
|
* @since 1.5
|
|
*/
|
|
public static long nanoTime()
|
|
{
|
|
return VMSystem.nanoTime();
|
|
}
|
|
|
|
/**
|
|
* Copy one array onto another from <code>src[srcStart]</code> ...
|
|
* <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
|
|
* <code>dest[destStart+len-1]</code>. First, the arguments are validated:
|
|
* neither array may be null, they must be of compatible types, and the
|
|
* start and length must fit within both arrays. Then the copying starts,
|
|
* and proceeds through increasing slots. If src and dest are the same
|
|
* array, this will appear to copy the data to a temporary location first.
|
|
* An ArrayStoreException in the middle of copying will leave earlier
|
|
* elements copied, but later elements unchanged.
|
|
*
|
|
* @param src the array to copy elements from
|
|
* @param srcStart the starting position in src
|
|
* @param dest the array to copy elements to
|
|
* @param destStart the starting position in dest
|
|
* @param len the number of elements to copy
|
|
* @throws NullPointerException if src or dest is null
|
|
* @throws ArrayStoreException if src or dest is not an array, if they are
|
|
* not compatible array types, or if an incompatible runtime type
|
|
* is stored in dest
|
|
* @throws IndexOutOfBoundsException if len is negative, or if the start or
|
|
* end copy position in either array is out of bounds
|
|
*/
|
|
public static void arraycopy(Object src, int srcStart,
|
|
Object dest, int destStart, int len)
|
|
{
|
|
VMSystem.arraycopy(src, srcStart, dest, destStart, len);
|
|
}
|
|
|
|
/**
|
|
* Get a hash code computed by the VM for the Object. This hash code will
|
|
* be the same as Object's hashCode() method. It is usually some
|
|
* convolution of the pointer to the Object internal to the VM. It
|
|
* follows standard hash code rules, in that it will remain the same for a
|
|
* given Object for the lifetime of that Object.
|
|
*
|
|
* @param o the Object to get the hash code for
|
|
* @return the VM-dependent hash code for this Object
|
|
* @since 1.1
|
|
*/
|
|
public static int identityHashCode(Object o)
|
|
{
|
|
return VMSystem.identityHashCode(o);
|
|
}
|
|
|
|
/**
|
|
* Get all the system properties at once. A security check may be performed,
|
|
* <code>checkPropertiesAccess</code>. Note that a security manager may
|
|
* allow getting a single property, but not the entire group.
|
|
*
|
|
* <p>The required properties include:
|
|
* <dl>
|
|
* <dt>java.version</dt> <dd>Java version number</dd>
|
|
* <dt>java.vendor</dt> <dd>Java vendor specific string</dd>
|
|
* <dt>java.vendor.url</dt> <dd>Java vendor URL</dd>
|
|
* <dt>java.home</dt> <dd>Java installation directory</dd>
|
|
* <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
|
|
* <dt>java.vm.specification.vendor</dt> <dd>VM Spec vendor</dd>
|
|
* <dt>java.vm.specification.name</dt> <dd>VM Spec name</dd>
|
|
* <dt>java.vm.version</dt> <dd>VM implementation version</dd>
|
|
* <dt>java.vm.vendor</dt> <dd>VM implementation vendor</dd>
|
|
* <dt>java.vm.name</dt> <dd>VM implementation name</dd>
|
|
* <dt>java.specification.version</dt> <dd>Java Runtime Environment version</dd>
|
|
* <dt>java.specification.vendor</dt> <dd>Java Runtime Environment vendor</dd>
|
|
* <dt>java.specification.name</dt> <dd>Java Runtime Environment name</dd>
|
|
* <dt>java.class.version</dt> <dd>Java class version number</dd>
|
|
* <dt>java.class.path</dt> <dd>Java classpath</dd>
|
|
* <dt>java.library.path</dt> <dd>Path for finding Java libraries</dd>
|
|
* <dt>java.io.tmpdir</dt> <dd>Default temp file path</dd>
|
|
* <dt>java.compiler</dt> <dd>Name of JIT to use</dd>
|
|
* <dt>java.ext.dirs</dt> <dd>Java extension path</dd>
|
|
* <dt>os.name</dt> <dd>Operating System Name</dd>
|
|
* <dt>os.arch</dt> <dd>Operating System Architecture</dd>
|
|
* <dt>os.version</dt> <dd>Operating System Version</dd>
|
|
* <dt>file.separator</dt> <dd>File separator ("/" on Unix)</dd>
|
|
* <dt>path.separator</dt> <dd>Path separator (":" on Unix)</dd>
|
|
* <dt>line.separator</dt> <dd>Line separator ("\n" on Unix)</dd>
|
|
* <dt>user.name</dt> <dd>User account name</dd>
|
|
* <dt>user.home</dt> <dd>User home directory</dd>
|
|
* <dt>user.dir</dt> <dd>User's current working directory</dd>
|
|
* </dl>
|
|
*
|
|
* In addition, gnu defines several other properties, where ? stands for
|
|
* each character in '0' through '9':
|
|
* <dl>
|
|
* <dt>gnu.classpath.home</dt> <dd>Path to the classpath libraries.</dd>
|
|
* <dt>gnu.classpath.version</dt> <dd>Version of the classpath libraries.</dd>
|
|
* <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
|
|
* used for finding property files in file system</dd>
|
|
* <dt>gnu.classpath.home.url</dt> <dd> Base URL; used for finding
|
|
* property files in file system</dd>
|
|
* <dt>gnu.cpu.endian</dt> <dd>big or little</dd>
|
|
* <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt> <dd>8859_?</dd>
|
|
* <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt> <dd>8859_?</dd>
|
|
* <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
|
|
* <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
|
|
* <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
|
|
* <dt>gnu.java.util.zoneinfo.dir</dt> <dd>Root of zoneinfo tree</dd>
|
|
* <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd>
|
|
* </dl>
|
|
*
|
|
* @return the system properties, will never be null
|
|
* @throws SecurityException if permission is denied
|
|
*/
|
|
public static Properties getProperties()
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPropertiesAccess();
|
|
return SystemProperties.getProperties();
|
|
}
|
|
|
|
/**
|
|
* Set all the system properties at once. A security check may be performed,
|
|
* <code>checkPropertiesAccess</code>. Note that a security manager may
|
|
* allow setting a single property, but not the entire group. An argument
|
|
* of null resets the properties to the startup default.
|
|
*
|
|
* @param properties the new set of system properties
|
|
* @throws SecurityException if permission is denied
|
|
*/
|
|
public static void setProperties(Properties properties)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPropertiesAccess();
|
|
SystemProperties.setProperties(properties);
|
|
}
|
|
|
|
/**
|
|
* Get a single system property by name. A security check may be performed,
|
|
* <code>checkPropertyAccess(key)</code>.
|
|
*
|
|
* @param key the name of the system property to get
|
|
* @return the property, or null if not found
|
|
* @throws SecurityException if permission is denied
|
|
* @throws NullPointerException if key is null
|
|
* @throws IllegalArgumentException if key is ""
|
|
*/
|
|
public static String getProperty(String key)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPropertyAccess(key);
|
|
if (key.length() == 0)
|
|
throw new IllegalArgumentException("key can't be empty");
|
|
return SystemProperties.getProperty(key);
|
|
}
|
|
|
|
/**
|
|
* Get a single system property by name. A security check may be performed,
|
|
* <code>checkPropertyAccess(key)</code>.
|
|
*
|
|
* @param key the name of the system property to get
|
|
* @param def the default
|
|
* @return the property, or def if not found
|
|
* @throws SecurityException if permission is denied
|
|
* @throws NullPointerException if key is null
|
|
* @throws IllegalArgumentException if key is ""
|
|
*/
|
|
public static String getProperty(String key, String def)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPropertyAccess(key);
|
|
// This handles both the null pointer exception and the illegal
|
|
// argument exception.
|
|
if (key.length() == 0)
|
|
throw new IllegalArgumentException("key can't be empty");
|
|
return SystemProperties.getProperty(key, def);
|
|
}
|
|
|
|
/**
|
|
* Set a single system property by name. A security check may be performed,
|
|
* <code>checkPropertyAccess(key, "write")</code>.
|
|
*
|
|
* @param key the name of the system property to set
|
|
* @param value the new value
|
|
* @return the previous value, or null
|
|
* @throws SecurityException if permission is denied
|
|
* @throws NullPointerException if key is null
|
|
* @throws IllegalArgumentException if key is ""
|
|
* @since 1.2
|
|
*/
|
|
public static String setProperty(String key, String value)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new PropertyPermission(key, "write"));
|
|
// This handles both the null pointer exception and the illegal
|
|
// argument exception.
|
|
if (key.length() == 0)
|
|
throw new IllegalArgumentException("key can't be empty");
|
|
return SystemProperties.setProperty(key, value);
|
|
}
|
|
|
|
/**
|
|
* Remove a single system property by name. A security check may be
|
|
* performed, <code>checkPropertyAccess(key, "write")</code>.
|
|
*
|
|
* @param key the name of the system property to remove
|
|
* @return the previous value, or null
|
|
* @throws SecurityException if permission is denied
|
|
* @throws NullPointerException if key is null
|
|
* @throws IllegalArgumentException if key is ""
|
|
* @since 1.5
|
|
*/
|
|
public static String clearProperty(String key)
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new PropertyPermission(key, "write"));
|
|
// This handles both the null pointer exception and the illegal
|
|
// argument exception.
|
|
if (key.length() == 0)
|
|
throw new IllegalArgumentException("key can't be empty");
|
|
return SystemProperties.remove(key);
|
|
}
|
|
|
|
/**
|
|
* Gets the value of an environment variable.
|
|
*
|
|
* @param name the name of the environment variable
|
|
* @return the string value of the variable or null when the
|
|
* environment variable is not defined.
|
|
* @throws NullPointerException
|
|
* @throws SecurityException if permission is denied
|
|
* @since 1.5
|
|
* @specnote This method was deprecated in some JDK releases, but
|
|
* was restored in 1.5.
|
|
*/
|
|
public static String getenv(String name)
|
|
{
|
|
if (name == null)
|
|
throw new NullPointerException();
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new RuntimePermission("getenv." + name));
|
|
return VMSystem.getenv(name);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Returns an unmodifiable view of the system environment variables.
|
|
* If the underlying system does not support environment variables,
|
|
* an empty map is returned.
|
|
* </p>
|
|
* <p>
|
|
* The returned map is read-only and does not accept queries using
|
|
* null keys or values, or those of a type other than <code>String</code>.
|
|
* Attempts to modify the map will throw an
|
|
* <code>UnsupportedOperationException</code>, while attempts
|
|
* to pass in a null value will throw a
|
|
* <code>NullPointerException</code>. Types other than <code>String</code>
|
|
* throw a <code>ClassCastException</code>.
|
|
* </p>
|
|
* <p>
|
|
* As the returned map is generated using data from the underlying
|
|
* platform, it may not comply with the <code>equals()</code>
|
|
* and <code>hashCode()</code> contracts. It is also likely that
|
|
* the keys of this map will be case-sensitive.
|
|
* </p>
|
|
* <p>
|
|
* Use of this method may require a security check for the
|
|
* RuntimePermission "getenv.*".
|
|
* </p>
|
|
*
|
|
* @return a map of the system environment variables.
|
|
* @throws SecurityException if the checkPermission method of
|
|
* an installed security manager prevents access to
|
|
* the system environment variables.
|
|
* @since 1.5
|
|
*/
|
|
public static Map<String, String> getenv()
|
|
{
|
|
SecurityManager sm = SecurityManager.current; // Be thread-safe.
|
|
if (sm != null)
|
|
sm.checkPermission(new RuntimePermission("getenv.*"));
|
|
|
|
if (environmentMap == null)
|
|
{
|
|
Map<String,String> variables = new EnvironmentMap();
|
|
List<String> environ = (List<String>)VMSystem.environ();
|
|
for (String envEntry : environ)
|
|
{
|
|
// avoid broken and null entries
|
|
if (envEntry != null && !envEntry.endsWith("="))
|
|
{
|
|
// it's perfectly legal that some entries may be in the form
|
|
// key=value=value=value
|
|
int equalSignIndex = envEntry.indexOf('=');
|
|
String key = envEntry.substring(0, equalSignIndex);
|
|
String value = envEntry.substring(equalSignIndex + 1);
|
|
variables.put(key, value);
|
|
}
|
|
}
|
|
|
|
environmentMap = Collections.unmodifiableMap(variables);
|
|
}
|
|
|
|
return environmentMap;
|
|
}
|
|
|
|
/**
|
|
* Terminate the Virtual Machine. This just calls
|
|
* <code>Runtime.getRuntime().exit(status)</code>, and never returns.
|
|
* Obviously, a security check is in order, <code>checkExit</code>.
|
|
*
|
|
* @param status the exit status; by convention non-zero is abnormal
|
|
* @throws SecurityException if permission is denied
|
|
* @see Runtime#exit(int)
|
|
*/
|
|
public static void exit(int status)
|
|
{
|
|
Runtime.getRuntime().exit(status);
|
|
}
|
|
|
|
/**
|
|
* Calls the garbage collector. This is only a hint, and it is up to the
|
|
* implementation what this hint suggests, but it usually causes a
|
|
* best-effort attempt to reclaim unused memory from discarded objects.
|
|
* This calls <code>Runtime.getRuntime().gc()</code>.
|
|
*
|
|
* @see Runtime#gc()
|
|
*/
|
|
public static void gc()
|
|
{
|
|
Runtime.getRuntime().gc();
|
|
}
|
|
|
|
/**
|
|
* Runs object finalization on pending objects. This is only a hint, and
|
|
* it is up to the implementation what this hint suggests, but it usually
|
|
* causes a best-effort attempt to run finalizers on all objects ready
|
|
* to be reclaimed. This calls
|
|
* <code>Runtime.getRuntime().runFinalization()</code>.
|
|
*
|
|
* @see Runtime#runFinalization()
|
|
*/
|
|
public static void runFinalization()
|
|
{
|
|
Runtime.getRuntime().runFinalization();
|
|
}
|
|
|
|
/**
|
|
* Tell the Runtime whether to run finalization before exiting the
|
|
* JVM. This is inherently unsafe in multi-threaded applications,
|
|
* since it can force initialization on objects which are still in use
|
|
* by live threads, leading to deadlock; therefore this is disabled by
|
|
* default. There may be a security check, <code>checkExit(0)</code>. This
|
|
* calls <code>Runtime.runFinalizersOnExit()</code>.
|
|
*
|
|
* @param finalizeOnExit whether to run finalizers on exit
|
|
* @throws SecurityException if permission is denied
|
|
* @see Runtime#runFinalizersOnExit(boolean)
|
|
* @since 1.1
|
|
* @deprecated never rely on finalizers to do a clean, thread-safe,
|
|
* mop-up from your code
|
|
*/
|
|
public static void runFinalizersOnExit(boolean finalizeOnExit)
|
|
{
|
|
Runtime.runFinalizersOnExit(finalizeOnExit);
|
|
}
|
|
|
|
/**
|
|
* Load a code file using its explicit system-dependent filename. A security
|
|
* check may be performed, <code>checkLink</code>. This just calls
|
|
* <code>Runtime.getRuntime().load(filename)</code>.
|
|
*
|
|
* <p>
|
|
* The library is loaded using the class loader associated with the
|
|
* class associated with the invoking method.
|
|
*
|
|
* @param filename the code file to load
|
|
* @throws SecurityException if permission is denied
|
|
* @throws UnsatisfiedLinkError if the file cannot be loaded
|
|
* @see Runtime#load(String)
|
|
*/
|
|
public static void load(String filename)
|
|
{
|
|
Runtime.getRuntime().load(filename, VMStackWalker.getCallingClassLoader());
|
|
}
|
|
|
|
/**
|
|
* Load a library using its explicit system-dependent filename. A security
|
|
* check may be performed, <code>checkLink</code>. This just calls
|
|
* <code>Runtime.getRuntime().load(filename)</code>.
|
|
*
|
|
* <p>
|
|
* The library is loaded using the class loader associated with the
|
|
* class associated with the invoking method.
|
|
*
|
|
* @param libname the library file to load
|
|
* @throws SecurityException if permission is denied
|
|
* @throws UnsatisfiedLinkError if the file cannot be loaded
|
|
* @see Runtime#load(String)
|
|
*/
|
|
public static void loadLibrary(String libname)
|
|
{
|
|
Runtime.getRuntime().loadLibrary(libname,
|
|
VMStackWalker.getCallingClassLoader());
|
|
}
|
|
|
|
/**
|
|
* Convert a library name to its platform-specific variant.
|
|
*
|
|
* @param libname the library name, as used in <code>loadLibrary</code>
|
|
* @return the platform-specific mangling of the name
|
|
* @since 1.2
|
|
*/
|
|
public static String mapLibraryName(String libname)
|
|
{
|
|
return VMRuntime.mapLibraryName(libname);
|
|
}
|
|
|
|
/**
|
|
* Returns the inherited channel of the VM.
|
|
*
|
|
* This wraps the inheritedChannel() call of the system's default
|
|
* {@link SelectorProvider}.
|
|
*
|
|
* @return the inherited channel of the VM
|
|
*
|
|
* @throws IOException If an I/O error occurs
|
|
* @throws SecurityException If an installed security manager denies access
|
|
* to RuntimePermission("inheritedChannel")
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
public static Channel inheritedChannel()
|
|
throws IOException
|
|
{
|
|
return SelectorProvider.provider().inheritedChannel();
|
|
}
|
|
|
|
/*
|
|
* @since 1.6
|
|
*/
|
|
public static Console console()
|
|
{
|
|
return Console.console();
|
|
}
|
|
|
|
/**
|
|
* Returns the system-dependent line separator.
|
|
*
|
|
* @return the system-dependent line separator.
|
|
*/
|
|
public static String lineSeparator()
|
|
{
|
|
return LINE_SEPARATOR;
|
|
}
|
|
|
|
/**
|
|
* This is a specialised <code>Collection</code>, providing
|
|
* the necessary provisions for the collections used by the
|
|
* environment variable map. Namely, it prevents
|
|
* querying anything but <code>String</code>s.
|
|
*
|
|
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
|
*/
|
|
private static class EnvironmentCollection
|
|
extends AbstractCollection<String>
|
|
{
|
|
|
|
/**
|
|
* The wrapped collection.
|
|
*/
|
|
protected Collection<String> c;
|
|
|
|
/**
|
|
* Constructs a new environment collection, which
|
|
* wraps the elements of the supplied collection.
|
|
*
|
|
* @param coll the collection to use as a base for
|
|
* this collection.
|
|
*/
|
|
public EnvironmentCollection(Collection<String> coll)
|
|
{
|
|
c = coll;
|
|
}
|
|
|
|
/**
|
|
* Blocks queries containing a null object or an object which
|
|
* isn't of type <code>String</code>. All other queries
|
|
* are forwarded to the underlying collection.
|
|
*
|
|
* @param obj the object to look for.
|
|
* @return true if the object exists in the collection.
|
|
* @throws NullPointerException if the specified object is null.
|
|
* @throws ClassCastException if the specified object is not a String.
|
|
*/
|
|
public boolean contains(Object obj)
|
|
{
|
|
if (obj == null)
|
|
throw new
|
|
NullPointerException("This collection does not support " +
|
|
"null values.");
|
|
if (!(obj instanceof String))
|
|
throw new
|
|
ClassCastException("This collection only supports Strings.");
|
|
return c.contains(obj);
|
|
}
|
|
|
|
/**
|
|
* Blocks queries where the collection contains a null object or
|
|
* an object which isn't of type <code>String</code>. All other
|
|
* queries are forwarded to the underlying collection.
|
|
*
|
|
* @param coll the collection of objects to look for.
|
|
* @return true if the collection contains all elements in the collection.
|
|
* @throws NullPointerException if the collection is null.
|
|
* @throws NullPointerException if any collection entry is null.
|
|
* @throws ClassCastException if any collection entry is not a String.
|
|
*/
|
|
public boolean containsAll(Collection<?> coll)
|
|
{
|
|
for (Object o: coll)
|
|
{
|
|
if (o == null)
|
|
throw new
|
|
NullPointerException("This collection does not support " +
|
|
"null values.");
|
|
if (!(o instanceof String))
|
|
throw new
|
|
ClassCastException("This collection only supports Strings.");
|
|
}
|
|
return c.containsAll(coll);
|
|
}
|
|
|
|
/**
|
|
* This returns an iterator over the map elements, with the
|
|
* same provisions as for the collection and underlying map.
|
|
*
|
|
* @return an iterator over the map elements.
|
|
*/
|
|
public Iterator<String> iterator()
|
|
{
|
|
return c.iterator();
|
|
}
|
|
|
|
/**
|
|
* Blocks the removal of elements from the collection.
|
|
*
|
|
* @return true if the removal was sucessful.
|
|
* @throws NullPointerException if the collection is null.
|
|
* @throws NullPointerException if any collection entry is null.
|
|
* @throws ClassCastException if any collection entry is not a String.
|
|
*/
|
|
public boolean remove(Object key)
|
|
{
|
|
if (key == null)
|
|
throw new
|
|
NullPointerException("This collection does not support " +
|
|
"null values.");
|
|
if (!(key instanceof String))
|
|
throw new
|
|
ClassCastException("This collection only supports Strings.");
|
|
return c.contains(key);
|
|
}
|
|
|
|
/**
|
|
* Blocks the removal of all elements in the specified
|
|
* collection from the collection.
|
|
*
|
|
* @param coll the collection of elements to remove.
|
|
* @return true if the elements were removed.
|
|
* @throws NullPointerException if the collection is null.
|
|
* @throws NullPointerException if any collection entry is null.
|
|
* @throws ClassCastException if any collection entry is not a String.
|
|
*/
|
|
public boolean removeAll(Collection<?> coll)
|
|
{
|
|
for (Object o: coll)
|
|
{
|
|
if (o == null)
|
|
throw new
|
|
NullPointerException("This collection does not support " +
|
|
"null values.");
|
|
if (!(o instanceof String))
|
|
throw new
|
|
ClassCastException("This collection only supports Strings.");
|
|
}
|
|
return c.removeAll(coll);
|
|
}
|
|
|
|
/**
|
|
* Blocks the retention of all elements in the specified
|
|
* collection from the collection.
|
|
*
|
|
* @param coll the collection of elements to retain.
|
|
* @return true if the other elements were removed.
|
|
* @throws NullPointerException if the collection is null.
|
|
* @throws NullPointerException if any collection entry is null.
|
|
* @throws ClassCastException if any collection entry is not a String.
|
|
*/
|
|
public boolean retainAll(Collection<?> coll)
|
|
{
|
|
for (Object o: coll)
|
|
{
|
|
if (o == null)
|
|
throw new
|
|
NullPointerException("This collection does not support " +
|
|
"null values.");
|
|
if (!(o instanceof String))
|
|
throw new
|
|
ClassCastException("This collection only supports Strings.");
|
|
}
|
|
return c.containsAll(coll);
|
|
}
|
|
|
|
/**
|
|
* This simply calls the same method on the wrapped
|
|
* collection.
|
|
*
|
|
* @return the size of the underlying collection.
|
|
*/
|
|
public int size()
|
|
{
|
|
return c.size();
|
|
}
|
|
|
|
} // class EnvironmentCollection<String>
|
|
|
|
/**
|
|
* This is a specialised <code>HashMap</code>, which
|
|
* prevents the addition or querying of anything other than
|
|
* <code>String</code> objects.
|
|
*
|
|
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
|
*/
|
|
static class EnvironmentMap
|
|
extends HashMap<String,String>
|
|
{
|
|
|
|
/**
|
|
* Cache the entry set.
|
|
*/
|
|
private transient Set<Map.Entry<String,String>> entries;
|
|
|
|
/**
|
|
* Cache the key set.
|
|
*/
|
|
private transient Set<String> keys;
|
|
|
|
/**
|
|
* Cache the value collection.
|
|
*/
|
|
private transient Collection<String> values;
|
|
|
|
/**
|
|
* Constructs a new empty <code>EnvironmentMap</code>.
|
|
*/
|
|
EnvironmentMap()
|
|
{
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Constructs a new <code>EnvironmentMap</code> containing
|
|
* the contents of the specified map.
|
|
*
|
|
* @param m the map to be added to this.
|
|
* @throws NullPointerException if a key or value is null.
|
|
* @throws ClassCastException if a key or value is not a String.
|
|
*/
|
|
EnvironmentMap(Map<String,String> m)
|
|
{
|
|
super(m);
|
|
}
|
|
|
|
/**
|
|
* Blocks queries containing a null key or one which is not
|
|
* of type <code>String</code>. All other queries
|
|
* are forwarded to the superclass.
|
|
*
|
|
* @param key the key to look for in the map.
|
|
* @return true if the key exists in the map.
|
|
* @throws NullPointerException if the specified key is null.
|
|
*/
|
|
public boolean containsKey(Object key)
|
|
{
|
|
if (key == null)
|
|
throw new
|
|
NullPointerException("This map does not support null keys.");
|
|
if (!(key instanceof String))
|
|
throw new
|
|
ClassCastException("This map only allows queries using Strings.");
|
|
return super.containsKey(key);
|
|
}
|
|
|
|
/**
|
|
* Blocks queries using a null or non-<code>String</code> value.
|
|
* All other queries are forwarded to the superclass.
|
|
*
|
|
* @param value the value to look for in the map.
|
|
* @return true if the value exists in the map.
|
|
* @throws NullPointerException if the specified value is null.
|
|
*/
|
|
public boolean containsValue(Object value)
|
|
{
|
|
if (value == null)
|
|
throw new
|
|
NullPointerException("This map does not support null values.");
|
|
if (!(value instanceof String))
|
|
throw new
|
|
ClassCastException("This map only allows queries using Strings.");
|
|
return super.containsValue(value);
|
|
}
|
|
|
|
/**
|
|
* Returns a set view of the map entries, with the same
|
|
* provisions as for the underlying map.
|
|
*
|
|
* @return a set containing the map entries.
|
|
*/
|
|
public Set<Map.Entry<String,String>> entrySet()
|
|
{
|
|
if (entries == null)
|
|
entries = super.entrySet();
|
|
return entries;
|
|
}
|
|
|
|
/**
|
|
* Blocks queries containing a null or non-<code>String</code> key.
|
|
* All other queries are passed on to the superclass.
|
|
*
|
|
* @param key the key to retrieve the value for.
|
|
* @return the value associated with the given key.
|
|
* @throws NullPointerException if the specified key is null.
|
|
* @throws ClassCastException if the specified key is not a String.
|
|
*/
|
|
public String get(Object key)
|
|
{
|
|
if (key == null)
|
|
throw new
|
|
NullPointerException("This map does not support null keys.");
|
|
if (!(key instanceof String))
|
|
throw new
|
|
ClassCastException("This map only allows queries using Strings.");
|
|
return super.get(key);
|
|
}
|
|
|
|
/**
|
|
* Returns a set view of the keys, with the same
|
|
* provisions as for the underlying map.
|
|
*
|
|
* @return a set containing the keys.
|
|
*/
|
|
public Set<String> keySet()
|
|
{
|
|
if (keys == null)
|
|
keys = new EnvironmentSet(super.keySet());
|
|
return keys;
|
|
}
|
|
|
|
/**
|
|
* Associates the given key to the given value. If the
|
|
* map already contains the key, its value is replaced.
|
|
* The map does not accept null keys or values, or keys
|
|
* and values not of type {@link String}.
|
|
*
|
|
* @param key the key to map.
|
|
* @param value the value to be mapped.
|
|
* @return the previous value of the key, or null if there was no mapping
|
|
* @throws NullPointerException if a key or value is null.
|
|
* @throws ClassCastException if a key or value is not a String.
|
|
*/
|
|
public String put(String key, String value)
|
|
{
|
|
if (key == null)
|
|
throw new NullPointerException("A new key is null.");
|
|
if (value == null)
|
|
throw new NullPointerException("A new value is null.");
|
|
if (!(key instanceof String))
|
|
throw new ClassCastException("A new key is not a String.");
|
|
if (!(value instanceof String))
|
|
throw new ClassCastException("A new value is not a String.");
|
|
return super.put(key, value);
|
|
}
|
|
|
|
/**
|
|
* Removes a key-value pair from the map. The queried key may not
|
|
* be null or of a type other than a <code>String</code>.
|
|
*
|
|
* @param key the key of the entry to remove.
|
|
* @return the removed value.
|
|
* @throws NullPointerException if the specified key is null.
|
|
* @throws ClassCastException if the specified key is not a String.
|
|
*/
|
|
public String remove(Object key)
|
|
{
|
|
if (key == null)
|
|
throw new
|
|
NullPointerException("This map does not support null keys.");
|
|
if (!(key instanceof String))
|
|
throw new
|
|
ClassCastException("This map only allows queries using Strings.");
|
|
return super.remove(key);
|
|
}
|
|
|
|
/**
|
|
* Returns a collection view of the values, with the same
|
|
* provisions as for the underlying map.
|
|
*
|
|
* @return a collection containing the values.
|
|
*/
|
|
public Collection<String> values()
|
|
{
|
|
if (values == null)
|
|
values = new EnvironmentCollection(super.values());
|
|
return values;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* This is a specialised <code>Set</code>, providing
|
|
* the necessary provisions for the collections used by the
|
|
* environment variable map. Namely, it prevents
|
|
* modifications and the use of queries with null
|
|
* or non-<code>String</code> values.
|
|
*
|
|
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
|
*/
|
|
private static class EnvironmentSet
|
|
extends EnvironmentCollection
|
|
implements Set<String>
|
|
{
|
|
|
|
/**
|
|
* Constructs a new environment set, which
|
|
* wraps the elements of the supplied set.
|
|
*
|
|
* @param set the set to use as a base for
|
|
* this set.
|
|
*/
|
|
public EnvironmentSet(Set<String> set)
|
|
{
|
|
super(set);
|
|
}
|
|
|
|
/**
|
|
* This simply calls the same method on the wrapped
|
|
* collection.
|
|
*
|
|
* @param obj the object to compare with.
|
|
* @return true if the two objects are equal.
|
|
*/
|
|
public boolean equals(Object obj)
|
|
{
|
|
return c.equals(obj);
|
|
}
|
|
|
|
/**
|
|
* This simply calls the same method on the wrapped
|
|
* collection.
|
|
*
|
|
* @return the hashcode of the collection.
|
|
*/
|
|
public int hashCode()
|
|
{
|
|
return c.hashCode();
|
|
}
|
|
|
|
} // class EnvironmentSet<String>
|
|
|
|
} // class System
|