summaryrefslogtreecommitdiff
path: root/libjava/java/net/URLConnection.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/net/URLConnection.java')
-rw-r--r--libjava/java/net/URLConnection.java423
1 files changed, 423 insertions, 0 deletions
diff --git a/libjava/java/net/URLConnection.java b/libjava/java/net/URLConnection.java
new file mode 100644
index 00000000000..12e8a8b4cc6
--- /dev/null
+++ b/libjava/java/net/URLConnection.java
@@ -0,0 +1,423 @@
+// URLConnection.java - Superclass of all communications links between
+// an application and a URL.
+
+/* Copyright (C) 1999 Cygnus Solutions
+
+ 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;
+
+/**
+ * @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: Two 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 = new Locale("En", "Us", "Unix");
+ private static SimpleDateFormat dateFormat1 =
+ new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
+ private static SimpleDateFormat dateFormat2 =
+ new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
+ private static SimpleDateFormat dateFormat3 =
+ new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
+
+ 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)
+ {
+ 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;
+ if (doOutput)
+ doInput = false;
+ }
+
+ 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;
+ }
+
+// TODO: protected static String guessContentTypeFromName(String fname)
+// {
+// }
+
+// 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;
+ }
+}