importPackage(Packages.de.elo.ix.client); //@include lib_Class.js //@include lib_sol.common.ObjectUtils.js /** * Converts a MapTable of a TemplateSord structure into an array * All types except the mapKeys are ignored by the converter. * * * MapTable fields that are not in the output definition * are also not considered in the result and are discarded. * * This also works with wfMapKeys! * * * Example of a TemplateSord object with MapTable * * { * mapKeys: { * "PERSON_ADDRESS_STREET1": "Musterstraße", * "PERSON_ADDRESS_CITY1": "Musterstadt" * } * } * * Example Call * * var converter = sol.create("sol.meeting.ObjectFormatter.MapTableToArrayToArray", { * output: [ * { source: { key: "PERSON_CRUD_STATUS" }, target: { prop: "status" } } * { source: { key: "PERSON_ADDRESS_CITY" }, target: { prop: "city" } } * ], * options: { * ignorePropertyNames: true, * filter: [ * { "prop" : "sord.mapKeys.SOLUTION_FIELD", value: "CREATE" } * ] * } * }); * * Output * * [ * { street: "Musterstraße", city: "Musterstadt", $mapIndex: "1"} * ] * * The special prop $mapIndex is added to the result object to determine the mapIndex in * further processing * * ### Options * * { * options: { ignorePropertyNames: true } * } * * When this parameter is defined, the target.prop name is ignored by default. An Array with objects on the original fieldnames will be created. * * #### propSelector * * When this parameter is defined the result array will be returned as simple string array instead of complex object * propSelector must select an output target prop. Only this prop will be returned. Others will be ignored. * * var converter = sol.create("sol.meeting.ObjectFormatter.MapTableToArray", { * output: [ * { source: { key: "PERSON_USERNAME1" }, target: { prop: "username" } } * { source: { key: "PERSON_USERNAME2" }, target: { prop: "username" } } * ], * options: { * propSelector: "username" * } * }); * * Output * * [ * "Sandra Renz", "Bodo Kraft" * ] * * * @requires sol.common.ObjectUtils * */ sol.define("sol.common.ObjectFormatter.MapTableToArray", { requiredConfig: ["output"], mixins: ["sol.common.mixins.ObjectFilter"], /** * @cfg {String} [kind=mapKeys] (optional) * Use formatter for wfMapKeys or mapKeys. Only this types are supported. * You have to decide wheather you want to convert wfMapKeys or mapKeys */ /** * @cfg {Object} options * @cfg {Boolean} options.ignorePropertyNames all target prop definition will be ignored * @cfg {String|Boolean} options.propSelector return single property in a flat string array with the passed prop */ initialize: function (config) { var me = this; if (!config.kind) { config.kind = "mapKeys"; } me.$super("sol.Base", "initialize", [config]); me.outputCache = {}; me.options = me.options || {}; me.options.ignorePropertyNames = me.options.ignorePropertyNames || false; me.options.propSelector = me.options.propSelector || false; me.options.filter = me.options.filter || []; me.sanitizeOutputConfig(me.output); }, sanitizeOutputConfig: function (output) { var me = this; // prepare an output temporary cache // With the cache we can find output definitions easier output.forEach(function (definition) { if (!definition.source) { throw Error("missing source prop in output definition, " + JSON.stringify(definition)); } if (!sol.common.ObjectUtils.type(definition.source.key, "string")) { throw Error("key in output definition is not a string," + JSON.stringify(definition)); } me.outputCache[definition.source.key] = definition; }); if (!(me.kind === "wfMapKeys" || me.kind === "mapKeys")) { throw Error("Only wfMapKeys or mapKeys are supported"); } }, /** * Convert mapKeys of a templateSord object to an array * @param {Object} templateSord * @param {Object} config * @param {Array} config.fields */ format: function (templateSord) { var me = this, result = {}, tableData, filter; if (!templateSord || !templateSord[me.kind]) { return []; } Object.keys(templateSord[me.kind]).forEach(function (mapKey) { var mapIndex = me.getFieldNameIndex(mapKey), outputDef, value, fieldName, targetFieldname; if (mapIndex > 0) { fieldName = me.getFieldName(mapKey); outputDef = me.outputCache[fieldName]; // transform mapKey only when output definition exists if (outputDef) { value = sol.common.ObjectUtils.getProp(templateSord[me.kind], mapKey); if (!result[mapIndex]) { // create new entry, when we read a new row result[mapIndex] = {}; } targetFieldname = me.getTargetFieldName(mapKey, outputDef); sol.common.ObjectUtils.setProp(result[mapIndex], targetFieldname, value); } } else { me.logger.debug(["skip field `{0}` because it is not a maptable", mapKey]); } }); tableData = me.convertToArray(result); me.logger.info(["tableData {0}", JSON.stringify(tableData)]) if (me.options.filter.length > 0) { // from mixin sol.common.ObjectUtils.ObjectFilter filter = me.generateFilter(me.options.filter || []); me.logger.info(["user filter {0}", JSON.stringify(filter)]); tableData = tableData.filter(me.matchObject.bind(null, filter)); } if (me.options.propSelector) { tableData = me.returnOnlyPropSelector(tableData); } return tableData; }, /** * @returns mapIndex when field has any index otherwise -1 */ getFieldNameIndex: function (fieldName) { var me = this, pos; pos = me.getIndexPosition(fieldName); if (pos > 0) { return fieldName.substring(pos); } return ""; }, getFieldName: function (fieldName) { var me = this, pos; pos = me.getIndexPosition(fieldName); if (pos > 0) { return fieldName.substring(0, pos); } return ""; }, getIndexPosition: function (fieldName) { if (!sol.common.ObjectUtils.isString(fieldName)) { throw Error("`fieldName must be a string, type=`" + sol.common.ObjectUtils.type(fieldName)); } return fieldName.search(/\d+$/); }, getTargetFieldName: function (mapKey, outputDefinition) { var me = this; return me.options.ignorePropertyNames ? mapKey : outputDefinition.target.prop; }, convertToArray: function (result) { return Object.keys(result).map(function (index) { result[index].$mapIndex = index; return result[index]; }); }, returnOnlyPropSelector: function (arr) { var me = this, propSelector = me.options.propSelector; return arr.map(function (data) { return data[propSelector]; }); } });