diff options
Diffstat (limited to 'libjava/classpath/java/lang/System.java')
-rw-r--r-- | libjava/classpath/java/lang/System.java | 488 |
1 files changed, 485 insertions, 3 deletions
diff --git a/libjava/classpath/java/lang/System.java b/libjava/classpath/java/lang/System.java index 19278aa32cd..ca390bf161b 100644 --- a/libjava/classpath/java/lang/System.java +++ b/libjava/classpath/java/lang/System.java @@ -44,6 +44,14 @@ import gnu.classpath.VMStackWalker; import java.io.InputStream; import java.io.PrintStream; +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; @@ -98,6 +106,11 @@ public final class System 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() @@ -118,6 +131,7 @@ public final class System SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPermission(new RuntimePermission("setIO")); + VMSystem.setIn(in); } @@ -134,8 +148,7 @@ public final class System { SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) - sm.checkPermission(new RuntimePermission("setIO")); - + sm.checkPermission(new RuntimePermission("setIO")); VMSystem.setOut(out); } @@ -221,7 +234,7 @@ public final class System { return VMSystem.currentTimeMillis(); } - + /** * <p> * Returns the current value of a nanosecond-precise system timer. @@ -493,6 +506,60 @@ public final class System } /** + * <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) + { + List<String> environ = (List<String>)VMSystem.environ(); + Map<String,String> variables = new EnvironmentMap(); + for (String pair : environ) + { + String[] parts = pair.split("="); + if (parts.length == 2) + variables.put(parts[0], parts[1]); + else + variables.put(parts[0], ""); + } + 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>. @@ -604,4 +671,419 @@ public final class System return VMRuntime.mapLibraryName(libname); } + + /** + * 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 c 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 |