importPackage(Packages.de.elo.ix.jscript); importPackage(Packages.de.elo.ix.scripting); //@include lib_Class.js //@include lib_sol.common.Config.js //@include lib_sol.common.ObjectUtils.js //@include lib_sol.common.TranslateTerms.js //@include lib_sol.common.Template.js //@include lib_sol.common.ix.DynKwlDatabaseIterator.js //@include lib_sol.common.ix.DynKwlSearchIterator.js //@include lib_sol.common.ix.DynKwlFindChildrenIterator.js //@include lib_sol.common.ix.DynKwlBLPIterator.js var kwlConfigString, // has priority over config file, has to be valid JSON configPath, // used together with 'kwlName' to determine the kwl config from a file kwlName, // used together with 'configPath' to determine the kwl config from a file __ctx = (function () { return this; }()); /** * This implements generic keywordlist functionality. * * # Supported keywordlist types * * |Type|Used Iterator| * |:-----|:------| * |DB|Database iterator| * |SEARCH|Search iterator| * |CHILDREN|Children iterator| * * # Configuration * It is highly recommended to use the provided app to create/edit the configurations. * * Each configuration (regardless of the used iterator) has to contain the following properties: * * |Property|Property type|Description|Note| * |:-----|:-----|:------|:------| * |type|String|The type used. See `Supported keywordlist types`.|| * |translate|Boolean|Determines, if translation should be applied on the `header`, the `output` and `searchParams.message`|Has to be `true`, if any of those contain translation keys.| * |title|String|The title of the returned table. Could be a fixed string or a translation key.|| * |header|String[]|An array with the table headers. Could be a fixed strings or a translation keys.|Currently not supported in children iterator.| * |output|String[]|An array containing the output fields.|No prefix for index fields. `IX_MAP_` prefix for map fields. `IX_MAP_` prefix and `{i}` suffix for map fields inside a form table.| * |searchParams|Object[]|An array containing configuration for the search.|This uses the old syntax of the iterators. For better understanding the app should be used to create the configuration. Currently not supported in children iterator.| * * There are additional configuration properties for each iterator type. * * ## DB * |Property|Property type|Description|Note| * |:-----|:-----|:------|:------| * |sqlQuery|String|The SQL query for the database.|Number of selected columns has to be the same as the number of `headers` and `output`. If the query contains `?` they will be replaced by evaluating the `searchParams`.| * |jdbc|String|The name of a ressource defined in the Tomcat `META-INF/context.xml`.|Optional. If not set, the query will be executed against the ELO database.| * |dbName|String|To use a devian schema.|Optional| * * ## SEARCH * |Property|Property type|Description|Note| * |:-----|:-----|:------|:------| * |dataFields|String[]|The fields from the found Sord objects which will be mapped to the output fields.|Has to be of the same size as the `output` array. Only index fields are supported.| * * ## CHILDREN * |Property|Property type|Description|Note| * |:-----|:-----|:------|:------| * |parantId|String|The start point for the children search.|Could be an arcpath, an objId or a guid.| * * # How to * To implement a keywordlist using this generic class two things are necessary: a script and a configuration. * The script needs to be implemented, because the only way to configure a field with a dynamic keyword list, is the name of a script file. * The configuration will tell the generic class how to performe the queries and how the data should be returned. * * The script file has to contain the include for the `lib_Class` as well as the include for the `lib_sol.common.ix.GenericDynKwl`. * * The easiest way to include the configuration is directly as a JSON string in the script as a global variable `kwlConfigString`: * * var kwlConfigString = '{ ... }' * * A more convinient way to include the configuration is in a separate configuration file: * * var configPath = "/contract/Configuration/kwl.config", * kwlName = "Companies"; * * The `kwl.config` has to be JSON containing the property `Companies` which holds the configuration for this keyword list. * For even more convinience there is an app to edit those configuration file. * * @author PZ, ELO Digital Office GmbH * @version 1.04.000 * * @eloix * @requires sol.common.ix.DynKwlDatabaseIterator * @requires sol.common.ix.DynKwlSearchIterator * @requires sol.common.ix.DynKwlFindChildrenIterator */ sol.define("sol.common.ix.GenericDynKwl", { initialize: function (config) { var me = this, cfg, providerCfg, prepare; cfg = me.loadConfig(config); if (!cfg) { throw "No configuration found. Configuration has to be provided by kwlConfigString, configPath/kwlName or contructor parameter."; } providerCfg = me.prepareConfig(cfg); prepare = me.prepareFunctions[cfg.type]; if (!sol.common.ObjectUtils.isFunction(prepare)) { throw "IllegalConfigurationException: type '" + cfg.type + "' is not supported"; } me._provider = prepare.call(me, providerCfg, cfg); if (cfg.columnProperties) { if (cfg.columnProperties.length !== cfg.output.length) { throw "IllegalConfigurationException: number of columnProperties has to match the number of columns."; } me._provider.getColumnProperties = function () { return cfg.columnProperties; }; } }, /** * Retrieves the kwl provider which was created during initialization. * @return {Object} */ getProvider: function () { var me = this; return me._provider; }, /** * @private * Initializes the configuration. Either from `kwlConfigString`, a config file or the contructor parameter. * @param {Object} initConfigParam * @return {Object} */ loadConfig: function (initConfigParam) { var config; if (kwlConfigString) { config = JSON.parse(kwlConfigString); } else if (configPath && kwlName) { config = sol.create("sol.common.Config", { compose: configPath }).config; if (!config.hasOwnProperty(kwlName)) { throw "No configuration found for '" + kwlName + "' (path='" + configPath + "')"; } config = config[kwlName]; } else { config = initConfigParam; } return config; }, /** * @private * Initializes the provider config for all provider types. * @param {Object} config * @return {Object} */ prepareConfig: function (config) { var me = this, providerConfig; me.translate(config); providerConfig = { tableTitle: config.title, tableHeaders: config.header, tableKeyNames: __ctx.output || config.output, // override default from configuration formatting: config.formatting }; if (typeof __ctx.output === "function") { // if output is overriden by a function instead of a property, this to properties are used by the mixin to determine the correct output fields providerConfig.tableKeyNames_default = config.output; providerConfig.tableKeyNames_configOverride = config.output_; } return providerConfig; }, /** * @private * Performs the translation if `translate` is set to `true`. * @param {Object} config */ translate: function (config) { var required; if (config.translate === true) { required = [config.title]; if (config.header) { // filter null/undefined values config.header.forEach(function (headerEntry) { headerEntry && required.push(headerEntry); }); } if (config.searchParams) { // only add key, if there is a search param with a 'message' property config.searchParams.forEach(function (param) { param && param.message && required.push(param.message); }); } sol.common.TranslateTerms.require(required); config.title = sol.common.TranslateTerms.translate(config.title); if (config.header) { config.header.forEach(function (column, idx) { if (column) { config.header[idx] = sol.common.TranslateTerms.translate(column); } }); } if (config.searchParams) { config.searchParams.forEach(function (param) { if (param && param.message) { param.message = sol.common.TranslateTerms.translate(param.message); } }); } } }, /** * @private * @property {Object} * Lookup object for the prepare functions for all supported iterators. * These function prepare the iterator specific configuration and create the provider. */ prepareFunctions: { DB: function (providerConfig, config) { providerConfig.sqlQuery = config.sqlQuery; providerConfig.sqlParams = config.searchParams; providerConfig.dbName = config.dbName; providerConfig.jdbc = config.jdbc; return sol.create("sol.common.ix.DynKwlDatabaseIterator", providerConfig); }, CHILDREN: function (providerConfig, config) { providerConfig.searchParams = config.searchParams; providerConfig.parentId = config.parentId; return sol.create("sol.common.ix.DynKwlFindChildrenIterator", providerConfig); }, SEARCH: function (providerConfig, config) { var me = this, provider; providerConfig.searchParams = config.searchParams; provider = sol.create("sol.common.ix.DynKwlSearchIterator", providerConfig); provider.dataFields = config.dataFields; provider.getFindInfo = me.getFindInfo; provider.getRowData = me.getRowData; return provider; }, BLP: function (providerConfig, config) { var me = this, provider; providerConfig.queryConditions = config.searchParams; providerConfig.queryName = config.blpQueryName; providerConfig.queryModule = config.blpQueryModule; providerConfig.addInId = config.blpAddInId; providerConfig.projectId = config.blpProjectId; providerConfig.moduleId = config.blpModuleId; providerConfig.appToken = config.blpAppToken; providerConfig.serverUrl = config.blpServerUrl; provider = sol.create("sol.common.ix.DynKwlBLPIterator", providerConfig); return provider; } }, /** * @private * Implements a find by type search that is filtered by ObjKeys. * Used for the 'DynKwlSearchIterator'. * @param {String[]} filterList * @return {de.elo.ix.client.FindInfo} */ getFindInfo: function (filterList) { var me = this, findInfo, findByIndex, okeys, okey, i, param, filter; this.log.enter("getFindInfo"); findInfo = new FindInfo(); findByIndex = new FindByIndex(); okeys = []; if (filterList && filterList.length > 0) { for (i = 0; i < filterList.length; i++) { param = me.searchParams[i]; filter = filterList[i]; if (param.name && filter && (filter != "")) { okey = new ObjKey(); okey.name = param.searchName || param.name; okey.data = [filter]; okeys.push(okey); } } } findByIndex.objKeys = okeys; findInfo.findByIndex = findByIndex; findInfo.findOptions = new FindOptions(); findInfo.findOptions.searchMode = SearchModeC.ONE_TERM; this.log.exit("getFindInfo"); return findInfo; }, /** * @private * Basic implementation for search results. * This returns the content of the sord index fields. * Used for the 'DynKwlSearchIterator'. * @param {de.elo.ix.client.Sord} sord * @return {String[]} */ getRowData: function (sord) { var me = this, data = [], dataField, value, i; for (i = 0; i < me.dataFields.length; i++) { dataField = me.dataFields[i]; if (sol.common.ObjectUtils.type(dataField, "string")) { // backwards compatibility (common <= 1.13.002) value = sol.common.SordUtils.getObjKeyValue(sord, me.dataFields[i]); } else if (dataField.type === "SORD") { value = String(sord[dataField.key]); } else { value = sol.common.SordUtils.getObjKeyValue(sord, dataField.key); } data.push(value); } return data; } }); function getDataIterator() { var log = sol.create("sol.Logger", { scope: "sol.common.ix.GenericDynKwl#" + kwlName }), provider; try { log.info("DynamicKeywordList ("); provider = sol.create("sol.common.ix.GenericDynKwl").getProvider(); return new DynamicKeywordDataProvider(provider); } finally { log.info(")getDataIterator"); } }