/* URLConnection.java -- Abstract superclass for reading from URL's
   Copyright (C) 1998, 2002, 2003, 2004, 2006 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.net;

import gnu.classpath.SystemProperties;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AllPermission;
import java.security.Permission;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Written using on-line Java Platform 1.2 API Specification, as well
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
 * Status:  One guessContentTypeFrom... methods not implemented.
 *    getContent method assumes content type from response; see comment there.
 */
/**
 * This class models a connection that retrieves the information pointed
 * to by a URL object.  This is typically a connection to a remote node
 * on the network, but could be a simple disk read.
 * <p>
 * A URLConnection object is normally created by calling the openConnection()
 * method of a URL object.  This method is somewhat misnamed because it does
 * not actually open the connection.  Instead, it return an unconnected
 * instance of this object.  The caller then has the opportunity to set
 * various connection options prior to calling the actual connect() method.
 * <p>
 * After the connection has been opened, there are a number of methods in
 * this class that access various attributes of the data, typically
 * represented by headers sent in advance of the actual data itself.
 * <p>
 * Also of note are the getInputStream and getContent() methods which allow
 * the caller to retrieve the actual data from the connection.  Note that
 * for some types of connections, writing is also allowed.  The setDoOutput()
 * method must be called prior to connecing in order to enable this, then
 * the getOutputStream method called after the connection in order to
 * obtain a stream to write the output to.
 * <p>
 * The getContent() method is of particular note.  This method returns an
 * Object that encapsulates the data returned.  There is no way do determine
 * the type of object that will be returned in advance.  This is determined
 * by the actual content handlers as described in the description of that
 * method.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Warren Levy (warrenl@cygnus.com)
 */
public abstract class URLConnection
{
  /**
   * This is an object that maps filenames to MIME types.  The interface
   * to do this is implemented by this class, so just create an empty
   * instance and store it here.
   */
  private static FileNameMap fileNameMap;

  /**
   * This is the ContentHandlerFactory set by the caller, if any
   */
  private static ContentHandlerFactory factory;

  /**
   * This is the default value that will be used to determine whether or
   * not user interaction should be allowed.
   */
  private static boolean defaultAllowUserInteraction;

  /**
   * This is the default flag indicating whether or not to use caches to
   * store the data returned from a server
   */
  private static boolean defaultUseCaches = true;

  /**
   * Default internal content handler factory.
   */
  private static ContentHandlerFactory defaultFactory
    = new gnu.java.net.DefaultContentHandlerFactory();

  /**
   * This variable determines whether or not interaction is allowed with
   * the user.  For example, to prompt for a username and password.
   */
  protected boolean allowUserInteraction;

  /**
   * Indicates whether or not a connection has been established to the
   * destination specified in the URL
   */
  protected boolean connected;

  /**
   * Indicates whether or not input can be read from this URL
   */
  protected boolean doInput = true;

  /**
   * Indicates whether or not output can be sent to this URL
   */
  protected boolean doOutput;

  /**
   * If this flag is set, the protocol is allowed to cache data whenever
   * it can (caching is not guaranteed). If it is not set, the protocol
   * must a get a fresh copy of the data.
   * <p>
   * This field is set by the setUseCaches method and returned by the
   * getUseCaches method.
   *
   * Its default value is that determined by the last invocation of
   * setDefaultUseCaches
   */
  protected boolean useCaches;

  /**
   * If this value is non-zero, then the connection will only attempt to
   * fetch the document pointed to by the URL if the document has been
   * modified more recently than the date set in this variable.  That date
   * should be specified as the number of seconds since 1/1/1970 GMT.
   */
  protected long ifModifiedSince;

  /**
   * This is the URL associated with this connection
   */
  protected URL url;

  private static SimpleDateFormat[] dateFormats;
  private static boolean dateformats_initialized;
  
  /**
   * The connection timeout period.
   */
  private int connectTimeout;

  /**
   * The read timeout period.
   */
  private int readTimeout;

  /* Cached ParsePosition, used when parsing dates. */
  private ParsePosition position;

  /**
   * Creates a URL connection to a given URL. A real connection is not made.
   * Use <code>connect()</code> to do this.
   *
   * @param url The Object to create the URL connection to
   *
   * @see URLConnection#connect()
   */
  protected URLConnection(URL url)
  {
    // Set up all our instance variables
    this.url = url;
    allowUserInteraction = defaultAllowUserInteraction;
    useCaches = defaultUseCaches;
  }

  /**
   * Establishes the actual connection to the URL associated with this
   * connection object
   *
   * @exception IOException if an error occurs
   */
  public abstract void connect() throws IOException;

  /**
   * Returns the URL object associated with this connection
   *
   * @return The URL for this connection.
   */
  public URL getURL()
  {
    return url;
  }

  /**
   * Returns the connection timeout speed, in milliseconds, or zero if
   * the timeout is infinite or not set.
   *
   * @return The timeout.
   *
   * @since 1.5
   */
  public int getConnectTimeout()
  {
    return connectTimeout;
  }

  /**
   * Set the connection timeout speed, in milliseconds, or zero if the timeout
   * is to be considered infinite. Note that in certain socket 
   * implementations/platforms this method may not have any effect.
   *
   * Throws an <code>IllegalArgumentException</code> if timeout < 0.
   *
   * @param timeout the timeout, in milliseconds.
   *
   * @since 1.5
   */
  public void setConnectTimeout(int timeout)
    throws IllegalArgumentException
  {
    if( timeout < 0 )
      throw new IllegalArgumentException("Timeout must be 0 or positive.");
    connectTimeout = timeout;
  }

  /**
   * Returns the read timeout, in milliseconds, or zero if the timeout
   * is infinite or not set.
   *
   * @return The timeout.
   *
   * @see #setReadTimeout
   *
   * @since 1.5
   */
  public int getReadTimeout()
  {
    return readTimeout;
  }

  /**
   * Set the read timeout, in milliseconds, or zero if the timeout
   * is to be considered infinite. Note that in certain socket 
   * implementations/platforms this method may not have any effect.
   *
   * Throws an <code>IllegalArgumentException</code> if timeout < 0.
   *
   * @param timeout - The timeout, in milliseconds.
   *
   * @throws IllegalArgumentException if timeout is negative.
   *
   * @see #getReadTimeout
   *
   * @since 1.5
   */
  public void setReadTimeout(int timeout)
    throws IllegalArgumentException
  {
    if( timeout < 0 )
      throw new IllegalArgumentException("Timeout must be 0 or positive.");
    readTimeout = timeout;
  }

  /**
   * Returns the value of the content-length header field or -1 if the value
   * is not known or not present.
   *
   * @return The content-length field
   */
  public int getContentLength()
  {
    return getHeaderFieldInt("content-length", -1);
  }

  /**
   * Returns the the content-type of the data pointed to by the URL.  This
   * method first tries looking for a content-type header.  If that is not
   * present, it attempts to use the file name to determine the content's
   * MIME type.  If that is unsuccessful, the method returns null.  The caller
   * may then still attempt to determine the MIME type by a call to
   * guessContentTypeFromStream()
   *
   * @return The content MIME type
   */
  public String getContentType()
  {
    return getHeaderField("content-type");
  }

  /**
   * Returns the value of the content-encoding field or null if it is not
   * known or not present.
   *
   * @return The content-encoding field
   */
  public String getContentEncoding()
  {
    return getHeaderField("content-encoding");
  }

  /**
   * Returns the value of the expires header or 0 if not known or present.
   * If populated, the return value is number of seconds since midnight
   * on 1/1/1970 GMT.
   *
   * @return The expiration time.
   */
  public long getExpiration()
  {
    return getHeaderFieldDate("expires", 0L);
  }

  /**
   * Returns the date of the document pointed to by the URL as reported in
   * the date field of the header or 0 if the value is not present or not
   * known. If populated, the return value is number of seconds since
   * midnight on 1/1/1970 GMT.
   *
   * @return The document date
   */
  public long getDate()
  {
    return getHeaderFieldDate("date", 0L);
  }

  /**
   * Returns the value of the last-modified header field or 0 if not known known
   * or not present.  If populated, the return value is the number of seconds
   * since midnight on 1/1/1970.
   *
   * @return The last modified time
   */
  public long getLastModified()
  {
    return getHeaderFieldDate("last-modified", 0L);
  }

  /**
   * Return a String representing the header value at the specified index.
   * This allows the caller to walk the list of header fields.  The analogous
   * {@link #getHeaderField(int)} method allows access to the corresponding 
   * key for this header field
   *
   * @param index The index into the header field list to retrieve the value for
   *
   * @return The header value or null if index is past the end of the headers
   */
  public String getHeaderField(int index)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  /**
   * Returns a String representing the value of the header field having
   * the named key.  Returns null if the header field does not exist.
   *
   * @param name The key of the header field
   *
   * @return The value of the header field as a String
   */
  public String getHeaderField(String name)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  /**
   * Returns an unmodifiable Map containing all sent header fields.
   * 
   * @return The map of header fields. The map consists of String keys with 
   * an unmodifiable List of String objects as value.
   *
   * @since 1.4
   */
  public Map<String,List<String>> getHeaderFields()
  {
    // Subclasses for specific protocols override this.
    return Collections.emptyMap();
  }

  /**
   * Returns the value of the named header field as an int.  If the field
   * is not present or cannot be parsed as an integer, the default value
   * will be returned.
   *
   * @param name The header field key to lookup
   * @param defaultValue The defaule value if the header field is not found
   * or can't be parsed.
   *
   * @return The value of the header field or the default value if the field
   * is missing or malformed
   */
  public int getHeaderFieldInt(String name, int defaultValue)
  {
    String value = getHeaderField(name);

    if (value == null)
      return defaultValue;

    try
      {
	return Integer.parseInt(value);
      }
    catch (NumberFormatException e)
      {
	return defaultValue;
      }
  }

  /**
   * Returns the value of the named header field as a date.  This date will
   * be the number of seconds since midnight 1/1/1970 GMT or the default
   * value if the field is not present or cannot be converted to a date.
   *
   * @param name The name of the header field
   * @param defaultValue The default date if the header field is not found
   * or can't be converted.
   *
   * @return The date value of the header filed or the default value
   * if the field is missing or malformed
   */
  public long getHeaderFieldDate(String name, long defaultValue)
  {
    if (! dateformats_initialized)
      initializeDateFormats();

    if (position == null)
      position = new ParsePosition(0);

    long result = defaultValue;
    String str = getHeaderField(name);

    if (str != null)
      {
	for (int i = 0; i < dateFormats.length; i++)
	  {
	    SimpleDateFormat df = dateFormats[i];
	    position.setIndex(0);
	    position.setErrorIndex(0);
	    Date date = df.parse(str, position);
	    if (date != null)
	      return date.getTime();
	  }
      }

    return result;
  }

  /**
   * Returns a String representing the header key at the specified index.
   * This allows the caller to walk the list of header fields.  The analogous
   * {@link #getHeaderField(int)} method allows access to the corresponding 
   * value for this tag.
   *
   * @param index The index into the header field list to retrieve the key for.
   *
   * @return The header field key or null if index is past the end
   * of the headers.
   */
  public String getHeaderFieldKey(int index)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  /**
   * This method returns the content of the document pointed to by the
   * URL as an Object.  The type of object depends on the MIME type of
   * the object and particular content hander loaded.  Most text type
   * content handlers will return a subclass of
   * <code>InputStream</code>.  Images usually return a class that
   * implements <code>ImageProducer</code>.  There is not guarantee
   * what type of object will be returned, however.
   *
   * <p>This class first determines the MIME type of the content, then
   * creates a ContentHandler object to process the input.  If the
   * <code>ContentHandlerFactory</code> is set, then that object is
   * called to load a content handler, otherwise a class called
   * gnu.java.net.content.&lt;content_type&gt; is tried.  If this
   * handler does not exist, the method will simple return the
   * <code>InputStream</code> returned by
   * <code>getInputStream()</code>.  Note that the default
   * implementation of <code>getInputStream()</code> throws a
   * <code>UnknownServiceException</code> so subclasses are encouraged
   * to override this method.</p>
   *
   * @return the content
   *
   * @exception IOException If an error with the connection occurs.
   * @exception UnknownServiceException If the protocol does not support the
   * content type at all.
   */
  public Object getContent() throws IOException
  {
    if (!connected)
      connect();

    // FIXME: Doc indicates that other criteria should be applied as
    // heuristics to determine the true content type, e.g. see 
    // guessContentTypeFromName() and guessContentTypeFromStream methods
    // as well as FileNameMap class & fileNameMap field & get/set methods.
    String type = getContentType();
    ContentHandler ch = getContentHandler(type);

    if (ch != null)
      return ch.getContent(this);

    return getInputStream();
  }

  /**
   * Retrieves the content of this URLConnection
   *
   * @param classes The allowed classes for the content
   *
   * @return the content
   *
   * @exception IOException If an error occurs
   * @exception UnknownServiceException If the protocol does not support the
   * content type
   */
  public Object getContent(Class[] classes)
    throws IOException
  {
    if (! connected)
      connect();
    String type = getContentType();
    ContentHandler ch = getContentHandler(type);
    if (ch != null)
      return ch.getContent(this, classes);
    throw new UnknownServiceException("protocol does not support the content type");
  }

  /**
   * This method returns a <code>Permission</code> object representing the
   * permissions required to access this URL.  This method returns
   * <code>java.security.AllPermission</code> by default.  Subclasses should
   * override it to return a more specific permission.  For example, an
   * HTTP URL should return an instance of <code>SocketPermission</code>
   * for the appropriate host and port.
   * <p>
   * Note that because of items such as HTTP redirects, the permission
   * object returned might be different before and after connecting.
   *
   * @return A Permission object
   *
   * @exception IOException If the computation of the permission requires
   * network or file I/O and an exception occurs while computing it
   */
  public Permission getPermission() throws IOException
  {
    // Subclasses may override this.
    return new AllPermission();
  }

  /**
   * Returns an InputStream for this connection.  As this default
   * implementation returns null, subclasses should override this method
   *
   * @return An InputStream for this connection
   *
   * @exception IOException If an error occurs
   * @exception UnknownServiceException If the protocol does not support input
   */
  public InputStream getInputStream() throws IOException
  {
    // Subclasses for specific protocols override this.
    throw new UnknownServiceException("Protocol " + url.getProtocol()
                                      + " does not support input.");
  }

  /**
   * Returns an OutputStream for this connection.  As this default
   * implementation returns null, subclasses should override this method
   *
   * @return An OutputStream for this connection
   *
   * @exception IOException If an error occurs
   * @exception UnknownServiceException If the protocol does not support output
   */
  public OutputStream getOutputStream() throws IOException
  {
    // Subclasses for specific protocols override this.
    throw new UnknownServiceException("Protocol " + url.getProtocol()
                                      + " does not support output.");
  }

  /**
   * The methods prints the value of this object as a String by calling the
   * toString() method of its associated URL.  Overrides Object.toString()
   *
   * @return A String representation of this object
   */
  public String toString()
  {
    return this.getClass().getName() + ":" + url.toString();
  }

  /**
   * Sets the value of a flag indicating whether or not input is going
   * to be done for this connection.  This default to true unless the
   * doOutput flag is set to false, in which case this defaults to false.
   *
   * @param input <code>true</code> if input is to be done,
   * <code>false</code> otherwise
   *
   * @exception IllegalStateException If already connected
   */
  public void setDoInput(boolean input)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    doInput = input;
  }

  /**
   * Returns the value of a flag indicating whether or not input is going
   * to be done for this connection.  This default to true unless the
   * doOutput flag is set to false, in which case this defaults to false.
   *
   * @return true if input is to be done, false otherwise
   */
  public boolean getDoInput()
  {
    return doInput;
  }

  /**
   * Sets a boolean flag indicating whether or not output will be done
   * on this connection.  The default value is false, so this method can
   * be used to override the default
   *
   * @param output ture if output is to be done, false otherwise
   *
   * @exception IllegalStateException If already connected
   */
  public void setDoOutput(boolean output)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    doOutput = output;
  }

  /**
   * Returns a boolean flag indicating whether or not output will be done
   * on this connection.  This defaults to false.
   *
   * @return true if output is to be done, false otherwise
   */
  public boolean getDoOutput()
  {
    return doOutput;
  }

  /**
   * Sets a boolean flag indicating whether or not user interaction is
   * allowed for this connection.  (For example, in order to prompt for
   * username and password info.
   *
   * @param allow true if user interaction should be allowed, false otherwise.
   *
   * @exception IllegalStateException If already connected
   */
  public void setAllowUserInteraction(boolean allow)
  {
    if (connected)
      throw new IllegalStateException("Already connected");
    
    allowUserInteraction = allow;
  }

  /**
   * Returns a boolean flag indicating whether or not user interaction is
   * allowed for this connection.  (For example, in order to prompt for
   * username and password info.
   *
   * @return true if user interaction is allowed, false otherwise
   */
  public boolean getAllowUserInteraction()
  {
    return allowUserInteraction;
  }

  /**
   * Sets the default flag for whether or not interaction with a user
   * is allowed.  This will be used for all connections unless overridden
   *
   * @param allow true to allow user interaction, false otherwise
   */
  public static void setDefaultAllowUserInteraction(boolean allow)
  {
    defaultAllowUserInteraction = allow;
  }

  /**
   * Returns the default flag for whether or not interaction with a user
   * is allowed.  This will be used for all connections unless overridden
   *
   * @return true if user interaction is allowed, false otherwise
   */
  public static boolean getDefaultAllowUserInteraction()
  {
    return defaultAllowUserInteraction;
  }

  /**
   * Sets a boolean flag indicating whether or not caching will be used
   * (if possible) to store data downloaded via the connection.
   *
   * @param usecaches The new value
   *
   * @exception IllegalStateException If already connected
   */
  public void setUseCaches(boolean usecaches)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    useCaches = usecaches;
  }

  /**
   * Returns a boolean flag indicating whether or not caching will be used
   * (if possible) to store data downloaded via the connection.
   *
   * @return true if caching should be used if possible, false otherwise
   */
  public boolean getUseCaches()
  {
    return useCaches;
  }

  /**
   * Sets the ifModified since instance variable.  If this value is non
   * zero and the underlying protocol supports it, the actual document will
   * not be fetched unless it has been modified since this time.  The value
   * passed should  be 0 if this feature is to be disabled or the time expressed
   * as the number of seconds since midnight 1/1/1970 GMT otherwise.
   *
   * @param ifmodifiedsince The new value in milliseconds
   * since January 1, 1970 GMT
   *
   * @exception IllegalStateException If already connected
   */
  public void setIfModifiedSince(long ifmodifiedsince)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    ifModifiedSince = ifmodifiedsince;
  }

  /**
   * Returns the ifModified since instance variable.  If this value is non
   * zero and the underlying protocol supports it, the actual document will
   * not be fetched unless it has been modified since this time.  The value
   * returned will be 0 if this feature is disabled or the time expressed
   * as the number of seconds since midnight 1/1/1970 GMT otherwise
   *
   * @return The ifModifiedSince value
   */
  public long getIfModifiedSince()
  {
    return ifModifiedSince;
  }

  /**
   * Returns the default value used to determine whether or not caching
   * of documents will be done when possible.
   *
   * @return true if caches will be used, false otherwise
   */
  public boolean getDefaultUseCaches()
  {
    return defaultUseCaches;
  }

  /**
   * Sets the default value used to determine whether or not caching
   * of documents will be done when possible.
   *
   * @param use true to use caches if possible by default, false otherwise
   */
  public void setDefaultUseCaches(boolean use)
  {
    defaultUseCaches = use;
  }

  /**
   * Sets the value of the named request property. 
   * This method does overwrite the value of existing properties with 
   * the new value.
   *
   * @param key The name of the property
   * @param value The value of the property
   *
   * @exception IllegalStateException If already connected
   * @exception NullPointerException If key is null
   *
   * @see URLConnection#getRequestProperty(String key)
   * @see URLConnection#addRequestProperty(String key, String value)
   *
   * @since 1.4
   */
  public void setRequestProperty(String key, String value)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    if (key == null)
      throw new NullPointerException("key is null");

    // Do nothing unless overridden by subclasses that support setting
    // header fields in the request.
  }

  /**
   * Adds a new request property by a key/value pair.
   * This method does not overwrite existing properties with the same key.
   *
   * @param key Key of the property to add
   * @param value Value of the Property to add
   *
   * @exception IllegalStateException If already connected
   * @exception NullPointerException If key is null
   *
   * @see URLConnection#getRequestProperty(String)
   * @see URLConnection#setRequestProperty(String, String)
   *
   * @since 1.4
   */
  public void addRequestProperty(String key, String value)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    if (key == null)
      throw new NullPointerException("key is null");

    // Do nothing unless overridden by subclasses that support adding
    // header fields in the request.
  }

  /**
   * Returns the value of the named request property.
   *
   * @param key The name of the property
   *
   * @return Value of the property, or <code>null</code> if key is null.
   *
   * @exception IllegalStateException If already connected
   *
   * @see URLConnection#setRequestProperty(String, String)
   * @see URLConnection#addRequestProperty(String, String)
   */
  public String getRequestProperty(String key)
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    // Overridden by subclasses that support reading header fields from the
    // request.
    return null;
  }

  /**
   * Returns an unmodifiable Map containing the request properties.
   * 
   * @return The map of properties. The map consists of String keys with an 
   * unmodifiable List of String objects as value.
   *
   * @exception IllegalStateException If already connected
   *
   * @since 1.4
   */
  public Map<String,List<String>> getRequestProperties()
  {
    if (connected)
      throw new IllegalStateException("Already connected");

    // Overridden by subclasses that support reading header fields from the
    // request.
    return Collections.emptyMap();
  }

  /**
   * Sets the default value of a request property.  This will be used
   * for all connections unless the value of the property is manually
   * overridden.
   *
   * @param key The request property name the default is being set for
   * @param value The value to set the default to
   *
   * @deprecated 1.3 The method setRequestProperty should be used instead.
   * This method does nothing now.
   *
   * @see URLConnection#setRequestProperty(String, String)
   */
  public static void setDefaultRequestProperty(String key, String value)
  {
    // This method does nothing since JDK 1.3.
  }

  /**
   * Returns the default value of a request property.  This will be used
   * for all connections unless the value of the property is manually
   * overridden.
   *
   * @param key The request property to return the default value of
   *
   * @return The value of the default property or null if not available
   *
   * @deprecated 1.3 The method getRequestProperty should be used instead.
   * This method does nothing now.
   *
   * @see URLConnection#getRequestProperty(String)
   */
  public static String getDefaultRequestProperty(String key)
  {
    // This method does nothing since JDK 1.3.
    return null;
  }

  /**
   * Sets the ContentHandlerFactory for an application.  This can be called
   * once and only once.  If it is called again, then an Error is thrown.
   * Unlike for other set factory methods, this one does not do a security
   * check prior to setting the factory.
   *
   * @param factory The ContentHandlerFactory for this application
   *
   * @exception Error If the factory has already been defined
   * @exception SecurityException If a security manager exists and its
   * checkSetFactory method doesn't allow the operation
   */
  public static synchronized void setContentHandlerFactory(ContentHandlerFactory factory)
  {
    if (URLConnection.factory != null)
      throw new Error("ContentHandlerFactory already set");

    // Throw an exception if an extant security mgr precludes
    // setting the factory.
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkSetFactory();

    URLConnection.factory = factory;
  }

  /**
   * Returns the MIME type of a file based on the name of the file.  This
   * works by searching for the file's extension in a list of file extensions
   * and returning the MIME type associated with it.  If no type is found,
   * then a MIME type of "application/octet-stream" will be returned.
   *
   * @param filename The filename to determine the MIME type for
   *
   * @return The MIME type String
   *
   * @specnote public since JDK 1.4
   */
  public static String guessContentTypeFromName(String filename)
  {
    return getFileNameMap().getContentTypeFor(filename.toLowerCase());
  }

  /**
   * Returns the MIME type of a stream based on the first few characters
   * at the beginning of the stream.  This routine can be used to determine
   * the MIME type if a server is believed to be returning an incorrect
   * MIME type.  This method returns "application/octet-stream" if it
   * cannot determine the MIME type.
   * <p>
   * NOTE: Overriding MIME types sent from the server can be obnoxious
   * to user's.  See Internet Exploder 4 if you don't believe me.
   *
   * @param is The InputStream to determine the MIME type from
   *
   * @return The MIME type
   *
   * @exception IOException If an error occurs
   */
  public static String guessContentTypeFromStream(InputStream is)
    throws IOException
  {
    String result = VMURLConnection.guessContentTypeFromStream(is);
    if (result == null)
      return "application/octet-stream";
    return result;
  }

  /**
   * This method returns the <code>FileNameMap</code> object being used
   * to decode MIME types by file extension.
   *
   * @return The <code>FileNameMap</code>.
   *
   * @since 1.2
   */
  public static synchronized FileNameMap getFileNameMap()
  {
    // Delayed initialization.
    if (fileNameMap == null)
      fileNameMap = new MimeTypeMapper();

    return fileNameMap;
  }

  /**
   * This method sets the <code>FileNameMap</code> object being used
   * to decode MIME types by file extension.
   *
   * @param map The <code>FileNameMap</code>.
   *
   * @exception SecurityException If a security manager exists and its
   * checkSetFactory method doesn't allow the operation
   *
   * @since 1.2
   */
  public static synchronized void setFileNameMap(FileNameMap map)
  {
    // Throw an exception if an extant security manager precludes
    // setting the factory.
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkSetFactory();

    fileNameMap = map;
  }

  private ContentHandler getContentHandler(String contentType)
  {
    // No content type so just handle it as the default.
    if (contentType == null || contentType.equals(""))
      return null;

    ContentHandler handler = null;

    // If a non-default factory has been set, use it.
    if (factory != null)
      handler = factory.createContentHandler(contentType);

    // Now try default factory. Using this factory to instantiate built-in
    // content handlers is preferable  
    if (handler == null)
      handler = defaultFactory.createContentHandler(contentType);

    // User-set factory has not returned a handler. Use the default search 
    // algorithm.
    if (handler == null)
      {
        // Get the list of packages to check and append our default handler
        // to it, along with the JDK specified default as a last resort.
        // Except in very unusual environments the JDK specified one shouldn't
        // ever be needed (or available).
        String propVal = SystemProperties.getProperty("java.content.handler.pkgs");
        propVal = (((propVal == null) ? "" : (propVal + "|"))
                   + "gnu.java.net.content|sun.net.www.content");

        // Deal with "Content-Type: text/html; charset=ISO-8859-1".
        int parameterBegin = contentType.indexOf(';');
        if (parameterBegin >= 1)
          contentType = contentType.substring(0, parameterBegin);
        contentType = contentType.trim();

        // Replace the '/' character in the content type with '.' and
        // all other non-alphabetic, non-numeric characters with '_'.
        char[] cArray = contentType.toCharArray();
        for (int i = 0; i < cArray.length; i++)
          {
            if (cArray[i] == '/')
              cArray[i] = '.';
            else if (! ((cArray[i] >= 'A' && cArray[i] <= 'Z') || 
                        (cArray[i] >= 'a' && cArray[i] <= 'z') ||
                        (cArray[i] >= '0' && cArray[i] <= '9')))
              cArray[i] = '_';
          }
        String contentClass = new String(cArray);

        // See if a class of this content type exists in any of the packages.
        StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
        do
          {
            String facName = pkgPrefix.nextToken() + "." + contentClass;
            try
              {
                handler =
                  (ContentHandler) Class.forName(facName).newInstance();
              }
            catch (Exception e)
              {
                // Can't instantiate; handler still null, go on to next element.
              }
          } while (handler == null && pkgPrefix.hasMoreTokens());
      }

    return handler;
  }
  
  // We don't put these in a static initializer, because it creates problems
  // with initializer co-dependency: SimpleDateFormat's constructors
  // eventually depend on URLConnection (via the java.text.*Symbols classes).
  private static synchronized void initializeDateFormats()
  {
    if (dateformats_initialized)
      return;

    Locale locale = new Locale("En", "Us", "Unix");
    dateFormats = new SimpleDateFormat[3];
    dateFormats[0] =
      new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
    dateFormats[1] =
      new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
    dateFormats[2] = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
    dateformats_initialized = true;
  }
}
