RelativeStepFilter.java 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (c) 2006 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.xquery.util;
  4. import gnu.lists.*;
  5. import gnu.kawa.xml.*;
  6. /** Used to filter the output of RelativeStep.
  7. * Atomic values are passed though as-is, while node values are sorted
  8. * by document order and duplicates removed. An exception is thrown
  9. * if there is a mix of atoms and nodes.
  10. * Informally: {@code E1/E2} is implemented as:
  11. * {@code RelativeStepFilter(for $dot in E1 return E2)}.
  12. */
  13. public class RelativeStepFilter extends FilterConsumer
  14. implements PositionConsumer
  15. {
  16. // 'A' for atomic, 'N' for nodes, '\0' for neither.
  17. char seen;
  18. SortedNodes snodes;
  19. public RelativeStepFilter (Consumer base)
  20. {
  21. super(base);
  22. }
  23. // Not sure if this is ever called ...
  24. public void writePosition(SeqPosition position)
  25. {
  26. writePosition(position.sequence, position.ipos);
  27. }
  28. public void writeObject(Object v)
  29. {
  30. if (v instanceof SeqPosition)
  31. {
  32. SeqPosition n = (SeqPosition) v;
  33. writePosition(n.sequence, n.ipos);
  34. }
  35. else
  36. super.writeObject(v);
  37. }
  38. protected void beforeContent ()
  39. {
  40. if (seen == 'N')
  41. throw new Error("path returns mix of atoms and nodes");
  42. seen = 'A';
  43. }
  44. public void writePosition(AbstractSequence seq, int ipos)
  45. {
  46. if (seen == 'A')
  47. throw new Error("path returns mix of atoms and nodes");
  48. seen = 'N';
  49. if (snodes == null)
  50. snodes = new SortedNodes();
  51. snodes.writePosition(seq, ipos);
  52. }
  53. public void finish ()
  54. {
  55. if (snodes != null)
  56. snodes.consume(base);
  57. snodes = null;
  58. }
  59. }