mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			453 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Java
		
	
	
	
// 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;
 | 
						|
  }
 | 
						|
}
 |