1 (function (callback) { 2 if (typeof define === 'function' && define.amd) { 3 define(['core/Core', 'core/Parameter'], callback); 4 } 5 else { 6 callback(); 7 } 8 }(function () { 9 10 /** 11 * The ParameterStore, as its name suggests, stores Solr parameters. Widgets 12 * expose some of these parameters to the user. Whenever the user changes the 13 * values of these parameters, the state of the application changes. In order to 14 * allow the user to move back and forth between these states with the browser's 15 * Back and Forward buttons, and to bookmark these states, each state needs to 16 * be stored. The easiest method is to store the exposed parameters in the URL 17 * hash (see the <tt>ParameterHashStore</tt> class). However, you may implement 18 * your own storage method by extending this class. 19 * 20 * <p>For a list of possible parameters, please consult the links below.</p> 21 * 22 * @see http://wiki.apache.org/solr/CoreQueryParameters 23 * @see http://wiki.apache.org/solr/CommonQueryParameters 24 * @see http://wiki.apache.org/solr/SimpleFacetParameters 25 * @see http://wiki.apache.org/solr/HighlightingParameters 26 * @see http://wiki.apache.org/solr/MoreLikeThis 27 * @see http://wiki.apache.org/solr/SpellCheckComponent 28 * @see http://wiki.apache.org/solr/StatsComponent 29 * @see http://wiki.apache.org/solr/TermsComponent 30 * @see http://wiki.apache.org/solr/TermVectorComponent 31 * @see http://wiki.apache.org/solr/LocalParams 32 * 33 * @param properties A map of fields to set. Refer to the list of public fields. 34 * @class ParameterStore 35 */ 36 AjaxSolr.ParameterStore = AjaxSolr.Class.extend( 37 /** @lends AjaxSolr.ParameterStore.prototype */ 38 { 39 constructor: function (attributes) { 40 /** 41 * @param {Object} [attributes] 42 * @param {String[]} [attributes.exposed] The names of the exposed 43 * parameters. Any parameters that your widgets expose to the user, 44 * directly or indirectly, should be listed here. 45 */ 46 AjaxSolr.extend(this, { 47 exposed: [], 48 // The Solr parameters. 49 params: {}, 50 // A reference to the parameter store's manager. 51 manager: null 52 }, attributes); 53 }, 54 55 /** 56 * An abstract hook for child implementations. 57 * 58 * <p>This method should do any necessary one-time initializations.</p> 59 */ 60 init: function () {}, 61 62 /** 63 * Some Solr parameters may be specified multiple times. It is easiest to 64 * hard-code a list of such parameters. You may change the list by passing 65 * <code>{ multiple: /pattern/ }</code> as an argument to the constructor of 66 * this class or one of its children, e.g.: 67 * 68 * <p><code>new ParameterStore({ multiple: /pattern/ })</code> 69 * 70 * @param {String} name The name of the parameter. 71 * @returns {Boolean} Whether the parameter may be specified multiple times. 72 * @see http://lucene.apache.org/solr/api/org/apache/solr/handler/DisMaxRequestHandler.html 73 */ 74 isMultiple: function (name) { 75 return name.match(/^(?:bf|bq|facet\.date|facet\.date\.other|facet\.date\.include|facet\.field|facet\.pivot|facet\.range|facet\.range\.other|facet\.range\.include|facet\.query|fq|group\.field|group\.func|group\.query|pf|qf)$/); 76 }, 77 78 /** 79 * Returns a parameter. If the parameter doesn't exist, creates it. 80 * 81 * @param {String} name The name of the parameter. 82 * @returns {AjaxSolr.Parameter|AjaxSolr.Parameter[]} The parameter. 83 */ 84 get: function (name) { 85 if (this.params[name] === undefined) { 86 var param = new AjaxSolr.Parameter({ name: name }); 87 if (this.isMultiple(name)) { 88 this.params[name] = [ param ]; 89 } 90 else { 91 this.params[name] = param; 92 } 93 } 94 return this.params[name]; 95 }, 96 97 /** 98 * If the parameter may be specified multiple times, returns the values of 99 * all identically-named parameters. If the parameter may be specified only 100 * once, returns the value of that parameter. 101 * 102 * @param {String} name The name of the parameter. 103 * @returns {String[]|Number[]} The value(s) of the parameter. 104 */ 105 values: function (name) { 106 if (this.params[name] !== undefined) { 107 if (this.isMultiple(name)) { 108 var values = []; 109 for (var i = 0, l = this.params[name].length; i < l; i++) { 110 values.push(this.params[name][i].val()); 111 } 112 return values; 113 } 114 else { 115 return [ this.params[name].val() ]; 116 } 117 } 118 return []; 119 }, 120 121 /** 122 * If the parameter may be specified multiple times, adds the given parameter 123 * to the list of identically-named parameters, unless one already exists with 124 * the same value. If it may be specified only once, replaces the parameter. 125 * 126 * @param {String} name The name of the parameter. 127 * @param {AjaxSolr.Parameter} [param] The parameter. 128 * @returns {AjaxSolr.Parameter|Boolean} The parameter, or false. 129 */ 130 add: function (name, param) { 131 if (param === undefined) { 132 param = new AjaxSolr.Parameter({ name: name }); 133 } 134 if (this.isMultiple(name)) { 135 if (this.params[name] === undefined) { 136 this.params[name] = [ param ]; 137 } 138 else { 139 if (AjaxSolr.inArray(param.val(), this.values(name)) == -1) { 140 this.params[name].push(param); 141 } 142 else { 143 return false; 144 } 145 } 146 } 147 else { 148 this.params[name] = param; 149 } 150 return param; 151 }, 152 153 /** 154 * Deletes a parameter. 155 * 156 * @param {String} name The name of the parameter. 157 * @param {Number} [index] The index of the parameter. 158 */ 159 remove: function (name, index) { 160 if (index === undefined) { 161 delete this.params[name]; 162 } 163 else { 164 this.params[name].splice(index, 1); 165 if (this.params[name].length == 0) { 166 delete this.params[name]; 167 } 168 } 169 }, 170 171 /** 172 * Finds all parameters with matching values. 173 * 174 * @param {String} name The name of the parameter. 175 * @param {String|Number|String[]|Number[]|RegExp} value The value. 176 * @returns {String|Number[]} The indices of the parameters found. 177 */ 178 find: function (name, value) { 179 if (this.params[name] !== undefined) { 180 if (this.isMultiple(name)) { 181 var indices = []; 182 for (var i = 0, l = this.params[name].length; i < l; i++) { 183 if (AjaxSolr.equals(this.params[name][i].val(), value)) { 184 indices.push(i); 185 } 186 } 187 return indices.length ? indices : false; 188 } 189 else { 190 if (AjaxSolr.equals(this.params[name].val(), value)) { 191 return name; 192 } 193 } 194 } 195 return false; 196 }, 197 198 /** 199 * If the parameter may be specified multiple times, creates a parameter using 200 * the given name and value, and adds it to the list of identically-named 201 * parameters, unless one already exists with the same value. If it may be 202 * specified only once, replaces the parameter. 203 * 204 * @param {String} name The name of the parameter. 205 * @param {String|Number|String[]|Number[]} value The value. 206 * @param {Object} [locals] The parameter's local parameters. 207 * @returns {AjaxSolr.Parameter|Boolean} The parameter, or false. 208 */ 209 addByValue: function (name, value, locals) { 210 if (locals === undefined) { 211 locals = {}; 212 } 213 if (this.isMultiple(name) && AjaxSolr.isArray(value)) { 214 var ret = []; 215 for (var i = 0, l = value.length; i < l; i++) { 216 ret.push(this.add(name, new AjaxSolr.Parameter({ name: name, value: value[i], locals: locals }))); 217 } 218 return ret; 219 } 220 else { 221 return this.add(name, new AjaxSolr.Parameter({ name: name, value: value, locals: locals })); 222 } 223 }, 224 225 /** 226 * Deletes any parameter with a matching value. 227 * 228 * @param {String} name The name of the parameter. 229 * @param {String|Number|String[]|Number[]|RegExp} value The value. 230 * @returns {String|Number[]} The indices deleted. 231 */ 232 removeByValue: function (name, value) { 233 var indices = this.find(name, value); 234 if (indices) { 235 if (AjaxSolr.isArray(indices)) { 236 for (var i = indices.length - 1; i >= 0; i--) { 237 this.remove(name, indices[i]); 238 } 239 } 240 else { 241 this.remove(indices); 242 } 243 } 244 return indices; 245 }, 246 247 /** 248 * Returns the Solr parameters as a query string. 249 * 250 * <p>IE6 calls the default toString() if you write <tt>store.toString() 251 * </tt>. So, we need to choose another name for toString().</p> 252 */ 253 string: function () { 254 var params = [], string; 255 for (var name in this.params) { 256 if (this.isMultiple(name)) { 257 for (var i = 0, l = this.params[name].length; i < l; i++) { 258 string = this.params[name][i].string(); 259 if (string) { 260 params.push(string); 261 } 262 } 263 } 264 else { 265 string = this.params[name].string(); 266 if (string) { 267 params.push(string); 268 } 269 } 270 } 271 return params.join('&'); 272 }, 273 274 /** 275 * Parses a query string into Solr parameters. 276 * 277 * @param {String} str The string to parse. 278 */ 279 parseString: function (str) { 280 var pairs = str.split('&'); 281 for (var i = 0, l = pairs.length; i < l; i++) { 282 if (pairs[i]) { // ignore leading, trailing, and consecutive &'s 283 var param = new AjaxSolr.Parameter(); 284 param.parseString(pairs[i]); 285 this.add(param.name, param); 286 } 287 } 288 }, 289 290 /** 291 * Returns the exposed parameters as a query string. 292 * 293 * @returns {String} A string representation of the exposed parameters. 294 */ 295 exposedString: function () { 296 var params = [], string; 297 for (var i = 0, l = this.exposed.length; i < l; i++) { 298 if (this.params[this.exposed[i]] !== undefined) { 299 if (this.isMultiple(this.exposed[i])) { 300 for (var j = 0, m = this.params[this.exposed[i]].length; j < m; j++) { 301 string = this.params[this.exposed[i]][j].string(); 302 if (string) { 303 params.push(string); 304 } 305 } 306 } 307 else { 308 string = this.params[this.exposed[i]].string(); 309 if (string) { 310 params.push(string); 311 } 312 } 313 } 314 } 315 return params.join('&'); 316 }, 317 318 /** 319 * Resets the values of the exposed parameters. 320 */ 321 exposedReset: function () { 322 for (var i = 0, l = this.exposed.length; i < l; i++) { 323 this.remove(this.exposed[i]); 324 } 325 }, 326 327 /** 328 * Loads the values of exposed parameters from persistent storage. It is 329 * necessary, in most cases, to reset the values of exposed parameters before 330 * setting the parameters to the values in storage. This is to ensure that a 331 * parameter whose name is not present in storage is properly reset. 332 * 333 * @param {Boolean} [reset=true] Whether to reset the exposed parameters. 334 * before loading new values from persistent storage. Default: true. 335 */ 336 load: function (reset) { 337 if (reset === undefined) { 338 reset = true; 339 } 340 if (reset) { 341 this.exposedReset(); 342 } 343 this.parseString(this.storedString()); 344 }, 345 346 /** 347 * An abstract hook for child implementations. 348 * 349 * <p>Stores the values of the exposed parameters in persistent storage. This 350 * method should usually be called before each Solr request.</p> 351 */ 352 save: function () {}, 353 354 /** 355 * An abstract hook for child implementations. 356 * 357 * <p>Returns the string to parse from persistent storage.</p> 358 * 359 * @returns {String} The string from persistent storage. 360 */ 361 storedString: function () { 362 return ''; 363 } 364 }); 365 366 })); 367