8008915: URLReader constructor should allow specifying encoding
Reviewed-by: hannesw, lagergren
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Jun 17 13:56:05 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Tue Jun 18 13:45:03 2013 +0530
@@ -34,6 +34,7 @@
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.URL;
+import java.nio.charset.Charset;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
@@ -121,7 +122,8 @@
try {
if (reader instanceof URLReader) {
final URL url = ((URLReader)reader).getURL();
- return evalImpl(compileImpl(new Source(url.toString(), url), ctxt), ctxt);
+ final Charset cs = ((URLReader)reader).getCharset();
+ return evalImpl(compileImpl(new Source(url.toString(), url, cs), ctxt), ctxt);
}
return evalImpl(Source.readFully(reader), ctxt);
} catch (final IOException e) {
--- a/nashorn/src/jdk/nashorn/api/scripting/URLReader.java Mon Jun 17 13:56:05 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/URLReader.java Tue Jun 18 13:45:03 2013 +0530
@@ -25,10 +25,12 @@
package jdk.nashorn.api.scripting;
+import java.io.CharArrayReader;
import java.io.IOException;
-import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
+import java.nio.charset.Charset;
+import jdk.nashorn.internal.runtime.Source;
/**
* A Reader that reads from a URL. Used to make sure that the reader
@@ -36,7 +38,10 @@
*/
public final class URLReader extends Reader {
// underlying URL
- private URL url;
+ private final URL url;
+ // Charset used to convert
+ private final Charset cs;
+
// lazily initialized underlying reader for URL
private Reader reader;
@@ -44,9 +49,35 @@
* Constructor
*
* @param url URL for this URLReader
+ * @throws NullPointerException if url is null
*/
public URLReader(final URL url) {
+ this(url, (Charset)null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param url URL for this URLReader
+ * @param charsetName Name of the Charset used to convert bytes to chars
+ * @throws NullPointerException if url is null
+ */
+ public URLReader(final URL url, final String charsetName) {
+ this(url, Charset.forName(charsetName));
+ }
+
+ /**
+ * Constructor
+ *
+ * @param url URL for this URLReader
+ * @param cs Charset used to convert bytes to chars
+ * @throws NullPointerException if url is null
+ */
+ public URLReader(final URL url, final Charset cs) {
+ // null check
+ url.getClass();
this.url = url;
+ this.cs = cs;
}
@Override
@@ -67,11 +98,20 @@
return url;
}
+ /**
+ * Charset used by this reader
+ *
+ * @return the Chartset used to convert bytes to chars
+ */
+ public Charset getCharset() {
+ return cs;
+ }
+
// lazily initialize char array reader using URL content
private Reader getReader() throws IOException {
synchronized (lock) {
if (reader == null) {
- reader = new InputStreamReader(url.openStream());
+ reader = new CharArrayReader(Source.readFully(url, cs));
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/Source.java Mon Jun 17 13:56:05 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Source.java Tue Jun 18 13:45:03 2013 +0530
@@ -116,7 +116,20 @@
* @throws IOException if source cannot be loaded
*/
public Source(final String name, final URL url) throws IOException {
- this(name, baseURL(url, null), readFully(url.openStream()), url);
+ this(name, baseURL(url, null), readFully(url), url);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param name source name
+ * @param url url from which source can be loaded
+ * @param cs Charset used to convert bytes to chars
+ *
+ * @throws IOException if source cannot be loaded
+ */
+ public Source(final String name, final URL url, final Charset cs) throws IOException {
+ this(name, baseURL(url, null), readFully(url, cs), url);
}
/**
@@ -131,6 +144,19 @@
this(name, dirName(file, null), readFully(file), getURLFromFile(file));
}
+ /**
+ * Constructor
+ *
+ * @param name source name
+ * @param file file from which source can be loaded
+ * @param cs Charset used to convert bytes to chars
+ *
+ * @throws IOException if source cannot be loaded
+ */
+ public Source(final String name, final File file, final Charset cs) throws IOException {
+ this(name, dirName(file, null), readFully(file, cs), getURLFromFile(file));
+ }
+
@Override
public boolean equals(final Object obj) {
if (this == obj) {
@@ -344,6 +370,53 @@
}
/**
+ * Read all of the source until end of file. Return it as char array
+ *
+ * @param file source file
+ * @param cs Charset used to convert bytes to chars
+ * @return source as content
+ *
+ * @throws IOException if source could not be read
+ */
+ public static char[] readFully(final File file, final Charset cs) throws IOException {
+ if (!file.isFile()) {
+ throw new IOException(file + " is not a file"); //TODO localize?
+ }
+
+ final byte[] buf = Files.readAllBytes(file.toPath());
+ if (cs != null) {
+ return new String(buf, cs).toCharArray();
+ } else {
+ return byteToCharArray(buf);
+ }
+ }
+
+ /**
+ * Read all of the source until end of stream from the given URL. Return it as char array
+ *
+ * @param url URL to read content from
+ * @return source as content
+ *
+ * @throws IOException if source could not be read
+ */
+ public static char[] readFully(final URL url) throws IOException {
+ return readFully(url.openStream());
+ }
+
+ /**
+ * Read all of the source until end of file. Return it as char array
+ *
+ * @param url URL to read content from
+ * @param cs Charset used to convert bytes to chars
+ * @return source as content
+ *
+ * @throws IOException if source could not be read
+ */
+ public static char[] readFully(final URL url, final Charset cs) throws IOException {
+ return readFully(url.openStream(), cs);
+ }
+
+ /**
* Get the base url. This is currently used for testing only
* @param url a URL
* @return base URL for url
@@ -391,6 +464,14 @@
return (idx != -1)? name.substring(0, idx + 1) : defaultValue;
}
+ private static char[] readFully(final InputStream is, final Charset cs) throws IOException {
+ if (cs != null) {
+ return new String(readBytes(is), cs).toCharArray();
+ } else {
+ return readFully(is);
+ }
+ }
+
private static char[] readFully(final InputStream is) throws IOException {
return byteToCharArray(readBytes(is));
}