gpii-universal
Version:
Cross platform, core components of the GPII personalization infrastructure.
153 lines (139 loc) • 6.35 kB
JavaScript
/*!
* Default Settings Loader
*
* Copyright 2018 OCAD University
* Copyright 2020 OCAD University
*
* Licensed under the New BSD license. You may not use this file except in
* compliance with this License.
*
* You may obtain a copy of the License at
* https://github.com/GPII/universal/blob/master/LICENSE.txt
*/
"use strict";
var fluid = fluid || require("infusion"),
gpii = fluid.registerNamespace("gpii"),
fs = require("fs"),
path = require("path"),
JSON5 = require("json5");
// The default settings loader reads default settings thru these steps:
// 1. Fetch default settings from the remote URL;
// 2. If the remote fetch fails, read default settings from the local system settings directory. In the case that the
// default settings file doesn't exists in the system settings directory, copy it from the code base to the settings
// directory.
// If the default settings file is not found at both places, return undefined.
fluid.defaults("gpii.defaultSettingsLoader", {
gradeNames: ["fluid.component"],
// The path to the file that has all QSS supported settings.
defaultSettingsInCodeBase: "%gpii-universal/testData/defaultSettings/defaultSettings.json5",
// The url to the remote default settings file. Must be provided by integrators.
defaultSettingsUrl: null,
members: {
gpiiSettingsDir: "@expand:{settingsDir}.getGpiiSettingsDir()",
// Populated by "onCreate.prepareSettingsFile" listener. It points to the default settings file in
// the settings directory rather than defaultSettingsInCodeBase, the default settings file in the code base.
defaultSettingsFile: null
},
components: {
settingsDir: {
type: "gpii.settingsDir"
},
remoteDefaultSettingsDataSource: {
type: "kettle.dataSource.URL",
options: {
url: "{defaultSettingsLoader}.options.defaultSettingsUrl"
}
}
},
events: {
onGet: null
},
listeners: {
"onCreate.prepareSettingsFile": {
listener: "fluid.set",
args: ["{that}", ["defaultSettingsFile"], "@expand:gpii.defaultSettingsLoader.prepareSettingsFile({that}.options.defaultSettingsInCodeBase,{that}.gpiiSettingsDir)"]
},
// The promise chain to fetch default settings:
// 1. If defaultSettingsUrl is provided, the first attempt is to fetch from the remote url;
// 2. If the fetch remote fails, perform the first fallback to read from the local system settings directory;
// 3. If the read from the local fails, return undefined.
"onGet.getRemoteDefaultSettings": {
listener: "gpii.defaultSettingsLoader.getRemoteDefaultSettings",
args: ["{that}.options.defaultSettingsUrl", "{that}.remoteDefaultSettingsDataSource"],
priority: "first"
},
"onGet.getLocalDefaultSettings": {
listener: "gpii.defaultSettingsLoader.getLocalDefaultSettings",
args: ["{arguments}.0", "{that}.defaultSettingsFile"],
priority: "after:getRemoteDefaultSettings"
}
},
invokers: {
get: {
funcName: "fluid.promise.fireTransformEvent",
args: ["{that}.events.onGet"]
}
}
});
/**
* Return the path to the default settings file in the settings directory. If it doesn't yet exist,
* copy the default settings file from the code base to the setting dir then return the path.
*
* @param {String} defaultSettingsInCodeBase - The path to the default settings file in the universal code base.
* @param {String} gpiiSettingsDir - GPII settings directory.
* @return {String} Return the path to the default settings file in the settings dir.
*/
gpii.defaultSettingsLoader.prepareSettingsFile = function (defaultSettingsInCodeBase, gpiiSettingsDir) {
var defaultSettingsInCodeBaseFullPath = fluid.module.resolvePath(defaultSettingsInCodeBase);
// Return undefined if the default settings file does not exist in the code base
if (!fs.existsSync(defaultSettingsInCodeBaseFullPath)) {
return undefined;
}
var gpiiSettingsAbsolutePath = fluid.module.resolvePath(gpiiSettingsDir);
var defaultSettingsFileName = path.basename(defaultSettingsInCodeBaseFullPath);
var defaultSettingsFile = path.join(gpiiSettingsAbsolutePath, defaultSettingsFileName);
// Copy the default settings file to the settings dir if it doesn't already in there
if (!fs.existsSync(defaultSettingsFile)) {
fs.writeFileSync(defaultSettingsFile, fs.readFileSync(defaultSettingsInCodeBaseFullPath, "utf-8"));
}
return defaultSettingsFile;
};
/**
* Read default settings from the remote URL
*
* @param {String} url - The url pointing to the remote default settings file.
* @param {Object} remoteDefaultSettingsDataSource - The content fetched from the remote default settings url.
* @return {Object} The content of default settings fetched from the remote URL. If the fetch fails,
* return undefined.
*/
gpii.defaultSettingsLoader.getRemoteDefaultSettings = function (url, remoteDefaultSettingsDataSource) {
if (!url) {
return undefined;
} else {
var promiseTogo = fluid.promise();
var remoteContentPromise = remoteDefaultSettingsDataSource.get();
remoteContentPromise.then(function (remoteDefaultSettings) {
promiseTogo.resolve(remoteDefaultSettings);
}, function () {
// If the fetch fails, return undefined.
promiseTogo.resolve(undefined);
});
return promiseTogo;
}
};
/**
* The fall back: read default settings from the local file system
*
* @param {Object} remoteDefaultSettings - The content fetched from the remote default settings url.
* @param {String} defaultSettingsFile - The path to the local default settings file.
* @return {Object} Default settings.
*/
gpii.defaultSettingsLoader.getLocalDefaultSettings = function (remoteDefaultSettings, defaultSettingsFile) {
var promiseTogo = fluid.promise();
if (remoteDefaultSettings) {
promiseTogo.resolve(remoteDefaultSettings);
} else {
promiseTogo.resolve(defaultSettingsFile ? JSON5.parse(fs.readFileSync(defaultSettingsFile, "utf-8")) : undefined);
}
return promiseTogo;
};