org.mozilla.javascript.tools.SourceReader Maven / Gradle / Ivy
The newest version!
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript.tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.mozilla.javascript.Kit;
import org.mozilla.javascript.commonjs.module.provider.ParsedContentType;
/**
* @author Attila Szegedi
* @version $Id: SourceReader.java,v 1.2 2010/02/15 19:31:17 szegedia%freemail.hu Exp $
*/
public class SourceReader
{
public static URL toUrl(String path) {
// Assume path is URL if it contains a colon and there are at least
// 2 characters in the protocol part. The later allows under Windows
// to interpret paths with driver letter as file, not URL.
if (path.indexOf(':') >= 2) {
try {
return new URL(path);
} catch (MalformedURLException ex) {
// not a URL
}
}
return null;
}
public static Object readFileOrUrl(String path, boolean convertToString,
String defaultEncoding) throws IOException
{
URL url = toUrl(path);
InputStream is = null;
int capacityHint = 0;
String encoding;
final String contentType;
byte[] data;
try {
if (url == null) {
File file = new File(path);
contentType = encoding = null;
capacityHint = (int)file.length();
is = new FileInputStream(file);
} else {
URLConnection uc = url.openConnection();
is = uc.getInputStream();
if(convertToString) {
ParsedContentType pct = new ParsedContentType(uc.getContentType());
contentType = pct.getContentType();
encoding = pct.getEncoding();
}
else {
contentType = encoding = null;
}
capacityHint = uc.getContentLength();
// Ignore insane values for Content-Length
if (capacityHint > (1 << 20)) {
capacityHint = -1;
}
}
if (capacityHint <= 0) {
capacityHint = 4096;
}
data = Kit.readStream(is, capacityHint);
} finally {
if(is != null) {
is.close();
}
}
Object result;
if (!convertToString) {
result = data;
} else {
if(encoding == null) {
// None explicitly specified in Content-type header. Use RFC-4329
// 4.2.2 section to autodetect
if(data.length > 3 && data[0] == -1 && data[1] == -2 && data[2] == 0 && data[3] == 0) {
encoding = "UTF-32LE";
}
else if(data.length > 3 && data[0] == 0 && data[1] == 0 && data[2] == -2 && data[3] == -1) {
encoding = "UTF-32BE";
}
else if(data.length > 2 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
encoding = "UTF-8";
}
else if(data.length > 1 && data[0] == -1 && data[1] == -2) {
encoding = "UTF-16LE";
}
else if(data.length > 1 && data[0] == -2 && data[1] == -1) {
encoding = "UTF-16BE";
}
else {
// No autodetect. See if we have explicit value on command line
encoding = defaultEncoding;
if(encoding == null) {
// No explicit encoding specification
if(url == null) {
// Local files default to system encoding
encoding = System.getProperty("file.encoding");
}
else if(contentType != null && contentType.startsWith("application/")) {
// application/* types default to UTF-8
encoding = "UTF-8";
}
else {
// text/* MIME types default to US-ASCII
encoding = "US-ASCII";
}
}
}
}
String strResult = new String(data, encoding);
// Skip BOM
if(strResult.length() > 0 && strResult.charAt(0) == '\uFEFF')
{
strResult = strResult.substring(1);
}
result = strResult;
}
return result;
}
}