1 package org.daisy.pipeline.css.calabash.impl;
2
3 import java.io.ByteArrayInputStream;
4 import java.net.URI;
5 import java.net.URISyntaxException;
6
7 import javax.xml.transform.Source;
8 import javax.xml.transform.TransformerException;
9 import javax.xml.transform.URIResolver;
10 import javax.xml.transform.stream.StreamSource;
11
12 import com.xmlcalabash.core.XProcConstants;
13 import com.xmlcalabash.io.ReadablePipe;
14 import com.xmlcalabash.util.Base64;
15 import com.xmlcalabash.util.S9apiUtils;
16
17 import net.sf.saxon.s9api.QName;
18 import net.sf.saxon.s9api.SaxonApiException;
19 import net.sf.saxon.s9api.XdmNode;
20
21
22
23
24 class InMemoryURIResolver implements URIResolver {
25
26 private ReadablePipe documents = null;
27
28 InMemoryURIResolver() {}
29
30 void setContext(ReadablePipe documents) {
31 this.documents = documents;
32 }
33
34 private static final QName c_encoding = new QName("c", XProcConstants.NS_XPROC_STEP, "encoding");
35 private static final QName _content_type = new QName("content-type");
36
37 public Source resolve(String href, String base) throws TransformerException {
38 if (documents == null) return null;
39 try {
40 URI uri = (base != null) ?
41 new URI(base).resolve(new URI(href)) :
42 new URI(href);
43 uri = normalizeUri(uri);
44 documents.resetReader();
45 while (documents.moreDocuments()) {
46 XdmNode doc = documents.read();
47 URI docUri = normalizeUri(doc.getBaseURI());
48 if (docUri.equals(uri)) {
49 XdmNode root = S9apiUtils.getDocumentElement(doc);
50 if (XProcConstants.c_result.equals(root.getNodeName())
51 && root.getAttributeValue(_content_type) != null
52 && root.getAttributeValue(_content_type).startsWith("text/"))
53 return new StreamSource(new ByteArrayInputStream(doc.getStringValue().getBytes()),
54 uri.toASCIIString());
55 else if ("base64".equals(root.getAttributeValue(c_encoding)))
56 return new StreamSource(new ByteArrayInputStream(Base64.decode(doc.getStringValue())),
57 uri.toASCIIString());
58 else if (XProcConstants.c_data.equals(root.getNodeName()))
59 return new StreamSource(new ByteArrayInputStream(doc.getStringValue().getBytes()),
60 uri.toASCIIString());
61 else
62 return doc.asSource(); }}}
63 catch (URISyntaxException e) {
64 e.printStackTrace();
65 throw new TransformerException(e); }
66 catch (SaxonApiException e) {
67 e.printStackTrace();
68 throw new TransformerException(e); }
69 return null;
70 }
71
72 private static URI normalizeUri(URI uri) {
73 String s = uri.toASCIIString();
74
75
76 if (s.startsWith("file:///"))
77 s = "file:" + s.substring(7);
78
79
80 if (s.startsWith("file:") && s.contains("!/"))
81 s = "zip:" + s;
82
83
84 if (s.startsWith("zip:file:") && !s.contains("!/"))
85 s = s.replaceFirst("!", "!/");
86 try {
87 return new URI(s); }
88 catch (URISyntaxException e) {
89 throw new RuntimeException(e); }
90 }
91 }