OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / lang / System.java
index 19278aa..ca390bf 100644 (file)
@@ -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