/* 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;
  }
}
