1 package net.sf.saxon.xpath; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.expr.Atomizer; 4 import net.sf.saxon.expr.Expression; 5 import net.sf.saxon.expr.ExpressionTool; 6 import net.sf.saxon.expr.XPathContextMajor; 7 import net.sf.saxon.functions.NumberFn; 8 import net.sf.saxon.instruct.SlotManager; 9 import net.sf.saxon.om.*; 10 import net.sf.saxon.pattern.NodeTest; 11 import net.sf.saxon.sort.FixedSortKeyDefinition; 12 import net.sf.saxon.sort.SortedIterator; 13 import net.sf.saxon.trans.XPathException; 14 import net.sf.saxon.value.*; 15 import org.xml.sax.InputSource ; 16 17 import javax.xml.namespace.QName ; 18 import javax.xml.transform.sax.SAXSource ; 19 import javax.xml.xpath.XPathConstants ; 20 import javax.xml.xpath.XPathExpression ; 21 import javax.xml.xpath.XPathExpressionException ; 22 import java.util.List ; 23 24 33 34 35 public class XPathExpressionImpl implements XPathExpression { 36 37 private Configuration config; 38 private Expression expression; 39 private NodeInfo contextNode; 40 private SlotManager stackFrameMap; 41 private XPathExpressionImpl sortKey = null; 42 43 47 48 protected XPathExpressionImpl(Expression exp, Configuration config) { 49 expression = exp; 50 this.config = config; 51 } 52 53 57 58 protected void setStackFrameMap(SlotManager map) { 59 stackFrameMap = map; 60 } 61 62 69 70 public void setSortKey(XPathExpressionImpl sortKey) { 71 this.sortKey = sortKey; 72 } 73 74 79 80 public void setContextNode(NodeInfo node) { 81 if (node==null) { 82 throw new NullPointerException ("Context node cannot be null"); 83 } 84 if (node.getNamePool() != config.getNamePool()) { 85 throw new IllegalArgumentException ("Supplied node uses the wrong NamePool"); 86 } 87 contextNode = node; 88 } 89 90 91 100 101 public List evaluate() throws XPathException { 102 XPathContextMajor context = new XPathContextMajor(contextNode, config); 103 context.openStackFrame(stackFrameMap); 104 SequenceIterator iter = expression.iterate(context); 105 SequenceExtent extent = new SequenceExtent(iter); 106 return (List )extent.convertToJava(Object .class, context); 107 } 108 109 119 120 public Object evaluateSingle() throws XPathException { 121 XPathContextMajor context = new XPathContextMajor(contextNode, config); 122 context.openStackFrame(stackFrameMap); 123 SequenceIterator iterator = expression.iterate(context); 124 Item item = iterator.next(); 125 if (item == null) { 126 return null; 127 } else { 128 return Value.convert(item); 129 } 130 } 131 132 138 139 public SequenceIterator rawIterator() throws XPathException { 140 XPathContextMajor context = new XPathContextMajor(contextNode, config); 141 context.openStackFrame(stackFrameMap); 142 SequenceIterator iterator = expression.iterate(context); 143 if (sortKey != null) { 144 Expression key = sortKey.expression; 145 if (key.getItemType() instanceof NodeTest) { 146 key = new Atomizer(key, config); 147 } 148 149 FixedSortKeyDefinition[] sk = new FixedSortKeyDefinition[1]; 150 151 sk[0] = new FixedSortKeyDefinition(); 152 sk[0].setSortKey(key); 153 sk[0].bindComparer(context); 154 155 iterator = new SortedIterator(context, iterator, sk); 156 } 157 return iterator; 158 } 159 160 202 public Object evaluate(Object node, QName qName) throws XPathExpressionException { 203 ExternalObjectModel model = null; 204 if (node instanceof NodeInfo) { 205 setContextNode((NodeInfo)node); 206 } else { 207 model = config.findExternalObjectModel(node); 208 if (model == null) { 209 throw new XPathExpressionException ( 210 "Cannot locate an object model implementation for nodes of class " 211 + node.getClass().getName()); 212 } 213 DocumentInfo doc = model.wrapDocument(node, "", config); 214 NodeInfo startNode = model.wrapNode(doc, node); 215 setContextNode(startNode); 216 } 217 XPathContextMajor context = new XPathContextMajor(contextNode, config); 218 context.openStackFrame(stackFrameMap); 219 try { 220 if (qName.equals(XPathConstants.BOOLEAN)) { 221 return Boolean.valueOf(ExpressionTool.effectiveBooleanValue(expression.iterate(context))); 222 } else if (qName.equals(XPathConstants.STRING)) { 223 SequenceIterator iter = expression.iterate(context); 224 225 Item first = iter.next(); 226 if (first == null) { 227 return ""; 228 } 229 return first.getStringValue(); 230 231 } else if (qName.equals(XPathConstants.NUMBER)) { 232 SequenceIterator iter = new Atomizer(expression, config).iterate(context); 233 234 Item first = iter.next(); 235 if (first == null) { 236 return new Double (Double.NaN); 237 } 238 if (first instanceof NumericValue) { 239 return new Double (((NumericValue)first).getDoubleValue()); 240 } else { 241 DoubleValue v = NumberFn.convert((AtomicValue)first); 242 return new Double (v.getDoubleValue()); 243 } 244 245 } else if (qName.equals(XPathConstants.NODE)) { 246 SequenceIterator iter = expression.iterate(context); 247 Item first = iter.next(); 248 if (first instanceof VirtualNode) { 249 return ((VirtualNode)first).getUnderlyingNode(); 250 } 251 if (first == null || first instanceof NodeInfo) { 252 return first; 253 } 254 throw new XPathExpressionException ("Expression result is not a node"); 255 } else if (qName.equals(XPathConstants.NODESET)) { 256 SequenceIterator iter = expression.iterate(context); 257 SequenceExtent extent = new SequenceExtent(iter); 258 if (model != null) { 259 Object result = model.convertToNodeList(extent); 260 if (result != null) { 261 return result; 262 } 263 } 264 return extent.convertToJava(List .class, context); 265 } else { 266 throw new IllegalArgumentException ("Unknown type for expected result"); 267 } 268 } catch (XPathException e) { 269 throw new XPathExpressionException (e); 270 } 271 } 272 273 279 280 public String evaluate(Object node) throws XPathExpressionException { 281 return (String )evaluate(node, XPathConstants.STRING); 282 } 283 284 293 public Object evaluate(InputSource inputSource, QName qName) throws XPathExpressionException { 294 try { 295 NodeInfo doc = new XPathEvaluator().setSource(new SAXSource (inputSource)); 296 return evaluate(doc, qName); 297 } catch (XPathException e) { 298 throw new XPathExpressionException (e); 299 } 300 } 301 302 309 310 public String evaluate(InputSource inputSource) throws XPathExpressionException { 311 try { 312 NodeInfo doc = new XPathEvaluator().setSource(new SAXSource (inputSource)); 313 return (String )evaluate(doc, XPathConstants.STRING); 314 } catch (XPathException e) { 315 throw new XPathExpressionException (e); 316 } 317 } 318 319 325 326 public Expression getInternalExpression() { 327 return expression; 328 } 329 330 } 331 332 343 | Popular Tags |