You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2006/12/06 06:57:54 UTC

svn commit: r482913 - in /xmlgraphics/batik/trunk/sources/org/apache/batik: bridge/ script/ script/jacl/ script/jpython/ script/rhino/ util/

Author: cam
Date: Tue Dec  5 21:57:52 2006
New Revision: 482913

URL: http://svn.apache.org/viewvc?view=rev&rev=482913
Log:
1. Encoding as specified in a Content-Type header's charset parameter is now
   honoured when scripts are loaded.
2. Changed InterpreterFactory so that multiple MIME types can be associated
   with a given Interpreter.  This breaks the extension interface, but since
   I already broke it before the 1.6 release (by adding the extra bool
   parameter to Interpreter's constructor) and nobody complained, I think it
   should be ok.  Any objections, let me know, and I'll make it a subinterface
   or something.
2. text/javascript, text/ecmascript, application/javascript and
   application/ecmascript are now all supported as script types for Rhino.
   Processing of application/ecmascript is as specified in RFC 4329.  This
   fixes bug 35549.

PR: 35549

Modified:
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterFactory.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/jacl/JaclInterpreterFactory.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/jpython/JPythonInterpreterFactory.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreterFactory.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURL.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURLData.java

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java Tue Dec  5 21:57:52 2006
@@ -19,9 +19,12 @@
 package org.apache.batik.bridge;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.PushbackInputStream;
 import java.io.Reader;
 import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashSet;
@@ -212,6 +215,12 @@
     protected static final String ALTERNATE_EVENT_NAME = "evt";
 
     /**
+     * The 'application/ecmascript' MIME type.
+     */
+    protected static final String APPLICATION_ECMASCRIPT =
+        "application/ecmascript";
+
+    /**
      * The bridge context.
      */
     protected BridgeContext bridgeContext;
@@ -400,7 +409,7 @@
             try {
                 String href = XLinkSupport.getXLinkHref(script);
                 String desc = null;
-                Reader reader;
+                Reader reader = null;
 
                 if (href.length() > 0) {
                     desc = href;
@@ -409,7 +418,62 @@
                     ParsedURL purl = new ParsedURL(script.getBaseURI(), href);
 
                     checkCompatibleScriptURL(type, purl);
-                    reader = new InputStreamReader(purl.openStream());
+                    InputStream is = purl.openStream();
+                    String mediaType = purl.getContentTypeMediaType();
+                    String enc = purl.getContentTypeCharset();
+                    if (enc != null) {
+                        try {
+                            reader = new InputStreamReader(is, enc);
+                        } catch (UnsupportedEncodingException uee) {
+                            enc = null;
+                        }
+                    }
+                    if (reader == null) {
+                        if (mediaType.equals(APPLICATION_ECMASCRIPT)) {
+                            // No encoding was specified in the MIME type, so
+                            // infer it according to RFC 4329.
+                            PushbackInputStream pbis =
+                                new PushbackInputStream(is, 8);
+                            byte[] buf = new byte[4];
+                            int read = pbis.read(buf);
+                            if (read > 0) {
+                                pbis.unread(buf, 0, read);
+                                if (read >= 2) {
+                                    if (buf[0] == (byte)0xff &&
+                                            buf[1] == (byte)0xfe) {
+                                        if (read >= 4 && buf[2] == 0 &&
+                                                buf[3] == 0) {
+                                            enc = "UTF32-LE";
+                                            pbis.skip(4);
+                                        } else {
+                                            enc = "UTF-16LE";
+                                            pbis.skip(2);
+                                        }
+                                    } else if (buf[0] == (byte)0xfe &&
+                                            buf[1] == (byte)0xff) {
+                                        enc = "UTF-16BE";
+                                        pbis.skip(2);
+                                    } else if (read >= 3 && buf[0] == 0xef &&
+                                            buf[1] == 0xbb && buf[2] == 0xbf) {
+                                        enc = "UTF-8";
+                                        pbis.skip(3);
+                                    } else if (read >= 4 && buf[0] == 0 &&
+                                            buf[1] == 0 &&
+                                            buf[2] == (byte)0xfe &&
+                                            buf[3] == (byte)0xff) {
+                                        enc = "UTF-32BE";
+                                        pbis.skip(4);
+                                    }
+                                }
+                                if (enc == null) {
+                                    enc = "UTF-8";
+                                }
+                            }
+                            reader = new InputStreamReader(pbis, enc);
+                        } else {
+                            reader = new InputStreamReader(is);
+                        }
+                    }
                 } else {
                     checkCompatibleScriptURL(type, docPURL);
                     DocumentLoader dl = bridgeContext.getDocumentLoader();

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterFactory.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterFactory.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterFactory.java Tue Dec  5 21:57:52 2006
@@ -21,18 +21,18 @@
 import java.net.URL;
 
 /**
- * An hight level interface that represents a factory allowing
- * to create instances of a particular <code>Interpreter</code> interface
- * implementation.
+ * An interface for factory objects than can create {@link Interpreter}
+ * instances for a particular script language.
+ *
  * @author <a href="mailto:cjolif@ilog.fr">Christophe Jolif</a>
  * @version $Id$
  */
 public interface InterpreterFactory {
 
     /**
-     * Returns the mime-type to register this interpereter with.
+     * Returns the mime-types to register this interpereter with.
      */
-    String getMimeType();
+    String[] getMimeTypes();
 
     /**
      * This method should create an instance of <code>Interpreter</code>

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java Tue Dec  5 21:57:52 2006
@@ -62,8 +62,10 @@
         while (iter.hasNext()) {
             InterpreterFactory factory = null;
             factory = (InterpreterFactory)iter.next();
-            // System.err.println("Factory : " + factory);
-            defaultFactories.put(factory.getMimeType(), factory);
+            String[] mimeTypes = factory.getMimeTypes();
+            for (int i = 0; i < mimeTypes.length; i++) {
+                defaultFactories.put(mimeTypes[i], factory);
+            }
         }
     }
 

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/jacl/JaclInterpreterFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/script/jacl/JaclInterpreterFactory.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/jacl/JaclInterpreterFactory.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/jacl/JaclInterpreterFactory.java Tue Dec  5 21:57:52 2006
@@ -30,7 +30,10 @@
  */
 public class JaclInterpreterFactory implements InterpreterFactory {
 
-    static final String TEXT_TCL = "text/tcl";
+    /**
+     * The MIME types that jacl can handle.
+     */
+    private static final String[] JACL_MIMETYPES = { "text/tcl" };
 
     /**
      * Builds a <code>JaclInterpreterFactory</code>.
@@ -39,9 +42,11 @@
     }
 
     /**
-     * Returns the mime-type to register this interpereter with.
+     * Returns the mime-types to register this interpereter with.
      */
-    public String getMimeType() { return TEXT_TCL; }
+    public String[] getMimeTypes() {
+        return JACL_MIMETYPES;
+    }
 
     /**
      * Creates an instance of <code>JaclInterpreter</code> class.

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/jpython/JPythonInterpreterFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/script/jpython/JPythonInterpreterFactory.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/jpython/JPythonInterpreterFactory.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/jpython/JPythonInterpreterFactory.java Tue Dec  5 21:57:52 2006
@@ -30,7 +30,10 @@
  */
 public class JPythonInterpreterFactory implements InterpreterFactory {
 
-    static final String TEXT_PYTHON = "text/python";
+    /**
+     * The MIME types that JPython can handle.
+     */
+    private static final String[] JPYTHON_MIMETYPES =  { "text/python" };
 
     /**
      * Builds a <code>JPythonInterpreterFactory</code>.
@@ -39,9 +42,11 @@
     }
 
     /**
-     * Returns the mime-type to register this interpereter with.
+     * Returns the mime-types to register this interpereter with.
      */
-    public String getMimeType() { return TEXT_PYTHON; }
+    public String[] getMimeTypes() {
+        return JPYTHON_MIMETYPES;
+    }
 
     /**
      * Creates an instance of <code>JPythonInterpreter</code> class.

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreterFactory.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreterFactory.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreterFactory.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreterFactory.java Tue Dec  5 21:57:52 2006
@@ -33,7 +33,15 @@
  */
 public class RhinoInterpreterFactory implements InterpreterFactory {
 
-    static final String TEXT_ECMASCRIPT = "text/ecmascript";
+    /**
+     * The MIME types that Rhino can handle.
+     */
+    private static final String[] RHINO_MIMETYPES = {
+        "application/ecmascript",
+        "application/javascript",
+        "text/ecmascript",
+        "text/javascript",
+    };
 
     /**
      * Builds a <code>RhinoInterpreterFactory</code>.
@@ -42,9 +50,11 @@
     }
 
     /**
-     * Returns the mime-type to register this interpereter with.
+     * Returns the mime-types to register this interpereter with.
      */
-    public String getMimeType() { return TEXT_ECMASCRIPT; }
+    public String[] getMimeTypes() {
+        return RHINO_MIMETYPES;
+    }
 
     /**
      * Creates an instance of <code>RhinoInterpreter</code> class.

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURL.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURL.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURL.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURL.java Tue Dec  5 21:57:52 2006
@@ -343,6 +343,22 @@
     }
 
     /**
+     * Returns the content type's type/subtype, if available.  This is
+     * only available for some protocols.
+     */
+    public String getContentTypeMediaType() {
+        return data.getContentTypeMediaType(userAgent);
+    }
+
+    /**
+     * Returns the content type's charset parameter, if available.  This is
+     * only available for some protocols.
+     */
+    public String getContentTypeCharset() {
+        return data.getContentTypeCharset(userAgent);
+    }
+
+    /**
      * Returns the content encoding if available.  This is only available
      * for some protocols.
      */

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURLData.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURLData.java?view=diff&rev=482913&r1=482912&r2=482913
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURLData.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/util/ParsedURLData.java Tue Dec  5 21:57:52 2006
@@ -129,6 +129,16 @@
     public boolean hasBeenOpened  = false;
 
     /**
+     * The extracted type/subtype from the Content-Type header.
+     */
+    protected String contentTypeMediaType;
+
+    /**
+     * The extracted charset parameter from the Content-Type header.
+     */
+    protected String contentTypeCharset;
+
+    /**
      * Void constructor
      */
     public ParsedURLData() {
@@ -275,6 +285,93 @@
         }
 
         return contentType;
+    }
+
+    /**
+     * Returns the content type's type/subtype, if available.  This is
+     * only available for some protocols.
+     */
+    public String getContentTypeMediaType(String userAgent) {
+        if (contentTypeMediaType != null) {
+            return contentTypeMediaType;
+        }
+
+        extractContentTypeParts(userAgent);
+
+        return contentTypeMediaType;
+    }
+
+    /**
+     * Returns the content type's charset parameter, if available.  This is
+     * only available for some protocols.
+     */
+    public String getContentTypeCharset(String userAgent) {
+        if (contentTypeMediaType != null) {
+            return contentTypeCharset;
+        }
+
+        extractContentTypeParts(userAgent);
+
+        return contentTypeCharset;
+    }
+
+    /**
+     * Extracts the type/subtype and charset parameter from the Content-Type
+     * header.
+     */
+    protected void extractContentTypeParts(String userAgent) {
+        getContentType(userAgent);
+        int i = 0;
+        int len = contentType.length();
+loop1:  while (i < len) {
+            switch (contentType.charAt(i)) {
+                case ' ':
+                case ';':
+                    break loop1;
+            }
+            i++;
+        }
+        System.err.println("i == " + i);
+        if (i == len) {
+            contentTypeMediaType = contentType;
+        } else {
+            contentTypeMediaType = contentType.substring(0, i);
+        }
+        for (;;) {
+            while (i < len && contentType.charAt(i) != ';') {
+                i++;
+            }
+            if (i == len) {
+                return;
+            }
+            i++;
+            while (i < len && contentType.charAt(i) == ' ') {
+                i++;
+            }
+            if (i >= len - 8) {
+                return;
+            }
+            if (contentType.charAt(i++) == 'c') {
+                if (contentType.charAt(i++) != 'h') continue;
+                if (contentType.charAt(i++) != 'a') continue;
+                if (contentType.charAt(i++) != 'r') continue;
+                if (contentType.charAt(i++) != 's') continue;
+                if (contentType.charAt(i++) != 'e') continue;
+                if (contentType.charAt(i++) != 't') continue;
+                if (contentType.charAt(i++) != '=') continue;
+                int j = i;
+loop2:          while (i < len) {
+                    switch (contentType.charAt(i)) {
+                        case ' ':
+                        case ';':
+                            break loop2;
+                    }
+                    i++;
+                }
+                contentTypeCharset = contentType.substring(j, i);
+                return;
+            }
+        }
     }
 
     /**