storyboard-webclient/src/app/services/criteria/criteria.js

203 lines
7.8 KiB
JavaScript

/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* Licensed 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.
*/
/**
* A service which centralizes management of search criteria: Creation,
* validation, filtering, criteria-to-parameter mapping, and more.
*/
angular.module('sb.services').service('Criteria',
function ($q, $log, $injector, Preference) {
'use strict';
return {
/**
* This method takes a set of criteria, and filters out the
* ones not valid for the passed resource.
*
* @param resourceName The name of the resource to filter for.
* @param criteria The list of criteria.
* @return {Array} A map of URL parameters.
*/
filterCriteria: function (resourceName, criteria) {
var resource = $injector.get(resourceName);
// Sanity check: If we don't have this resource, wat?
if (!resource || !resource.hasOwnProperty('criteriaFilter')) {
$log.warn('Attempting to filter criteria for unknown ' +
'resource "' + resourceName + '"');
return [];
}
return resource.criteriaFilter(criteria);
},
/**
* This method takes a set of criteria, and maps them against the
* query parameters available for the provided resource. It will
* skip any items not valid for this resource, and return an
* array of criteria that are valid
*
* @param resourceName
* @param criteria
* @return A map of URL parameters.
*/
mapCriteria: function (resourceName, criteria) {
var resource = $injector.get(resourceName);
// Sanity check: If we don't have this resource, wat?
if (!resource || !resource.hasOwnProperty('criteriaMap')) {
$log.warn('Attempting to map criteria for unknown ' +
'resource "' + resourceName + '"');
return {};
}
return resource.criteriaMap(criteria);
},
/**
* Create a new build criteria object.
*
* @param type The type of the criteria tag.
* @param value Value of the tag. Unique DB ID, or text string.
* @param title The title of the criteria tag.
* @returns {Criteria}
*/
create: function (type, value, title) {
title = title || value;
return {
'type': type,
'value': value,
'title': title
};
},
/**
* Rather than actually performing a search, this method returns a
* customized lambda that will perform our browse search for us.
*
* @param types An array of resource types to browse.
* @param pageSize An optional page size for the criteria. Defaults
* to the global page_size preference.
*/
buildCriteriaSearch: function (types, pageSize) {
pageSize = pageSize || Preference.get('page_size');
var resolvers = [];
types.forEach(function (type) {
// Retrieve an instance of the declared resource.
var resource = $injector.get(type);
if (!resource.hasOwnProperty('criteriaResolvers')) {
$log.warn('Resource type "' + type +
'" does not implement criteriaResolvers.');
return;
}
resource.criteriaResolvers().forEach(function (resolver) {
if (resolvers.indexOf(resolver) === -1) {
resolvers.push(resolver);
}
});
});
/**
* Construct the search lambda that issues the search
* and assembles the results.
*/
return function (searchString) {
var deferred = $q.defer();
// Clear the criteria
var promises = [];
resolvers.forEach(function (resolver) {
promises.push(resolver(searchString, pageSize));
});
// Wrap everything into a collective promise
$q.all(promises).then(function (results) {
var criteria = [];
results.forEach(function (result) {
result.forEach(function (item) {
criteria.push(item);
});
});
deferred.resolve(criteria);
});
// Return the search promise.
return deferred.promise;
};
},
/**
* This method takes a set of criteria, and filters out the
* ones not valid for the passed resource.
*
* @param parameterMap A map of criteria types and parameters
* in the search query they correspond to.
* @return {Function} A criteria filter for the passed parameters.
*/
buildCriteriaFilter: function (parameterMap) {
return function (criteria) {
var filteredCriteria = [];
criteria.forEach(function (item) {
if (parameterMap.hasOwnProperty(item.type)) {
filteredCriteria.push(item);
}
});
return filteredCriteria;
};
},
/**
* This method takes a set of criteria, and maps them against the
* query parameters available for the provided resource. It will
* skip any items not valid for this resource, and return an
* array of criteria that are valid
*
* @param parameterMap A map of criteria types and parameters
* in the search query they correspond to.
* @return {Function} A criteria mapper for the passed parameters.
*/
buildCriteriaMap: function (parameterMap) {
return function (criteria) {
var params = {};
criteria.forEach(function (item) {
if (parameterMap.hasOwnProperty(item.type)) {
if (parameterMap[item.type] === 'tags') {
if (!('tags' in params)) {
params.tags = [item.value];
} else {
params.tags.push(item.value);
}
} else {
params[parameterMap[item.type]] = item.value;
}
}
});
return params;
};
}
};
}
);