AllElemMatchOp.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. "use strict";
  2. var MatchExpression = require('./MatchExpression');
  3. // From expression_array.h
  4. var AllElemMatchOp = module.exports = function AllElemMatchOp(){
  5. base.call(this);
  6. this._matchType = 'ALL';
  7. this._elementPath = new ElementPath();
  8. this._list = [];
  9. }, klass = AllElemMatchOp, base = MatchExpression , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  10. var errors = require("../../Errors.js"),
  11. ErrorCodes = errors.ErrorCodes,
  12. ElementPath = require('./ElementPath.js');
  13. // ElementPath _elementPath
  14. proto._elementPath = undefined;
  15. // std::vector< MatchExpression* > _list;
  16. proto._list = undefined;
  17. // StringData _path;
  18. proto._path = undefined;
  19. /**
  20. *
  21. * This method checks the input array and determines if each item inside matches
  22. * @method _allMatch
  23. * @param anArray
  24. *
  25. */
  26. proto._allMatch = function _allMatch(anArray) {
  27. if (this._list.length === 0) return false;
  28. for (var i = 0; i < this._list.length; i++) {
  29. if (!this._list[i].matchesArray(anArray, null)) return false;
  30. }
  31. return true;
  32. };
  33. /**
  34. *
  35. * This method adds a new expression to the internal array of expression
  36. * @method add
  37. * @param expr
  38. *
  39. */
  40. proto.add = function add(expr) {
  41. if (!expr) throw new Error("AllElemMatchOp:add#68 failed to verify expr");
  42. this._list.push(expr);
  43. };
  44. /**
  45. *
  46. * Writes a debug string for this object
  47. * @method debugString
  48. * @param level
  49. *
  50. */
  51. proto.debugString = function debugString(level) {
  52. console.debug(this._debugAddSpace(level) + this._path + " AllElemMatchOp: " + this._path + '\n');
  53. for (var i = 0; i < this._list.length; i++) {
  54. this._list[i].debugString(level +1);
  55. }
  56. };
  57. /**
  58. *
  59. * checks if this expression is == to the other
  60. * @method equivalent
  61. * @param other
  62. *
  63. */
  64. proto.equivalent = function equivalent(other) {
  65. if (this.matchType() != other.matchType()) {
  66. return false;
  67. }
  68. if (this._path != other._path) {
  69. return false;
  70. }
  71. if (this._list.length != other._list.length) {
  72. return false;
  73. }
  74. for (var i = 0; i < this._list.length; i++) {
  75. if (!this._list[i].equivalent(other._list[i])) {
  76. return false;
  77. }
  78. }
  79. return true;
  80. };
  81. /**
  82. *
  83. * gets the specified item from the list
  84. * @method getChild
  85. * @param i
  86. *
  87. */
  88. proto.getChild = function getChild(i) {
  89. return this._list[i];
  90. };
  91. /**
  92. *
  93. * Initialize the necessary items
  94. * @method init
  95. * @param path
  96. *
  97. */
  98. proto.init = function init(path) {
  99. this._path = path;
  100. var s = this._elementPath.init(this._path);
  101. this._elementPath.setTraverseLeafArray(false);
  102. return s;
  103. };
  104. /**
  105. *
  106. * matches checks the input doc against the internal path to see if it is a match
  107. * @method matches
  108. * @param doc
  109. * @param details
  110. *
  111. */
  112. proto.matches = function matches(doc, details) {
  113. var self = this,
  114. checker = function(element) {
  115. if (!(element instanceof Array)) {
  116. return false;
  117. }
  118. //var amIRoot = (element.length === 0);
  119. if (self._allMatch(element)) {
  120. return true;
  121. }
  122. /*
  123. if (!amIRoot && details && details.needRecord() {
  124. details.setElemMatchKey(element);
  125. }
  126. */
  127. return false;
  128. };
  129. return this._elementPath._matches(doc, details, checker);
  130. };
  131. /**
  132. *
  133. * Check if the input element matches
  134. * @method matchesSingleElement
  135. * @param e
  136. *
  137. */
  138. proto.matchesSingleElement = function matchesSingleElement(e) {
  139. if (!(e instanceof Array)) {
  140. return false;
  141. }
  142. return this._allMatch(e);
  143. };
  144. /**
  145. *
  146. * return the length of the internal array
  147. * @method numChildren
  148. * @param
  149. *
  150. */
  151. proto.numChildren = function numChildren() {
  152. return this._list.length;
  153. };
  154. /**
  155. *
  156. * return the internal path
  157. * @method path
  158. * @param
  159. *
  160. */
  161. proto.path = function path() {
  162. return this._path;
  163. };
  164. /**
  165. *
  166. * clone this instance to a new one
  167. * @method shallowClone
  168. * @param
  169. *
  170. */
  171. proto.shallowClone = function shallowClone() {
  172. var e = new AllElemMatchOp();
  173. e.init(this._path);
  174. e._list = this._list.slice(0);
  175. return e;
  176. };