1 /**
  2  * @fileoverview An abstract class representing basic expressions.
  3  */
  4 
  5 goog.provide('xrx.xpath.Expr');
  6 
  7 goog.require('xrx.xpath.NodeSet');
  8 
  9 
 10 
 11 /**
 12  * Abstract constructor for an XPath expression.
 13  *
 14  * @param {!xrx.xpath.DataType} dataType The data type that the expression
 15  *                                    will be evaluated into.
 16  * @constructor
 17  */
 18 xrx.xpath.Expr = function(dataType) {
 19 
 20   /**
 21    * @type {!xrx.xpath.DataType}
 22    * @private
 23    */
 24   this.dataType_ = dataType;
 25 
 26   /**
 27    * @type {boolean}
 28    * @private
 29    */
 30   this.needContextPosition_ = false;
 31 
 32   /**
 33    * @type {boolean}
 34    * @private
 35    */
 36   this.needContextNode_ = false;
 37 
 38   /**
 39    * @type {?{name: string, valueExpr: xrx.xpath.Expr}}
 40    * @private
 41    */
 42   this.quickAttr_ = null;
 43 };
 44 
 45 
 46 /**
 47  * Indentation method for pretty printing.
 48  *
 49  * @param {*} obj The object to return a string representation for.
 50  * @return {string} The string prepended with newline and two spaces.
 51  */
 52 xrx.xpath.Expr.indent = function(obj) {
 53   return '\n  ' + obj.toString().split('\n').join('\n  ');
 54 };
 55 
 56 
 57 /**
 58  * Evaluates the expression.
 59  *
 60  * @param {!xrx.xpath.Context} ctx The context to evaluate the expression in.
 61  * @return {!(string|boolean|number|xrx.xpath.NodeSet)} The evaluation result.
 62  */
 63 xrx.xpath.Expr.prototype.evaluate = goog.abstractMethod;
 64 
 65 
 66 /**
 67  * @override
 68  */
 69 xrx.xpath.Expr.prototype.toString = goog.abstractMethod;
 70 
 71 
 72 /**
 73  * Returns the data type of the expression.
 74  *
 75  * @return {!xrx.xpath.DataType} The data type that the expression
 76  *                            will be evaluated into.
 77  */
 78 xrx.xpath.Expr.prototype.getDataType = function() {
 79   return this.dataType_;
 80 };
 81 
 82 
 83 /**
 84  * Returns whether the expression needs context position to be evaluated.
 85  *
 86  * @return {boolean} Whether context position is needed.
 87  */
 88 xrx.xpath.Expr.prototype.doesNeedContextPosition = function() {
 89   return this.needContextPosition_;
 90 };
 91 
 92 
 93 /**
 94  * Sets whether the expression needs context position to be evaluated.
 95  *
 96  * @param {boolean} flag Whether context position is needed.
 97  */
 98 xrx.xpath.Expr.prototype.setNeedContextPosition = function(flag) {
 99   this.needContextPosition_ = flag;
100 };
101 
102 
103 /**
104  * Returns whether the expression needs context node to be evaluated.
105  *
106  * @return {boolean} Whether context node is needed.
107  */
108 xrx.xpath.Expr.prototype.doesNeedContextNode = function() {
109   return this.needContextNode_;
110 };
111 
112 
113 /**
114  * Sets whether the expression needs context node to be evaluated.
115  *
116  * @param {boolean} flag Whether context node is needed.
117  */
118 xrx.xpath.Expr.prototype.setNeedContextNode = function(flag) {
119   this.needContextNode_ = flag;
120 };
121 
122 
123 /**
124  * Returns the quick attribute information, if exists.
125  *
126  * @return {?{name: string, valueExpr: xrx.xpath.Expr}} The attribute
127  *         information.
128  */
129 xrx.xpath.Expr.prototype.getQuickAttr = function() {
130   return this.quickAttr_;
131 };
132 
133 
134 /**
135  * Sets up the quick attribute info.
136  *
137  * @param {?{name: string, valueExpr: xrx.xpath.Expr}} attrInfo The attribute
138  *        information.
139  */
140 xrx.xpath.Expr.prototype.setQuickAttr = function(attrInfo) {
141   this.quickAttr_ = attrInfo;
142 };
143 
144 
145 /**
146  * Evaluate and interpret the result as a number.
147  *
148  * @param {!xrx.xpath.Context} ctx The context to evaluate the expression in.
149  * @return {number} The evaluated number value.
150  */
151 xrx.xpath.Expr.prototype.asNumber = function(ctx) {
152   var exrs = this.evaluate(ctx);
153   if (exrs instanceof xrx.xpath.NodeSet) {
154     return exrs.number();
155   }
156   return +exrs;
157 };
158 
159 
160 /**
161  * Evaluate and interpret the result as a string.
162  *
163  * @param {!xrx.xpath.Context} ctx The context to evaluate the expression in.
164  * @return {string} The evaluated string.
165  */
166 xrx.xpath.Expr.prototype.asString = function(ctx) {
167   var exrs = this.evaluate(ctx);
168   if (exrs instanceof xrx.xpath.NodeSet) {
169     return exrs.string();
170   }
171   return '' + exrs;
172 };
173 
174 
175 /**
176  * Evaluate and interpret the result as a boolean value.
177  *
178  * @param {!xrx.xpath.Context} ctx The context to evaluate the expression in.
179  * @return {boolean} The evaluated boolean value.
180  */
181 xrx.xpath.Expr.prototype.asBool = function(ctx) {
182   var exrs = this.evaluate(ctx);
183   if (exrs instanceof xrx.xpath.NodeSet) {
184     return !!exrs.getLength();
185   }
186   return !!exrs;
187 };
188