/** * Analyze a sord for spezified values. * * Each of the spezified values has to be meet. * * Each value has to define a `type` and a `key` (see {@link sol.common.SordUtils#getValue}) * * # Value definitions * * Check if a field exists * * { type: "GRP", key: "STATUS", exists: true } * * Check if a field has any value * * { type: "GRP", key: "STATUS", notEmpty: true } * * Check if a field is empty * * { type: "GRP", key: "STATUS", isEmpty: true } * * Compare field content to a reference value (with default comparator '==') * * { type: "GRP", key: "STATUS", referenceValue: "UPDATE" } * * Compare field content to be greater than a reference value (in this case: is the saved ISO date in the map before the sord edit date) * * { type: "MAP", key: "CHECK_ISO", referenceValue: { type: "SORD", key: "TStamp" }, comparator: "<" } * * Compare field content with several localized keyword list keys * * { type: "GRP", key: "CONTRACT_STATUS", localizedKwl: true, referenceValues: ["D", "S"] } * * The value analyzer has a spezial type `PARENT_MAP`. This will try to check the values from a parent elements map. * Therefore the collector has to return a prefilled context with a `parentMap` property (like e.g. the {@link sol.common_monitoring.as.collectors.ChildrenCollector ChildrenCollector} does). * If the collector does not return such a property, it will be handled as empty. * Check if the parent has a map value STATUS.4711 (key.objId) for the sord with `sord.id=4711`: * * { type: "PARENT_MAP", key: "STATUS", notEmpty: true } * * # Comparisons * If compared with a reference value, several comparators can be defined. * * Supported comparators are: * * - "==" equal (default) * - ">" greater * - ">=" greater or equal * - "<" smaller * - "<=" smaller or equal * * # Context enhancement * In addition to just check the values, they can be saved in an context object which can then be used in further processing. * E.g. the {@link sol.common_monitoring.as.executors.SimpleExecutor SimpleExecutor} can use those values in the action definitions. * * var analyzer = sol.create("sol.common_monitoring.as.analyzers.ValueAnalyzer", { * action: { type: "WORKFLOW", templateId: "{{ctx.updateWorkflow}}" }, * values: [ * { type: "MAP", key: "UPDATE_WF", notEmpty: true, toContext: "updateWorkflow" } * ] * }); * * In case of a successfull check, the corresponding value will be written to the context object, which can then be used by the following components. * * @author PZ, ELO Digital Office GmbH * @version 1.02.000 * * @eloas * @requires sol.common.StringUtils * @requires sol.common.SordUtils */ sol.define("sol.common_monitoring.as.analyzers.ValueAnalyzer", { requiredConfig: ["action", "values"], /** * @cfg {Object} action */ /** * @cfg {Object[]} values */ initialize: function (config) { var me = this; me.$super("sol.Base", "initialize", [config]); }, /** * Analyzes an object for matches of set of values. * @param {de.elo.ix.client.Sord} sord * @param {Object} ctx Context object * @return {Object[]} */ analyze: function (sord, ctx) { var me = this, results = [], allRequirementsMeet = true, i, max, valueCfg, checkFct, checkResult; me.logger.enter("analyze", { objId: sord.id, name: String(sord.name), valuesCount: me.values.length }); for (i = 0, max = me.values.length; i < max; i++) { valueCfg = me.values[i]; checkFct = me.noop; // this will the rule -> in case it has an unsupported configuration if (valueCfg.exists === true) { checkFct = me.exists; } else if (valueCfg.notEmpty === true) { checkFct = me.notEmpty; } else if (valueCfg.isEmpty === true) { checkFct = me.isEmpty; } else if (valueCfg.referenceValue || me.checkReferenceValues) { checkFct = me.checkReferenceValues; } checkResult = checkFct.call(me, sord, valueCfg, ctx); if (checkResult.success && ctx && valueCfg.toContext) { ctx[valueCfg.toContext] = checkResult.value; } allRequirementsMeet = allRequirementsMeet && checkResult.success; if (!allRequirementsMeet) { break; // skip further processing } } if (allRequirementsMeet) { results.push({ action: me.action }); } me.logger.exit("analyze", results); return results; }, /** * @private * If there is an illegal check configuration, this 'no operation' will be used to void check. * @return {Object} */ noop: function () { return { success: false }; }, /** * @private * Checks, if the spezified field exists. * @param {de.elo.ix.client.Sord} sord * @param {Object} value * @param {Object} ctx * @return {Object} */ exists: function (sord, value, ctx) { var me = this, result = { success: false }, propertyValue; propertyValue = me.getValue(sord, value, ctx); result.success = ((typeof propertyValue !== "undefined") && (propertyValue !== null)); result.value = propertyValue; return result; }, /** * @private * Checks, if the spezified field has any value. * @param {de.elo.ix.client.Sord} sord * @param {Object} value * @param {Object} ctx * @return {Object} */ notEmpty: function (sord, value, ctx) { var me = this, result = { success: false }, propertyValue; propertyValue = me.getValue(sord, value, ctx); result.success = !sol.common.StringUtils.isEmpty(propertyValue); result.value = propertyValue; return result; }, /** * @private * Checks, if the spezified field is empty. * @param {de.elo.ix.client.Sord} sord * @param {Object} value * @param {Object} ctx * @return {Object} */ isEmpty: function (sord, value, ctx) { var me = this, propertyValue, result; result = { success: false }; propertyValue = me.getValue(sord, value, ctx); result.success = sol.common.StringUtils.isEmpty(propertyValue); return result; }, /** * @private * Checks, if a specific value is set on the sord. * @param {de.elo.ix.client.Sord} sord * @param {Object} value * @param {Object} ctx * @return {Object} */ checkReferenceValues: function (sord, value, ctx) { var me = this, result = { success: false }, referenceValueDefs, i, referenceValueDef, propertyValue, referenceValue; propertyValue = me.getValue(sord, value, ctx); referenceValueDefs = value.referenceValues || [value.referenceValue]; for (i = 0; i < referenceValueDefs.length; i++) { referenceValueDef = referenceValueDefs[i]; referenceValue = me.getValue(sord, referenceValueDef, ctx); if (propertyValue && referenceValue) { result.success = me.compare(propertyValue, referenceValue, value.comparator); result.value = propertyValue; if (result.success) { break; } } } return result; }, /** * @private * Compares two values. * @param {String} value * @param {String} referenceValue * @param {String} comparator * @return {Boolean} */ compare: function (value, referenceValue, comparator) { var compareResult; switch (comparator) { case ">": compareResult = (value > referenceValue); break; case ">=": compareResult = (value >= referenceValue); break; case "<": compareResult = (value < referenceValue); break; case "<=": compareResult = (value <= referenceValue); break; default: compareResult = (value === referenceValue); break; } return compareResult; }, /** * @private * Retrieves a value dependent on a configuration. * * If the 'valueCfg' is already a constant value, it will be returned as it is. * * If the value from sord.TStamp should be loaded, this function converts it to a legal ISO date. * * @param {de.elo.ix.client.Sord} sord * @param {Object} valueCfg * @param {Object} ctx * @return {String} */ getValue: function (sord, valueCfg, ctx) { var value; if (valueCfg && valueCfg.hasOwnProperty("type") && valueCfg.hasOwnProperty("key")) { if (valueCfg.type === "PARENT_MAP" && ctx && ctx.parentMap) { value = ctx.parentMap.getValue(valueCfg.key + "." + sord.id); } else { if (valueCfg.localizedKwl) { value = (sol.common.SordUtils.getLocalizedKwlKey(sord, valueCfg) || "") + ""; } else { value = (sol.common.SordUtils.getValue(sord, valueCfg) || "") + ""; } if (valueCfg.type === "SORD" && valueCfg.key === "TStamp") { value = value.replace(/\./g, ""); } } } else { value = valueCfg; } return value; } });