I'm checking this in.
I went ahead and removed the cache. I doubt this is very important.
This also fixes the /etc/mime.types problem by adding a new system
property. The reference implementation only sets this for Linux. We
need a more sophisticated way to handle OS variances here... but I
think this sort of problem occurs in a few places.
Tom
2006-04-05 Tom Tromey <[EMAIL PROTECTED]>
* java/net/MimeTypeMapper.java (MimeTypeMapper): Look for system
property with mime.types name.
* gnu/classpath/SystemProperties.java: Set
gnu.classpath.mime.types.file if not already set.
* java/net/URLConnection.java (defaultFactory): New field.
(guessContentTypeFromStream): Mark as unimplemented.
(getContentHandler): Updated with libgcj's implementation.
* gnu/java/net/DefaultContentHandlerFactory.java: New file,
from libgcj.
Index: gnu/classpath/SystemProperties.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/classpath/SystemProperties.java,v
retrieving revision 1.11
diff -u -r1.11 SystemProperties.java
--- gnu/classpath/SystemProperties.java 7 Mar 2006 22:21:00 -0000 1.11
+++ gnu/classpath/SystemProperties.java 5 Apr 2006 20:11:29 -0000
@@ -111,6 +111,13 @@
defaultProperties.put("java.io.tmpdir",
defaultProperties.get("java.tmpdir"));
+ // FIXME: we need a better way to handle this.
+ // For instance, having a single VM class for each OS might help.
+ if (defaultProperties.get("gnu.classpath.mime.types.file") == null
+ && "Linux".equals(defaultProperties.get("os.name")))
+ defaultProperties.put("gnu.classpath.mime.types.file",
+ "/etc/mime.types");
+
VMSystemProperties.postInit(defaultProperties);
// Note that we use clone here and not new. Some programs assume
Index: java/net/MimeTypeMapper.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/MimeTypeMapper.java,v
retrieving revision 1.9
diff -u -r1.9 MimeTypeMapper.java
--- java/net/MimeTypeMapper.java 5 Apr 2006 00:20:29 -0000 1.9
+++ java/net/MimeTypeMapper.java 5 Apr 2006 20:11:31 -0000
@@ -37,6 +37,8 @@
package java.net;
+import gnu.classpath.SystemProperties;
+
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
@@ -240,18 +242,19 @@
for (int i = 0; i < mime_strings.length; i++)
mime_types.put(mime_strings[i][0], mime_strings[i][1]);
- // Now read from /etc/mime.types, if it exists. Entries found
+ // Now read from the system mime database, if it exists. Entries found
// here override our internal ones.
try
{
- fillFromFile(mime_types, "/etc/mime.types");
+ // On Linux this usually means /etc/mime.types.
+ String file
+ = SystemProperties.getProperty("gnu.classpath.mime.types.file");
+ if (file != null)
+ fillFromFile(mime_types, file);
}
catch (IOException ignore)
{
}
-
- // FIXME: should read ~/.mime.types.
- // FIXME: should consider having a mime.types in $JAVA_HOME/lib/.
}
public static void fillFromFile (Map table, String fname)
@@ -323,6 +326,9 @@
public static void main(String[] args) throws IOException
{
TreeMap map = new TreeMap();
+ // It is fine to hard-code the name here. This is only ever
+ // used by maintainers, who can hack it if they need to re-run
+ // it.
fillFromFile(map, "/etc/mime.types");
Iterator it = map.keySet().iterator();
boolean first = true;
Index: java/net/URLConnection.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/URLConnection.java,v
retrieving revision 1.39
diff -u -r1.39 URLConnection.java
--- java/net/URLConnection.java 23 Mar 2006 15:49:35 -0000 1.39
+++ java/net/URLConnection.java 5 Apr 2006 20:11:31 -0000
@@ -38,6 +38,9 @@
package java.net;
+import gnu.classpath.NotImplementedException;
+import gnu.classpath.SystemProperties;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -47,8 +50,10 @@
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
+import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
+import java.util.StringTokenizer;
/**
* Written using on-line Java Platform 1.2 API Specification, as well
@@ -114,6 +119,12 @@
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.
*/
@@ -160,6 +171,7 @@
* This is the URL associated with this connection
*/
protected URL url;
+
private static SimpleDateFormat[] dateFormats;
private static boolean dateformats_initialized;
@@ -923,8 +935,10 @@
* @exception IOException If an error occurs
*/
public static String guessContentTypeFromStream(InputStream is)
- throws IOException
+ throws IOException, NotImplementedException
{
+ // See /etc/gnome-vfs-mime-magic or /etc/mime-magic for a reasonable
+ // idea of how to handle this.
return "application/octet-stream";
}
@@ -979,44 +993,66 @@
if (factory != null)
handler = factory.createContentHandler(contentType);
- // Then try our default class.
- try
- {
- String typeClass = contentType.replace('/', '.');
-
- // Deal with "Content-Type: text/html; charset=ISO-8859-1".
- int parameterBegin = typeClass.indexOf(';');
- if (parameterBegin >= 1)
- typeClass = typeClass.substring(0, parameterBegin);
-
- Class cls = Class.forName("gnu.java.net.content." + typeClass);
- Object obj = cls.newInstance();
-
- if (obj instanceof ContentHandler)
- {
- handler = (ContentHandler) obj;
- return handler;
- }
- }
- catch (ClassNotFoundException e)
- {
- // Ignore.
- }
- catch (InstantiationException e)
- {
- // Ignore.
- }
- catch (IllegalAccessException e)
+ // 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)
{
- // Ignore.
+ // 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).
+ // 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)
Index: gnu/java/net/DefaultContentHandlerFactory.java
===================================================================
RCS file: gnu/java/net/DefaultContentHandlerFactory.java
diff -N gnu/java/net/DefaultContentHandlerFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gnu/java/net/DefaultContentHandlerFactory.java 1 Jan 1970 00:00:00
-0000
@@ -0,0 +1,94 @@
+/* DefaultContentHandlerFactory.java
+ Copyright (C) 2004 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 gnu.java.net;
+
+import java.io.IOException;
+import java.net.ContentHandler;
+import java.net.ContentHandlerFactory;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.HashSet;
+
+/** Content Handler for Image types, using the AWT Toolkit's image decoder. */
+class ImageHandler extends ContentHandler
+{
+ static ImageHandler instance = new ImageHandler();
+
+ public Object getContent(URLConnection urlc) throws IOException
+ {
+ // FIXME: implement using ImageIO
+ // ClasspathToolkit tk = (ClasspathToolkit) Toolkit.getDefaultToolkit();
+ // java.awt.image.ImageProducer ip = tk.createImageProducer(urlc.getURL());
+ // return ip;
+ return null;
+ }
+}
+
+/**
+ */
+public class DefaultContentHandlerFactory implements ContentHandlerFactory
+{
+ /** For now, hard code the list of types that we assume should
+ * be supported by the Toolkit. ClasspathToolkit should perhaps provide
+ * an API to express what Image MIME types the Toolkit understands.
+ */
+ private static String[] known_image_types =
+ {
+ "image/bmp",
+ "image/gif",
+ "image/jpeg",
+ "image/png",
+ "image/tiff",
+ "image/x-portable-anymap",
+ "image/x-cmu-raster",
+ "image/x-xbitmap",
+ "image/x-xpixmap"
+ };
+
+ private static HashSet imageTypes
+ = new HashSet(Arrays.asList(known_image_types));
+
+ public ContentHandler createContentHandler(String mimeType)
+ {
+ if (imageTypes.contains(mimeType))
+ return ImageHandler.instance;
+ // Currently, only image types are handled.
+ return null;
+ }
+}