Permalink
Browse files

Fix issues #144 and #145 by parsing the MIME data correctly and provi…

…ding support for overriding the content type
  • Loading branch information...
ndw committed Mar 11, 2014
1 parent a7784ff commit a85cda61678d7e2f6e3594659c3173466ce6e809
@@ -72,7 +72,7 @@ public void run() throws SaxonApiException {
try {
String base = pURI.toASCIIString();
DataStore store = runtime.getDataStore();
- store.readEntry(pFn, base, ACCEPT_TEXT, new DataReader() {
+ store.readEntry(pFn, base, ACCEPT_TEXT, null, new DataReader() {
public void load(URI id, String media, InputStream stream,
long len) throws IOException {
properties.load(stream);
@@ -93,7 +93,7 @@ public void run() throws SaxonApiException {
final DatatypeFactory dfactory = DatatypeFactory.newInstance();
DataStore store = runtime.getDataStore();
String base = zipURI.toASCIIString();
- store.readEntry(zipFn, base, ACCEPT_ZIP, new DataReader() {
+ store.readEntry(zipFn, base, ACCEPT_ZIP, null, new DataReader() {
public void load(URI id, String media, InputStream content,
long len) throws IOException {
unzip(dfactory, id.toASCIIString(), content);
@@ -167,7 +167,7 @@ public void run() throws SaxonApiException {
public void store(OutputStream content) throws IOException {
final ZipOutputStream outZip = new ZipOutputStream(content);
try {
- store.readEntry(zipFn, base, "application/zip", new DataStore.DataReader() {
+ store.readEntry(zipFn, base, "application/zip", null, new DataStore.DataReader() {
public void load(URI id, String media, InputStream content, long len)
throws IOException {
ZipInputStream inZip = new ZipInputStream(content);
@@ -192,7 +192,7 @@ public void load(URI id, String media, InputStream content, long len)
try {
final DatatypeFactory dfactory = DatatypeFactory.newInstance();
DataStore store = runtime.getDataStore();
- store.readEntry(zipFn, zipFn, "application/zip, */*", new DataReader() {
+ store.readEntry(zipFn, zipFn, "application/zip, */*", null, new DataReader() {
public void load(URI id, String media, InputStream stream,
long len) throws IOException {
read(id, stream, dfactory);
@@ -382,7 +382,7 @@ public void update(ZipInputStream inZip, final ZipOutputStream outZip, boolean f
store(file, doc, baos);
} else {
DataStore store = runtime.getDataStore();
- store.readEntry(href, href, "*/*", new DataReader() {
+ store.readEntry(href, href, "*/*", null, new DataReader() {
public void load(URI id, String media,
InputStream stream, long len)
throws IOException {
@@ -408,7 +408,7 @@ public void load(URI id, String media,
store(file, doc, outZip);
} else {
DataStore store = runtime.getDataStore();
- store.readEntry(href, href, "*/*", new DataReader() {
+ store.readEntry(href, href, "*/*", null, new DataReader() {
public void load(URI id, String media,
InputStream stream, long len)
throws IOException {
@@ -64,7 +64,7 @@ public void run() throws SaxonApiException {
try {
final DataStore store = runtime.getDataStore();
- store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "*/*", new DataReader() {
+ store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "*/*", null, new DataReader() {
public void load(URI id, String media, final InputStream src, long len)
throws IOException {
RuntimeValue target = getOption(_target);
@@ -72,7 +72,7 @@ public void run() throws SaxonApiException {
try {
DataStore store = runtime.getDataStore();
- store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "text/*, */*", new DataReader() {
+ store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "text/*, */*", null, new DataReader() {
public void load(URI id, String media, InputStream content, long len)
throws IOException {
Reader rdr = new InputStreamReader(content);
@@ -62,7 +62,7 @@ public void run() throws SaxonApiException {
try {
final DataStore store = runtime.getDataStore();
String base = href.getBaseURI().toASCIIString();
- store.readEntry(href.getString(), base, "*/*", new DataReader() {
+ store.readEntry(href.getString(), base, "*/*", null, new DataReader() {
public void load(URI id, String media, final InputStream src, long len)
throws IOException {
RuntimeValue target = getOption(_target);
@@ -69,7 +69,7 @@ public void run() throws SaxonApiException {
try {
DataStore store = runtime.getDataStore();
- store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "text/*, */*", new DataReader() {
+ store.readEntry(href.getString(), href.getBaseURI().toASCIIString(), "text/*, */*", null, new DataReader() {
public void load(URI id, String media, InputStream content, long len)
throws IOException {
TreeWriter tree = new TreeWriter(runtime);
@@ -141,7 +141,7 @@ URI writeEntry(String href, String base, String media, DataWriter handler)
* @throws IOException
* if the document could not be read
*/
- void readEntry(String href, String base, String accept, DataReader handler)
+ void readEntry(String href, String base, String accept, String overrideContentType, DataReader handler)
throws MalformedURLException, FileNotFoundException, IOException;
/**
@@ -44,7 +44,7 @@ public URI writeEntry(String href, String base, String media,
}
public void readEntry(String href, String base, String accept,
- DataReader handler) throws MalformedURLException,
+ String overrideContentType, DataReader handler) throws MalformedURLException,
FileNotFoundException, IOException {
URI baseURI = URI.create(base);
URI uri = baseURI.resolve(href);
@@ -34,6 +34,7 @@
import java.net.MalformedURLException;
import java.net.URI;
import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.Properties;
/**
@@ -47,14 +48,15 @@
public class FileDataStore implements DataStore {
private final DataStore fallback;
private final Properties contentTypes;
+ private Hashtable<String,String> cachedMapping = null;
public FileDataStore(DataStore fallback) {
super();
this.fallback = fallback;
contentTypes = new Properties();
loadDefaultContentTypes(contentTypes);
loadContentTypes(contentTypes);
- }
+ }
public URI writeEntry(String href, String base, String media,
DataWriter handler) throws MalformedURLException,
@@ -104,21 +106,24 @@ public URI writeEntry(String href, String base, String media,
}
public void readEntry(String href, String base, String accept,
- DataReader handler) throws MalformedURLException,
+ String overrideContentType, DataReader handler) throws MalformedURLException,
FileNotFoundException, IOException {
URI baseURI = URI.create(base);
URI uri = baseURI.resolve(href);
if ("file".equalsIgnoreCase(uri.getScheme())) {
File file = new File(uri);
String type = getContentTypeFromName(file.getName());
+ if (overrideContentType != null) {
+ type = overrideContentType;
+ }
InputStream in = new FileInputStream(file);
try {
handler.load(file.toURI(), type, in, file.length());
} finally {
in.close();
}
} else {
- fallback.readEntry(href, base, accept, handler);
+ fallback.readEntry(href, base, accept, overrideContentType, handler);
}
}
@@ -247,14 +252,32 @@ protected String getContentTypeFromName(String name) {
if (ext == null) {
return "application/octet-stream";
}
- Enumeration<?> types = contentTypes.propertyNames();
- while (types.hasMoreElements()) {
- String type = (String) types.nextElement();
- String attrs = contentTypes.getProperty(type);
- if (attrs.contains(ext)) {
- return type;
- }
- }
+
+ if (cachedMapping == null) {
+ // Let's do this only once...
+ cachedMapping = new Hashtable<String,String> ();
+ Enumeration<?> types = contentTypes.propertyNames();
+ while (types.hasMoreElements()) {
+ String type = (String) types.nextElement();
+ String attrs = contentTypes.getProperty(type);
+
+ String[] tokens = attrs.split(";");
+ for (String tok : tokens) {
+ if (tok.startsWith("file_extensions=")) {
+ String extList = tok.substring(16);
+ String[] exts = extList.split(",");
+ for (String e : exts) {
+ cachedMapping.put(e, type);
+ }
+ }
+ }
+ }
+ }
+
+ if (cachedMapping.containsKey(ext)) {
+ return cachedMapping.get(ext);
+ }
+
return "application/octet-stream";
}
@@ -310,7 +333,9 @@ private String getFileExtension(String fname) {
* Load some basic types in case the system doesn't have them.
*/
private void loadDefaultContentTypes(Properties contentTypes) {
- contentTypes.put("application/json", "file_extensions=.json");
+ contentTypes.put("application/json", "file_extensions=.json");
+ contentTypes.put("application/javascript", "file_extensions=.js");
+ contentTypes.put("text/css", "file_extensions=.css");
contentTypes.put("application/xml", "file_extensions=.xml");
contentTypes.put("application/zip", "file_extensions=.zip");
contentTypes.put("text/plain", "file_extensions=.txt");
@@ -146,15 +146,15 @@ public URI handleResponse(HttpResponse response)
}
public void readEntry(String href, String base, String accept,
- DataReader handler) throws MalformedURLException,
+ String overrideContentType, DataReader handler) throws MalformedURLException,
FileNotFoundException, IOException {
URI baseURI = URI.create(base);
URI uri = baseURI.resolve(href);
String sch = uri.getScheme();
if ("http".equalsIgnoreCase(sch) || "https".equalsIgnoreCase(sch)) {
- readHttpEntity(uri, accept, handler);
+ readHttpEntity(uri, accept, overrideContentType, handler);
} else {
- fallback.readEntry(href, base, accept, handler);
+ fallback.readEntry(href, base, accept, overrideContentType, handler);
}
}
@@ -234,7 +234,7 @@ private long getLastModified(HttpResponse response)
}
private void readHttpEntity(final URI uri, final String accept,
- final DataReader handler) throws IOException,
+ final String overrideContentType, final DataReader handler) throws IOException,
ClientProtocolException, Error {
final HttpContext localContext = new BasicHttpContext();
HttpGet get = new HttpGet(uri);
@@ -249,6 +249,9 @@ public Void handleResponse(HttpResponse response)
if (hd != null) {
type = hd.getValue();
}
+ if (overrideContentType != null) {
+ type = overrideContentType;
+ }
handler.load(contentId, type, entity.getContent(),
entity.getContentLength());
return null;
@@ -105,7 +105,7 @@ private DocumentSequence ensureDocuments() {
accept = userContentType + ", */*";
}
DataStore store = runtime.getDataStore();
- store.readEntry(uri, uri, accept, new DataReader() {
+ store.readEntry(uri, uri, accept, null, new DataReader() {
public void load(URI dataURI, String serverContentType,
InputStream stream, long len) throws IOException {
read(userContentType, dataURI, stream,
@@ -161,11 +161,11 @@ public void load(URI id, String media,
public void list(URI id, String media, long lastModified)
throws IOException {
String entry = id.toASCIIString();
- store.readEntry(entry, entry, accept, handler);
+ store.readEntry(entry, entry, accept, null, handler);
}
});
} else {
- store.readEntry(entry, entry, accept, handler);
+ store.readEntry(entry, entry, accept, null, handler);
}
}
});
@@ -176,7 +176,7 @@ public void list(URI id, String media, long lastModified)
if (runtime.transparentJSON()) {
try {
DataStore store = runtime.getDataStore();
- store.readEntry(uri, base, ACCPET_JSON, new DataReader() {
+ store.readEntry(uri, base, ACCPET_JSON, null, new DataReader() {
public void load(URI id, String media, InputStream content, long len)
throws IOException {
String cs = HttpUtils.getCharset(media);
@@ -69,7 +69,7 @@ public URI writeEntry(String href, String base, String media,
}
public void readEntry(String href, String base, String accept,
- DataReader handler) throws MalformedURLException,
+ String overrideContentType, DataReader handler) throws MalformedURLException,
FileNotFoundException, IOException {
URI baseURI = URI.create(base);
URL url = baseURI.resolve(href).toURL();
@@ -78,6 +78,9 @@ public void readEntry(String href, String base, String accept,
final InputStream stream = connection.getInputStream();
try {
String type = connection.getContentType();
+ if (overrideContentType != null) {
+ type = overrideContentType;
+ }
URI id = URI.create(connection.getURL().toExternalForm());
long len = 0;
@@ -1106,16 +1106,9 @@ private String decodeBase64(XdmNode doc, String charset) {
}
private void doFile(String href, String base) {
- // Find the content type
- String contentType = overrideContentType;
-
- if (contentType == null) {
- contentType = "application/octet-stream";
- }
-
try {
DataStore store = runtime.getDataStore();
- store.readEntry(href, base, "application/xml, text/xml, */*", new DataReader() {
+ store.readEntry(href, base, "application/xml, text/xml, */*", overrideContentType, new DataReader() {
public void load(URI id, String contentType, InputStream bodyStream, long len)
throws IOException {
// FIXME: Is ISO-8859-1 the right default?
@@ -279,7 +279,7 @@ private void readText(final String href, final XdmNode node,
DataStore store = runtime.getDataStore();
try {
- store.readEntry(href, base, "text/plain, text/*, */*", new DataReader() {
+ store.readEntry(href, base, "text/plain, text/*, */*", null, new DataReader() {
public void load(URI id, String media, InputStream content,
long len) throws IOException {
String text = readText(node, xpointer, media, content, len);

0 comments on commit a85cda6

Please sign in to comment.