UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

137 lines (121 loc) 5.75 kB
/* * Flat MatchMaker * * Copyright 2014 Raising the Floor - International * Copyright 2018 OCAD University * * Licensed under the New BSD license. You may not use this file except in * compliance with this License. * * The research leading to these results has received funding from the European Union's * Seventh Framework Programme (FP7/2007-2013) * under grant agreement no. 289016. * * You may obtain a copy of the License at * https://github.com/GPII/universal/blob/master/LICENSE.txt */ /* eslint-env browser */ /* eslint strict: ["error", "function"] */ (function () { "use strict"; var fluid = fluid || require("infusion"), gpii = fluid.registerNamespace("gpii"); require("kettle"); fluid.defaults("gpii.flatMatchMaker", { gradeNames: ["fluid.component"], components: { ontologyHandler: { "type": "gpii.ontologyHandler" } }, invokers: { match: { funcName: "gpii.flatMatchMaker.match", args: [ "{ontologyHandler}", "{arguments}.0", "{flatMatchMaker}.disposeStrategy"] }, disposeStrategy: { funcName: "gpii.flatMatchMaker.disposeStrategy", args: [ "{arguments}.0", "{arguments}.1", "{arguments}.2"] // leaves, solrecs, solutionTypeMapping } } }); /* * Main function of the flat matchmaker. Ensures that the inferred common terms are taken * into account and that the preferences are stored in a hierarchical format, needed by * the flat MM, and then runs the framework's 'disposeSolutions' function with the * flatMatchMaker.disposeStrategy strategy. The correct output format is ensured by the * buildReturnPayload function of the MM framework. */ gpii.flatMatchMaker.match = function (ontologyHandler, payload, disposeStrategy) { // augment payload with information about the solution types var appTransformSpec = gpii.ontologyHandler.getTransformSpec(ontologyHandler.ontologyTransformSpecs, "flat", "apptology"); gpii.matchMakerFramework.utils.addSolutionTypeInformation(payload, appTransformSpec); payload.hierarchicalPrefs = ontologyHandler.prefsToOntology(payload.preferences, "flat", "ISO24751"); var transformSpec = gpii.ontologyHandler.getTransformSpec(ontologyHandler.ontologyTransformSpecs, "flat", "ISO24751"); var disposed = gpii.matchMakerFramework.utils.disposeSolutions(payload, disposeStrategy, transformSpec); return gpii.matchMakerFramework.utils.buildReturnPayload(payload, disposed); }; /* * Very simple strategy that accepts any solution for which any preference el-path matches * a one of the solutions capabilities (inferred from the capabilities transformations and * capabilities block of that solution). * * We consider that any accepted solution will be activated because of the simple-minded * policy adopted by the flat matchmaker */ gpii.flatMatchMaker.disposeStrategy = function (leaves, solrecs, solutionTypeMapping) { fluid.each(solrecs, function (solrec) { var accepted = fluid.find(leaves, function (leaf) { return fluid.get(solrec.skeleton, leaf, fluid.model.escapedGetConfig); }); if (solrec.priority !== undefined) { accepted = true; } fluid.extend(solrec, { disposition: accepted ? "accept" : "reject", active: accepted ? true : false // always true if accepted }); }); // Apply Apptology fluid.each(solutionTypeMapping, function (solutions) { var numOfSolutions = fluid.keys(solutions).length; // If there's only one solution for a solution type, the filtering by apptology is not needed. if (numOfSolutions > 1) { gpii.flatMatchMaker.applyApptology(solrecs, solutions); } }); return solrecs; }; // Apply "Apptology" to only select one solution from all that perform the same functionality. For example, only one // screen reader will be selected when there are multiple matched screen readers. gpii.flatMatchMaker.applyApptology = function (solrecs, solutions) { var bestSolutionId, highestPriority; // Find the best solution: // 1. the one with the highest priority value; // 2. if all solutions have the same priority value, select the first one. fluid.each(solutions, function (value, solutionId) { var thisPriority = solrecs[solutionId].priority ? solrecs[solutionId].priority : 0; if (solrecs[solutionId].active) { // Select the first active solution to be the best match in case all solutions have the same priority. if (!bestSolutionId) { bestSolutionId = solutionId; highestPriority = thisPriority; } // find the solution with the highest priority if (thisPriority > highestPriority) { bestSolutionId = solutionId; highestPriority = thisPriority; } } }); // Reject all non-best solutions fluid.each(solutions, function (value, solutionId) { // Reject solutions from 2nd place onwards if (solrecs[solutionId].active && solutionId !== bestSolutionId) { fluid.set(solrecs, [solutionId, "disposition"], "reject"); fluid.set(solrecs, [solutionId, "active"], false); } }); }; })();