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;
+  }
+}

Reply via email to