1. package org.apache.xpath.operations;
  2. import javax.xml.transform.TransformerException;
  3. import org.apache.xml.dtm.DTM;
  4. import org.apache.xml.dtm.DTMIterator;
  5. import org.apache.xml.dtm.DTMManager;
  6. import org.apache.xpath.Expression;
  7. import org.apache.xpath.XPathContext;
  8. import org.apache.xpath.objects.XNodeSet;
  9. import org.apache.xpath.objects.XObject;
  10. /**
  11. * This is a "smart" variable reference that is used in situations where
  12. * an absolute path is optimized into a variable reference, but may
  13. * be used in some situations where the document context may have changed.
  14. * For instance, in select="document(doc/@href)//name[//salary > 7250]", the
  15. * root in the predicate will be different for each node in the set. While
  16. * this is easy to detect statically in this case, in other cases static
  17. * detection would be very hard or impossible. So, this class does a dynamic check
  18. * to make sure the document context of the referenced variable is the same as
  19. * the current document context, and, if it is not, execute the referenced variable's
  20. * expression with the current context instead.
  21. */
  22. public class VariableSafeAbsRef extends Variable
  23. {
  24. /**
  25. * Dereference the variable, and return the reference value. Note that lazy
  26. * evaluation will occur. If a variable within scope is not found, a warning
  27. * will be sent to the error listener, and an empty nodeset will be returned.
  28. *
  29. *
  30. * @param xctxt The runtime execution context.
  31. *
  32. * @return The evaluated variable, or an empty nodeset if not found.
  33. *
  34. * @throws javax.xml.transform.TransformerException
  35. */
  36. public XObject execute(XPathContext xctxt, boolean destructiveOK)
  37. throws javax.xml.transform.TransformerException
  38. {
  39. XNodeSet xns = (XNodeSet)super.execute(xctxt, destructiveOK);
  40. DTMManager dtmMgr = xctxt.getDTMManager();
  41. int context = xctxt.getContextNode();
  42. if(dtmMgr.getDTM(xns.getRoot()).getDocument() !=
  43. dtmMgr.getDTM(context).getDocument())
  44. {
  45. Expression expr = (Expression)xns.getContainedIter();
  46. xns = (XNodeSet)expr.asIterator(xctxt, context);
  47. }
  48. return xns;
  49. }
  50. }