// URLConnection.java - Superclass of all communications links between
//			an application and a URL.

/* Copyright (C) 1999, 2000  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.net;

import java.io.*;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Hashtable;
import java.util.StringTokenizer;
import gnu.gcj.io.MimeTypes;

/**
 * @author Warren Levy <warrenl@cygnus.com>
 * @date March 5, 1999.
 */

/**
 * 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.
 */

public abstract class URLConnection
{
  protected URL url;
  protected boolean doInput = true;
  protected boolean doOutput = false;
  protected boolean allowUserInteraction;
  protected boolean useCaches;
  protected long ifModifiedSince = 0L;
  protected boolean connected = false;
  private static boolean defaultAllowUserInteraction = false;
  private static boolean defaultUseCaches = true;
  private static FileNameMap fileNameMap;  // Set by the URLConnection subclass.
  private static ContentHandlerFactory factory;
  private static ContentHandler contentHandler;
  private static Hashtable handlers = new Hashtable();
  private static Locale locale; 
  private static SimpleDateFormat dateFormat1, dateFormat2, dateFormat3;
  private static boolean dateformats_initialized = false;

  protected URLConnection(URL url)
  {
    this.url = url;
    allowUserInteraction = defaultAllowUserInteraction;
    useCaches = defaultUseCaches;
  }

  public abstract void connect() throws IOException;

  public URL getURL()
  {
    return url;
  }

  public int getContentLength()
  {
    return getHeaderFieldInt("content-length", -1);
  }

  public String getContentType()
  {
    return getHeaderField("content-type");
  }

  public String getContentEncoding()
  {
    return getHeaderField("content-encoding");
  }

  public long getExpiration()
  {
    return getHeaderFieldDate("expiration", 0L);
  }

  public long getDate()
  {
    return getHeaderFieldDate("date", 0L);
  }

  public long getLastModified()
  {
    return getHeaderFieldDate("last-modified", 0L);
  }

  public String getHeaderField(int n)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  public String getHeaderField(String name)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  public int getHeaderFieldInt(String name, int val)
  {
    String str = getHeaderField(name);
    try
      {
	if (str != null)
	  val = Integer.parseInt(str);
      }
    catch (NumberFormatException e)
      {
	; // Do nothing; val is the default.
      }
    return val;
  }

  public long getHeaderFieldDate(String name, long val)
  {
    if (! dateformats_initialized)
      initializeDateFormats();
    String str = getHeaderField(name);
    if (str != null)
      {
        Date date;
	if ((date = dateFormat1.parse(str, new ParsePosition(0))) != null)
	  val = date.getTime();
	else if ((date = dateFormat2.parse(str, new ParsePosition(0))) != null)
	  val = date.getTime();
	else if ((date = dateFormat3.parse(str, new ParsePosition(0))) != null)
	  val = date.getTime();
      }
    return val;
  }

  public String getHeaderFieldKey(int n)
  {
    // Subclasses for specific protocols override this.
    return null;
  }

  public Object getContent() throws IOException
  {
    // 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 cType = getContentType();
    contentHandler = setContentHandler(cType);
    if (contentHandler == null)
      return getInputStream();

    return contentHandler.getContent(this);
  }

// TODO12:  public Permission getPermission() throws IOException
//   {
//     // Subclasses may override this.
//     return java.security.AllPermission;
//   }

  public InputStream getInputStream() throws IOException
  {
    // Subclasses for specific protocols override this.
    throw new UnknownServiceException("Protocol " + url.getProtocol() +
			" does not support input.");
  }

  public OutputStream getOutputStream() throws IOException
  {
    // Subclasses for specific protocols override this.
    throw new UnknownServiceException("Protocol " + url.getProtocol() +
			" does not support output.");
  }

  public String toString()
  {
    return this.getClass().getName() + ":" + url.toString();
  }

  public void setDoInput(boolean doinput)
  {
    if (connected)
      throw new IllegalAccessError("Already connected");

    doInput = doinput;
  }

  public boolean getDoInput()
  {
    return doInput;
  }

  public void setDoOutput(boolean dooutput)
  {
    if (connected)
      throw new IllegalAccessError("Already connected");

    doOutput = dooutput;
  }

  public boolean getDoOutput()
  {
    return doOutput;
  }

  public void setAllowUserInteraction(boolean allowuserinteraction)
  {
    if (connected)
      throw new IllegalAccessError("Already connected");

    allowUserInteraction = allowuserinteraction;
  }

  public boolean getAllowUserInteraction()
  {
    return allowUserInteraction;
  }

  public static void
    setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
  {
    defaultAllowUserInteraction = defaultallowuserinteraction;
  }

  public static boolean getDefaultAllowUserInteraction()
  {
    return defaultAllowUserInteraction;
  }

  public void setUseCaches(boolean usecaches)
  {
    if (connected)
      throw new IllegalAccessError("Already connected");

    useCaches = usecaches;
  }

  public boolean getUseCaches()
  {
    return useCaches;
  }

  public void setIfModifiedSince(long ifmodifiedsince)
  {
    if (connected)
      throw new IllegalAccessError("Already connected");

    ifModifiedSince = ifmodifiedsince;
  }

  public long getIfModifiedSince()
  {
    return ifModifiedSince;
  }

  public boolean getDefaultUseCaches()
  {
    return defaultUseCaches;
  }

  public void setDefaultUseCaches(boolean defaultusecaches)
  {
    defaultUseCaches = defaultusecaches;
  }

  public void setRequestProperty(String key, String value)
  {
    // Do nothing unless overridden by subclasses that support setting
    // header fields in the request.
  }

  public String getRequestProperty(String key)
  {
    // Overridden by subclasses that support reading header fields from the
    // request.
    return null;
  }

  public static void setDefaultRequestProperty(String key, String value)
  {
    // Do nothing unless overridden by subclasses that support setting
    // default request properties.
  }

  public static String getDefaultRequestProperty(String key)
  {
    // Overridden by subclasses that support default request properties.
    return null;
  }

  public static void setContentHandlerFactory(ContentHandlerFactory fac)
  {
    if (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();
    factory = fac;
  }

  protected static String guessContentTypeFromName(String fname)
  {
    int dot = fname.lastIndexOf (".");
    
    if (dot != -1)
      {
	if (dot == fname.length())
	  return ("application/octet-stream");
	else
	  fname = fname.substring (dot + 1);
      }
    
    String type = MimeTypes.getMimeTypeFromExtension (fname);
    
    if (type == null)
      return("application/octet-stream");

    return(type);
  }

// TODO:  public static String guessContentTypeFromStream(InputStream is)
//          throws IOException
//   {
//   }

// TODO12:  protected void parseURL(URL u, String spec, int start, int limit)

  // JDK1.2
  public static FileNameMap getFileNameMap()
  {
    return fileNameMap;
  }

  // JDK1.2
  public static void setFileNameMap(FileNameMap map)
  {
    // Throw an exception if an extant security mgr precludes
    // setting the factory.
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkSetFactory();

    fileNameMap = map;
  }

  private ContentHandler setContentHandler(String contentType)
  {
    ContentHandler handler;

    // No content type so just handle it as the default.
    if (contentType == null || contentType == "")
      return null;

    // See if a handler has been cached for this content type.
    // For efficiency, if a content type has been searched for but not
    // found, it will be in the hash table but as the contentType String
    // instead of a ContentHandler.
    if ((handler = (ContentHandler) handlers.get(contentType)) != null)
      if (handler instanceof ContentHandler)
	return handler;
      else
	return null;

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

    // Non-default factory may have returned null or a factory wasn't set.
    // Use the default search algorithm to find a handler for this content type.
    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 = System.getProperty("java.content.handler.pkgs");
	propVal = (propVal == null) ? "" : (propVal + "|");
	propVal = propVal + "gnu.gcj.content|sun.net.www.content";

	// Replace the '/' character in the content type with '.' and
	// all other non-alphabetic, non-numeric characters with '_'.
	StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
	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.
	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 ||
		    ! (handler instanceof ContentHandler)) &&
		   pkgPrefix.hasMoreTokens());
      }

    // Update the hashtable with the new content handler.
    if (handler != null && handler instanceof ContentHandler)
      {
	handlers.put(contentType, handler);
	return handler;
      }

    // For efficiency on subsequent searches, put a dummy entry in the hash
    // table for content types that don't have a non-default ContentHandler.
    handlers.put(contentType, contentType);
    return null;
  }
  
  // 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 synchronized void initializeDateFormats()
  {
    if (dateformats_initialized)
      return;
    locale = new Locale("En", "Us", "Unix");
    dateFormat1 = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", 
                                       locale);
    dateFormat2 = new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", 
                                       locale);
    dateFormat3 = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
    dateformats_initialized = true;
  }
}
