1 package com.icl.saxon.functions; 2 import com.icl.saxon.*; 3 import com.icl.saxon.om.*; 4 import com.icl.saxon.expr.*; 5 6 import javax.xml.transform.URIResolver ; 7 import javax.xml.transform.TransformerException ; 8 import javax.xml.transform.Source ; 9 import javax.xml.transform.sax.SAXSource ; 10 import javax.xml.transform.dom.DOMSource ; 11 12 import org.xml.sax.InputSource ; 13 import org.xml.sax.XMLReader ; 14 import org.w3c.dom.Node ; 15 import java.net.URL ; 16 import java.net.MalformedURLException ; 17 18 19 public class Document extends Function { 20 21 private Controller boundController = null; 22 23 public String getName() { 24 return "document"; 25 }; 26 27 31 32 public int getDataType() { 33 return Value.NODESET; 34 } 35 36 39 40 public Expression simplify() throws XPathException { 41 int numArgs = checkArgumentCount(1, 2); 42 argument[0] = argument[0].simplify(); 43 if (numArgs==2) { 44 argument[1] = argument[1].simplify(); 45 } 46 47 51 return this; 52 } 53 54 55 58 59 public Value evaluate(Context c) throws XPathException { 60 int numArgs = getNumberOfArguments(); 61 62 Value arg0 = argument[0].evaluate(c); 63 NodeSetValue arg1 = null; 64 if (numArgs==2) { 65 arg1 = argument[1].evaluateAsNodeSet(c); 66 } 67 68 String styleSheetURI = getStaticContext().getBaseURI(); 69 70 return getDocuments(arg0, arg1, styleSheetURI, c); 71 } 72 73 83 84 public NodeSetValue getDocuments( 85 Value arg0, 86 NodeSetValue arg1, 87 String styleSheetURL, 88 Context context) throws XPathException { 89 String baseURL; 90 91 if ((arg0 instanceof NodeSetValue) && 92 !(arg0 instanceof FragmentValue || arg0 instanceof TextFragmentValue)) { 93 94 NodeEnumeration supplied = ((NodeSetValue)arg0).enumerate(); 95 NodeSetExtent nv = new NodeSetExtent(context.getController()); 96 97 while (supplied.hasMoreElements()) { 98 NodeInfo n = supplied.nextElement(); 99 if (arg1==null) { 100 baseURL = n.getBaseURI(); 101 } else { 102 NodeInfo first = arg1.getFirst(); 103 if (first==null) { 104 throw new XPathException("Second argument to document() is empty node-set"); 106 } 107 else { 108 baseURL = first.getBaseURI(); 109 } 110 } 111 NodeInfo doc = makeDoc(n.getStringValue(), baseURL, context); 112 if (doc!=null) { 113 nv.append(doc); 114 } 115 } 116 return nv; 117 118 } else { 119 120 if (arg1==null) { 121 baseURL = styleSheetURL; 122 } else { 123 NodeInfo first = arg1.getFirst(); 124 if (first==null) { 125 baseURL = null; 128 } else { 129 baseURL = first.getBaseURI(); 130 } 131 } 132 133 String href = arg0.asString(); 134 NodeInfo doc = makeDoc(href, baseURL, context); 135 return new SingletonNodeSet(doc); 136 } 137 } 138 139 142 143 private NodeInfo makeDoc(String href, String baseURL, Context c) throws XPathException { 144 145 147 int hash = href.indexOf('#'); 148 149 String fragmentId = null; 150 if (hash>=0) { 151 if (hash==href.length()-1) { 152 href = href.substring(0, hash); 154 } else { 155 fragmentId = href.substring(hash+1); 156 href = href.substring(0, hash); 157 } 158 } 159 160 162 163 String documentKey; 164 if (baseURL==null) { try { 166 documentKey = (new URL (href)).toString(); 168 } catch (MalformedURLException err) { 169 documentKey = baseURL + "/" + href; 171 baseURL = ""; 172 } 173 } else { 174 try { 175 URL url = new URL (new URL (baseURL), href); 176 documentKey = url.toString(); 177 } catch (MalformedURLException err) { 178 documentKey = baseURL + "/../" + href; 179 } 180 } 181 182 Controller controller = boundController; 183 if (controller==null) { 184 controller = c.getController(); 185 } 186 187 if (controller==null) { 188 throw new XPathException("Internal error: no controller available for document() function"); 189 } 190 191 193 194 DocumentInfo doc = controller.getDocumentPool().find(documentKey); 195 if (doc!=null) return getFragment(doc, fragmentId); 196 197 try { 198 200 URIResolver r = controller.getURIResolver(); 201 Source source = r.resolve(href, baseURL); 202 203 if (source==null) { 206 r = controller.getStandardURIResolver(); 207 source = r.resolve(href, baseURL); 208 } 209 210 DocumentInfo newdoc = null; 211 if (source instanceof DocumentInfo) { 212 newdoc = (DocumentInfo)source; 213 } else { 214 if (source instanceof DOMSource ) { 215 DOMSource ds = (DOMSource )source; 216 if (ds.getNode() instanceof DocumentInfo) { 217 newdoc = (DocumentInfo)ds.getNode(); 220 } 221 } 222 if (newdoc==null) { 223 SAXSource saxSource = 225 controller.getTransformerFactory().getSAXSource(source, false); 226 227 Builder b = controller.makeBuilder(); 228 newdoc = b.build(saxSource); 229 } 230 } 231 232 controller.getDocumentPool().add(newdoc, documentKey); 234 235 return getFragment(newdoc, fragmentId); 236 237 } catch (TransformerException err) { 238 try { 239 controller.reportRecoverableError(err); 240 } catch (TransformerException err2) { 241 throw new XPathException(err); 242 } 243 return null; 244 } 245 } 246 247 254 255 private NodeInfo getFragment(DocumentInfo doc, String fragmentId) { 256 if (fragmentId==null) { 257 return doc; 258 } 259 return doc.selectID(fragmentId); 260 } 261 262 267 268 public int getDependencies() { 269 int dep = argument[0].getDependencies(); 270 if (getNumberOfArguments()==2) { 271 dep |= argument[1].getDependencies(); 272 } 273 if (boundController == null) { 274 return dep | Context.CONTROLLER; 275 } else { 276 return dep; 277 } 278 } 279 280 283 284 public Expression reduce(int dep, Context context) 285 throws XPathException { 286 287 Document doc = new Document(); 288 doc.addArgument(argument[0].reduce(dep, context)); 289 if (getNumberOfArguments()==2) { 290 doc.addArgument(argument[1].reduce(dep, context)); 291 } 292 doc.setStaticContext(getStaticContext()); 293 294 if ( boundController==null && ((dep & Context.CONTROLLER) != 0)) { 295 doc.boundController = context.getController(); 296 } 297 298 if (doc.getDependencies()==0) { 299 return doc.evaluate(context); 300 } 301 302 return doc; 303 } 304 305 306 } 307 308 309 310 311 312 | Popular Tags |