blob: ad7e03202262a54a60df712434c13a5b30aae712 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function (callback) {
if (typeof define === 'function' && define.amd) {
define(['core/Core', 'core/Parameter'], callback);
}
else {
callback();
}
}(function () {
/**
* The ParameterStore, as its name suggests, stores Solr parameters. Widgets
* expose some of these parameters to the user. Whenever the user changes the
* values of these parameters, the state of the application changes. In order to
* allow the user to move back and forth between these states with the browser's
* Back and Forward buttons, and to bookmark these states, each state needs to
* be stored. The easiest method is to store the exposed parameters in the URL
* hash (see the <tt>ParameterHashStore</tt> class). However, you may implement
* your own storage method by extending this class.
*
* <p>For a list of possible parameters, please consult the links below.</p>
*
* @see http://wiki.apache.org/solr/CoreQueryParameters
* @see http://wiki.apache.org/solr/CommonQueryParameters
* @see http://wiki.apache.org/solr/SimpleFacetParameters
* @see http://wiki.apache.org/solr/HighlightingParameters
* @see http://wiki.apache.org/solr/MoreLikeThis
* @see http://wiki.apache.org/solr/SpellCheckComponent
* @see http://wiki.apache.org/solr/StatsComponent
* @see http://wiki.apache.org/solr/TermsComponent
* @see http://wiki.apache.org/solr/TermVectorComponent
* @see http://wiki.apache.org/solr/LocalParams
*
* @param properties A map of fields to set. Refer to the list of public fields.
* @class ParameterStore
*/
AjaxSolr.ParameterStore = AjaxSolr.Class.extend(
/** @lends AjaxSolr.ParameterStore.prototype */
{
constructor: function (attributes) {
/**
* @param {Object} [attributes]
* @param {String[]} [attributes.exposed] The names of the exposed
* parameters. Any parameters that your widgets expose to the user,
* directly or indirectly, should be listed here.
*/
AjaxSolr.extend(this, {
exposed: [],
// The Solr parameters.
params: {},
// A reference to the parameter store's manager.
manager: null
}, attributes);
},
/**
* An abstract hook for child implementations.
*
* <p>This method should do any necessary one-time initializations.</p>
*/
init: function () {},
/**
* Some Solr parameters may be specified multiple times. It is easiest to
* hard-code a list of such parameters. You may change the list by passing
* <code>{ multiple: /pattern/ }</code> as an argument to the constructor of
* this class or one of its children, e.g.:
*
* <p><code>new ParameterStore({ multiple: /pattern/ })</code>
*
* @param {String} name The name of the parameter.
* @returns {Boolean} Whether the parameter may be specified multiple times.
* @see http://lucene.apache.org/solr/api/org/apache/solr/handler/DisMaxRequestHandler.html
*/
isMultiple: function (name) {
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)$/);
},
/**
* Returns a parameter. If the parameter doesn't exist, creates it.
*
* @param {String} name The name of the parameter.
* @returns {AjaxSolr.Parameter|AjaxSolr.Parameter[]} The parameter.
*/
get: function (name) {
if (this.params[name] === undefined) {
var param = new AjaxSolr.Parameter({ name: name });
if (this.isMultiple(name)) {
this.params[name] = [ param ];
}
else {
this.params[name] = param;
}
}
return this.params[name];
},
/**
* If the parameter may be specified multiple times, returns the values of
* all identically-named parameters. If the parameter may be specified only
* once, returns the value of that parameter.
*
* @param {String} name The name of the parameter.
* @returns {String[]|Number[]} The value(s) of the parameter.
*/
values: function (name) {
if (this.params[name] !== undefined) {
if (this.isMultiple(name)) {
var values = [];
for (var i = 0, l = this.params[name].length; i < l; i++) {
values.push(this.params[name][i].val());
}
return values;
}
else {
return [ this.params[name].val() ];
}
}
return [];
},
/**
* If the parameter may be specified multiple times, adds the given parameter
* to the list of identically-named parameters, unless one already exists with
* the same value. If it may be specified only once, replaces the parameter.
*
* @param {String} name The name of the parameter.
* @param {AjaxSolr.Parameter} [param] The parameter.
* @returns {AjaxSolr.Parameter|Boolean} The parameter, or false.
*/
add: function (name, param) {
if (param === undefined) {
param = new AjaxSolr.Parameter({ name: name });
}
if (this.isMultiple(name)) {
if (this.params[name] === undefined) {
this.params[name] = [ param ];
}
else {
if (AjaxSolr.inArray(param.val(), this.values(name)) == -1) {
this.params[name].push(param);
}
else {
return false;
}
}
}
else {
this.params[name] = param;
}
return param;
},
/**
* Deletes a parameter.
*
* @param {String} name The name of the parameter.
* @param {Number} [index] The index of the parameter.
*/
remove: function (name, index) {
if (index === undefined) {
delete this.params[name];
}
else {
this.params[name].splice(index, 1);
if (this.params[name].length == 0) {
delete this.params[name];
}
}
},
/**
* Finds all parameters with matching values.
*
* @param {String} name The name of the parameter.
* @param {String|Number|String[]|Number[]|RegExp} value The value.
* @returns {String|Number[]} The indices of the parameters found.
*/
find: function (name, value) {
if (this.params[name] !== undefined) {
if (this.isMultiple(name)) {
var indices = [];
for (var i = 0, l = this.params[name].length; i < l; i++) {
if (AjaxSolr.equals(this.params[name][i].val(), value)) {
indices.push(i);
}
}
return indices.length ? indices : false;
}
else {
if (AjaxSolr.equals(this.params[name].val(), value)) {
return name;
}
}
}
return false;
},
/**
* If the parameter may be specified multiple times, creates a parameter using
* the given name and value, and adds it to the list of identically-named
* parameters, unless one already exists with the same value. If it may be
* specified only once, replaces the parameter.
*
* @param {String} name The name of the parameter.
* @param {String|Number|String[]|Number[]} value The value.
* @param {Object} [locals] The parameter's local parameters.
* @returns {AjaxSolr.Parameter|Boolean} The parameter, or false.
*/
addByValue: function (name, value, locals) {
if (locals === undefined) {
locals = {};
}
if (this.isMultiple(name) && AjaxSolr.isArray(value)) {
var ret = [];
for (var i = 0, l = value.length; i < l; i++) {
ret.push(this.add(name, new AjaxSolr.Parameter({ name: name, value: value[i], locals: locals })));
}
return ret;
}
else {
return this.add(name, new AjaxSolr.Parameter({ name: name, value: value, locals: locals }));
}
},
/**
* Deletes any parameter with a matching value.
*
* @param {String} name The name of the parameter.
* @param {String|Number|String[]|Number[]|RegExp} value The value.
* @returns {String|Number[]} The indices deleted.
*/
removeByValue: function (name, value) {
var indices = this.find(name, value);
if (indices) {
if (AjaxSolr.isArray(indices)) {
for (var i = indices.length - 1; i >= 0; i--) {
this.remove(name, indices[i]);
}
}
else {
this.remove(indices);
}
}
return indices;
},
/**
* Returns the Solr parameters as a query string.
*
* <p>IE6 calls the default toString() if you write <tt>store.toString()
* </tt>. So, we need to choose another name for toString().</p>
*/
string: function () {
var params = [], string;
for (var name in this.params) {
if (this.isMultiple(name)) {
for (var i = 0, l = this.params[name].length; i < l; i++) {
string = this.params[name][i].string();
if (string) {
params.push(string);
}
}
}
else {
string = this.params[name].string();
if (string) {
params.push(string);
}
}
}
return params.join('&');
},
/**
* Parses a query string into Solr parameters.
*
* @param {String} str The string to parse.
*/
parseString: function (str) {
var pairs = str.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
if (pairs[i]) { // ignore leading, trailing, and consecutive &'s
var param = new AjaxSolr.Parameter();
param.parseString(pairs[i]);
this.add(param.name, param);
}
}
},
/**
* Returns the exposed parameters as a query string.
*
* @returns {String} A string representation of the exposed parameters.
*/
exposedString: function () {
var params = [], string;
for (var i = 0, l = this.exposed.length; i < l; i++) {
if (this.params[this.exposed[i]] !== undefined) {
if (this.isMultiple(this.exposed[i])) {
for (var j = 0, m = this.params[this.exposed[i]].length; j < m; j++) {
string = this.params[this.exposed[i]][j].string();
if (string) {
params.push(string);
}
}
}
else {
string = this.params[this.exposed[i]].string();
if (string) {
params.push(string);
}
}
}
}
return params.join('&');
},
/**
* Resets the values of the exposed parameters.
*/
exposedReset: function () {
for (var i = 0, l = this.exposed.length; i < l; i++) {
this.remove(this.exposed[i]);
}
},
/**
* Loads the values of exposed parameters from persistent storage. It is
* necessary, in most cases, to reset the values of exposed parameters before
* setting the parameters to the values in storage. This is to ensure that a
* parameter whose name is not present in storage is properly reset.
*
* @param {Boolean} [reset=true] Whether to reset the exposed parameters.
* before loading new values from persistent storage. Default: true.
*/
load: function (reset) {
if (reset === undefined) {
reset = true;
}
if (reset) {
this.exposedReset();
}
this.parseString(this.storedString());
},
/**
* An abstract hook for child implementations.
*
* <p>Stores the values of the exposed parameters in persistent storage. This
* method should usually be called before each Solr request.</p>
*/
save: function () {},
/**
* An abstract hook for child implementations.
*
* <p>Returns the string to parse from persistent storage.</p>
*
* @returns {String} The string from persistent storage.
*/
storedString: function () {
return '';
}
});
}));