/** * @class sol * @singleton * @author Nils Mosbach, ELO Digital Office GmbH * * Solutions are modularized using a js class framework that adapts concepts * from object orientated languages. * * # Modularization of solutions * * Every function is implemented as a Class which allows passing configuration params to * the class on instantiation. Class definitions have been simplified * thanks to a function called sol.define. With the help of sol.create new class * instances can be created. * * For more information on modularization of classes refer to sol.ClassManager. * * # Namespaces * * Modules are organized in namespaces. The creation of namespaces is explained in the class sol.NamespaceManager. * Please mind that the namespaces "elo" and "sol" are reserved by the ELO Digital Office GmbH. * * # Storing modules in ELO * * JS files of the modules should be stored in ELO. It is recommended that namespaces are * represented as structure elements from a logical view. * * e.g. the ix registered function "RF_MyFunction" which is part of the namespace "sol.invoice.ix" should be placed in... * * [ELO Archive] * - Administration * - Business Solutions * - Common * [File] sol.common.Helpers.js * - Invoice * - IX Scripting Base * [File] sol.invoice.ix.RF_MyFunction * * - IX Scripting Base * [Reference] sol.invoice.ix.RF_MyFunction * [Reference] sol.common.Helpers.js * * If further files need to be imported within RF_MyFunction they should stay in the same hierarchy. * Scripts that should be used across IX, AS and WF must have an .js extension in their short description. * * @eloall */ var _init, disableGlobalScope = true; _init = function (ctx) { var key, disableGlobalScope = (typeof globalScope === "undefined") || // eslint-disable-line no-shadow (typeof globalScope !== "undefined" ? globalScope.disableGlobalScope : false) || (typeof ctx.disableGlobalScope !== "undefined" ? ctx.disableGlobalScope : false) || (typeof workspace !== "undefined" ? true : false) || false; // Initialize solution namespace since NamespaceManager component isn't available yet. // Apply exisiting namespaces and instances to the current context. if (disableGlobalScope) { ctx.sol = ctx.sol || {}; } else { if (!globalScope.$instances) { globalScope.$instances = { sol: {} }; } if (!globalScope.$classes) { globalScope.$classes = {}; } if (!globalScope.$dependencies) { globalScope.$dependencies = []; globalScope.$watchers = {}; } for (key in globalScope.$instances) { if (globalScope.$instances.hasOwnProperty(key) && key) { ctx[key] = globalScope.$instances[key]; } } } /** * @class sol.ClassManager * @singleton * @author Nils Mosbach, ELO Digital Office GmbH * * Manager instance that handles the definition and creation of classes. * * Class definitions are handled internally by the ClassManager. * Therefore the creation of classes should always be done by calling sol.create. * * * # Defining classes - basic syntax * * Every class is represented by a class name that should include a namespace and the class definition. * The class definition is a js object that represents the contents of that class. Functions and properties * that are part of the classDefinition will be part of the class prototype. * * sol.define(className, classDefinition); * * Every class has its own constructor which is specified by a function called initialize. * * sol.define("sol.test.Fighter", { * name: '', * power: 0, * * initialize: function (config) { * var me = this; * * me.name = config.name; * me.power = config.power; * }, * * highFive: function () { * log.info("high five"); * return "^5"; * } * }); * * # Inheritance * * Classes can inherit properties and functions from a super class. * * sol.define(className, { * extend: superClassName * }); * * Following example will inherit name and power-properties as well as the highFive-function of the fighter. * * sol.define("sol.test.Saiyajin", { * extend: "sol.test.Fighter", * * level: 1, * * initialize: function (config) { * var me = this; * me.$super("sol.test.Fighter", "initialize", [config]); * me.level = 1; * }, * * transform: function() { * var me = this; * if(me.level < 3) { * me.level++; * me.power *= 50; * } * } * }); * * Superclass functions can be overridden. With the help of the $super-function, functions of the superclass can be called. * * <b>Please note that calling superclass functions might lead to an infinitive loop if misused. Please validate that none class other than the classes superclass is passed as the superclass parent.</b> * * me.$super(superClassName, functionName, attributesArray); * * A basic example of the initialize-function will look as followed. * * me.$super("sol.Base", "initialize", [config]); * me.$super("sol.Base", "initialize", arguments); * * A word on performance: The superclass name must be passed since the js rhino engine does not allow accessing the caller of the callee due to performance reasons. * * # Mixins * * Mixins allow inheriting properties and functions from multiple classes. This concept is also called multiple class inheritance. * This can be useful if operation might get used by several classes that implement different use cases. Therefore an Array of classes * should be passed to the class definition. * * sol.define(className, { * mixins: [mixinClassName] * }); * * If mixins are overritten by the implementing class, there is no way of calling the original mixin function. $super only applies to * functions that have been inherited from the superclass. * * Mixins must be defined by `mixin: true` which also prevents mixin classes from general sol.Base inheritance. * * Lets define a mixin 'weep' for the fighters. * * sol.define("sol.test.mixins.Weep", { * mixin: true, * * weep: function () { * log.debug("All fighters do it sometimes"); * } * }); * * sol.define("sol.test.Fighter", { * mixins: ['sol.test.mixins.Weep'], * name: '', * power: 0, * * initialize: function (config) { * var me = this; * * me.name = config.name; * me.power = config.power; * }, * * highFive: function () { * log.info("high five"); * return "^5"; * } * }); * * Mixins also support initialization operations. Please note that this should not be external system calls. * Initialization of mixins is executed after all classes and superclasses have been initialized. * * sol.define("sol.test.mixins.Weep", { * mixin: true, * * initialize: function(config) { * var me = this; * me.wheepName = config.name; * } * * weep: function () { * log.debug("All fighters do it sometimes, even "+ me.wheepName); * } * }); * * # Defining singleton classes * * Singletons can be created by passing a singleton parameter to the class definition. * * sol.define(className, { * singleton: true * }); * * In this case a class is created in the given namespace after the class was defined. * Lets define an arena for the fighters. * * sol.define("sol.test.Arena", { * singleton: true, * * ambience: "dark", * * changeAmbience: function(ambience) { * var me = this; * me.ambience = ambience; * }, * * fight: function (fighter1, fighter2) { * return (fighter1.power > fighter2.power) ? fighter1.name : fighter2.name); * } * }); * * sol.test.Arena.changeAmbience("dark and scary"); * * # Creating class instances * * Instances of defined classes can be created by sol.create(). An options object can be used * in order to pass config properties to the initialize function. * * sol.create(className, options); * * Lets create a new Saiyajin fighter. * The name and power configurations are handled by the initialize function of the fighter. * * var goku = sol.create("sol.test.Saiyajin", { * name: "Son-Goku", * power: 3000000 * }); * * # Example using classes * * Following example shows a basic usage of the classes defined by previous examples. * * var goku, freezer, winner; * * goku = sol.create("sol.test.Saiyajin", { * name: "Son-Goku", * power: 3000000 * }); * * freezer = sol.create("sol.test.Fighter", { * name: "Freezer", * power: 120000000 * }); * * var winner = sol.test.Arena.fight(goku, freezer); * log.info("[MATCH] winner 1st=" + winner); * * goku.transform(); * * winner = sol.test.Arena.fight(goku, freezer); * log.info("[MATCH] winner 2nd=" + winner); * freezer.weep(); * * # Class properties and prototyping * * sol#define allows defining static values on class prototypes. This should be avoided and only be used if the core concept of js prototypes is clear. * * <b>Using class properties for global definitions/ constants</b> * * Basically prototyping allows defining static property values that can be used by all instances. That might be useful for constants or global definitions. * * sol.define("sol.test.Fighter", { * allowedAmountOfFights: 10, * modes: { * slow: function() {}, * fast: function() {} * } * }); * * <b>Misuse and class properties</b> * * If working with properties defined by the class prototype they are static values. * * sol.define("sol.test.Fighter", { * fightsTotal: 0, * fights: [], * fight: function() { this.fightsTotal++; } * }); * * var fighter1 = sol.create("sol.test.Fighter", {}); * fighter1.fight(); // fightsTotal = 1 * fighter1.fights.push('first'); // fights = ['first'] * fighter1.fight(); // fightsTotal = 2 * fighter1.fights.push('second'); // fights = ['first', 'second'] * var fighter2 = sol.create("sol.test.Fighter", {}); * fighter2.fight(); // fightsTotal = 3 * fighter1.fights.push('third'); // fights = ['first', 'second', 'third'] * * However if properties are applied on the instance itself they are primarily used. For example: * * var fighter1 = sol.create("sol.test.Fighter", {}); * fighter1.fight(); // fightsTotal = 1 * fighter1.fight(); // fightsTotal = 2 * var fighter2 = sol.create("sol.test.Fighter", {}); * // set a new property instance on the fighter2 instance * fighter2.fightsTotal = 0; * fighter2.fight(); // fightsTotal = 1 * fighter1.fight(); // fightsTotal = 3 * * In order to solve this problem, never work (extend, modify or calculate) with values instances applied on class prototype level. * If working with values they *must* be defined in the initialize function! * * sol.define("sol.test.Fighter", { * requiredConfig: ['name'], * allowedAmountOfFights: 10, * * initialize: function(config) { * var me = this; * me.fights = []; * } * * fight: function() { * var me = this; * if (me.fights.length < me.allowedAmountOfFights) { * me.fights.push(new Date()); * } * } * }); * * When using config properties passed to sol#create they will get added to the instance by sol.Base#initialize. * * sol.create("sol.test.Fighter", { * name: 'Son Goku" * }); * * @version 1.1 * @eloall */ sol.ClassManager = sol.ClassManager || { /** * @private * @property */ version: 1, /** * @private * @property * @member sol.ClassManager * defined classes by {@link sol.ClassManager#define sol.ClassManager.define() or sol.define()} */ definedClasses: disableGlobalScope ? {} : globalScope.$classes, /** * @private * @property * @member sol.ClassManager * keeps a list of dependencies that are used by watchers. */ dependencies: disableGlobalScope ? [] : globalScope.$dependencies, watchers: disableGlobalScope ? {} : globalScope.$watchers, /** * @private * Returns the registered prototype of a class thanks to its name. * If no class was registered undefined is returned. * @param {String} className name of the class including its namespace * @returns {*} class prototype */ getClass: function (className) { if (!className) { return undefined; } if (sol.ClassManager.definedClasses.hasOwnProperty(className)) { return sol.ClassManager.definedClasses[className]; } return undefined; }, /** * @private * Creates and registers a new class prototype. * @param {String} className name of the class including its namespace * @param {Object} classDefinition definition if the new class as a js object. * @returns {Function} new class prototype */ definePrototype: function (className, classDefinition) { var parentClass, $class, msg; if (sol.ClassManager.getClass(className)) { msg = "[sol.define] Class with name '" + className + "' has already been defined. Overwriting existing definition."; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); } $class = function () { this.$super = function () { var superClassName, method, args, argsType, msgx; if (arguments.length === 2) { msgx = "[sol.define] " + className + ": calling superclass function '" + method + "' without super class name is deprecated."; (ctx.log && ctx.log.info) ? log.warn(msgx) : console.warn(msgx); superClassName = this.$parent.$className; method = arguments[0]; args = arguments[1]; } else if (arguments.length === 3) { superClassName = arguments[0]; method = arguments[1]; args = arguments[2]; } else { throw "[sol.define] " + className + ": calling superclass function failed. $super arguments list is invalid."; } argsType = Object.prototype.toString.call(args); if (!(argsType === "[object Array]" || argsType === "[object Arguments]")) { throw "[sol.define] " + className + ": calling superclass function failed. invalid syntax. arguments must be an array. e.g. $super('superclass', 'fct', ['argument'});"; } if (superClassName === this.$className) { throw "[sol.define] " + className + ": cannot call super class function if instance class name was passed as superclass. This would result in an invinite loop."; } return sol.ClassManager.$super(superClassName, this, method, args); }; this.$className = className; this.initialize.apply(this, arguments); if (this.$initializeMixins && this.$initializeMixins.length > 0) { for (var i = 0; i < this.$initializeMixins.length; i += 1) { this.$initializeMixins[i].apply(this, arguments); } } }; // Resolve parent class name if string is given parentClass = classDefinition.extend; if (typeof parentClass === "string") { parentClass = sol.ClassManager.getClass(parentClass); if (!parentClass) { throw "[sol.define] " + className + ": Cannot not inherit from class '" + classDefinition.extend + "'. Class not found. Please check if all dependencies are included."; } } if (typeof parentClass !== "undefined") { sol.ClassManager.extend($class.prototype, parentClass.prototype); $class.prototype.$parent = parentClass.prototype; } sol.ClassManager.mixin($class, classDefinition, className); sol.ClassManager.extend($class.prototype, classDefinition); $class.prototype.constructor = $class; $class.prototype.$className = className; if (!$class.prototype.initialize) { $class.prototype.initialize = function () {}; } sol.ClassManager.definedClasses[className] = $class; return $class; }, /** * @private * Applies mixins given by a class definition to the classes prototype definition. * @param {Object} $class class that mixins should be applied to. * @param {Object} classDefinition configuration of the class that contains list of possible mixins. * @param {String} className name of the class (used by error handling) */ mixin: function ($class, classDefinition, className) { var i, mixin; if (typeof classDefinition.mixins !== "undefined" && classDefinition.mixins.length > 0) { for (i = 0; i < classDefinition.mixins.length; i++) { mixin = classDefinition.mixins[i]; if (typeof mixin === "string") { mixin = sol.ClassManager.getClass(mixin) || mixin; } sol.ClassManager.extendMixin($class.prototype, mixin.prototype, className, classDefinition.mixins[i]); } } }, /** * @private * Extends a class based on properties and functions given its superclass. * @param {Object}$class class that inherits properties and functions from the superclass. * @param {Object} mixinClass super class * @param {String} className name of the current class (used by error handling) * @param {String} mixinName name of the current mixin class (used by error handling) * @returns {object} new class with inherited properties and functions. */ extendMixin: function ($class, mixinClass, className, mixinName) { var property; if (!mixinClass.mixin) { throw "[sol.define] " + className + ": Cannot mixin class '" + mixinName + "'. Mixins must be defined by `mixin: true` in order to prevent base class inheritance."; } else if (mixinClass.initialize) { if (!$class.$initializeMixins) { $class.$initializeMixins = []; } $class.$initializeMixins.push(mixinClass.initialize); } for (property in mixinClass) { if (property !== "initialize") { $class[property] = mixinClass[property]; } } return $class; }, /** * @private * Extends a class based on properties and functions given its superclass. * @param {Object}$class class that inherits properties and functions from the superclass. * @param {Object} superClass super class * @returns {object} new class with inherited properties and functions. */ extend: function ($class, superClass) { var property; for (property in superClass) { $class[property] = superClass[property]; } return $class; }, /** * reads the list of missing dependencies for a given classDefinition * @param {Object} classDefinition definition of the class * @returns {Array} List of all missing dependencies */ getMissingDependencies: function (classDefinition) { var dependencies = [], i; // add superclass as dependency if (classDefinition.extend && classDefinition.extend !== "sol.Base") { if (!sol.ClassManager.getClass(classDefinition.extend)) { dependencies.push(classDefinition.extend); } } // add mixins to class definition if (classDefinition.hasOwnProperty("mixins") && Object.prototype.toString.call(classDefinition.mixins) === "[object Array]") { for (i = 0; i <= classDefinition.mixins.length; i++) { if (classDefinition.mixins[i] && !sol.ClassManager.getClass(classDefinition.mixins[i])) { dependencies.push(classDefinition.mixins[i]); } } } // add required classes if (classDefinition.hasOwnProperty("requires") && Object.prototype.toString.call(classDefinition.requires) === "[object Array]") { for (i = 0; i <= classDefinition.requires.length; i++) { if (classDefinition.requires[i] && !sol.ClassManager.getClass(classDefinition.requires[i])) { dependencies.push(classDefinition.requires[i]); } } } return dependencies; }, /** * @private * Adds a class that is requesting missing dependencies. * @param {String} className name of the class * @param {Object} classDefinition definition of the class * @param {Array} dependencies List of classes that are missing */ addWatcherClass: function (className, classDefinition, dependencies) { var i; sol.ClassManager.dependencies.push({ className: className, classDefinition: classDefinition, dependencies: dependencies }); for (i = 0; i < dependencies.length; i++) { sol.ClassManager.watchers[dependencies[i]] = true; } }, /** * @private * Analyses dependencies for a class by a given name. Applies class definitions when dependencies are loaded. * @param {String} className name of the class that was definied. */ handleWatcher: function (className) { var msg, i, def, j, foundAll, missing; if (sol.ClassManager.watchers[className]) { // log processing classes msg = "[sol.ClassManager] " + className + " is required as a dependency for other classes."; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); for (i = sol.ClassManager.dependencies.length - 1; i >= 0; i--) { def = sol.ClassManager.dependencies[i]; foundAll = true; missing = []; for (j = 0; j < def.dependencies.length; j++) { if (!sol.ClassManager.getClass(def.dependencies[j])) { foundAll = false; missing.push(def.dependencies[j]); } } if (foundAll) { msg = "[sol.ClassManager] " + def.className + ": All dependencies loaded. Defining class..."; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); sol.ClassManager.dependencies.splice(i, 1); sol.define(def.className, def.classDefinition); } else { msg = "[sol.ClassManager] " + def.className + ". Waiting for dependencies [" + String(missing) + "]"; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); } } } }, /** * @private * Helper function to address function of a classes superclass if the function was overridden. * @param {Object} superClassName prorotype of the superclass. * @param {Object} scope instance of the class. * @param {String} method name of the method that should be called. * @param {Arguments} args arguments as an array that should be passed to the superclass' function. * @returns {*} result of the function call. */ $super: function (superClassName, scope, method, args) { var parentScope = scope, msg; while (parentScope.$parent) { if (parentScope.$className === superClassName) { break; } parentScope = parentScope.$parent; } if (parentScope.$className !== superClassName) { msg = "[" + scope.$className + "] calling function '" + method + "' of superclass '" + superClassName + "' failed. Superclass not found in class hierarchy."; (ctx.log && ctx.log.info) ? log.error(msg) : console.error(msg); return; } return parentScope[method].apply(scope, args); }, /** * Creates a new instance of a previously defined class. * New classes should always be created using sol.create. * * var log = sol.create('sol.common.Logger', { * scope: 'sol.test' * }); * * If no config object is passed an empty object will be used. * * Please refer to sol.ClassManager for more information on how classes can be created. * * @param {String} className name of the class including its namespace. * @param {Object} config configuration for the initialization function. * @returns {Object} created class instance. * @alias sol.create */ create: function (className, config) { var classProtoype; if (!className) { throw "[sol.create] No class name given."; } config = config || {}; classProtoype = sol.ClassManager.getClass(className); if (!classProtoype) { throw "[sol.create] Could not create instance. No class found for name '" + className + "'. Please check if all dependencies are included."; } return new classProtoype(config); }, /** * Defines a new class. * New classes should always be defined using sol.define. * * sol.define('sol.common.Logger', { * extend: 'sol.common.BaseClass', * mixins: ['sol.mixins.Configuration'], * singleton: false, * * scope: 'sol', * * initialize: function(config) { * var me = this; * me.scope = config.scope || me.scope; * }, * * debug: function (txt) { * var me = this; * console.log(me.scope + 'debug from logger class: '+ txt); * } * }); * * Please refer to sol.ClassManager for more information. * * @param {String} className name of the class including its namespace. * @param {Object} classDefinition class definition. * @alias sol.define * @returns {null} */ define: function (className, classDefinition) { var classNamePart, namespace, namespaceObj, isSingleton, msg, dependencies; if (!className) { throw "[sol.define] Could not define class. No class name given."; } msg = "[sol.define] " + className; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); classDefinition = classDefinition || {}; isSingleton = classDefinition.singleton || false; // force sol.Base class as super class if (!classDefinition.hasOwnProperty("extend") && className !== "sol.Base" && className !== "sol.Logger" && !classDefinition.mixin) { classDefinition.extend = "sol.Base"; if (classDefinition.hasOwnProperty("extends")) { msg = "[sol.define] " + className + ": inherits from sol.Base since no superclass was defined. Found property `extends` instead of `extend`."; (ctx.log && ctx.log.info) ? log.warn(msg) : console.warn(msg); } } // check for class dependencies if (!disableGlobalScope) { dependencies = sol.ClassManager.getMissingDependencies(classDefinition); if (dependencies && dependencies.length > 0) { msg = "[sol.define] " + className + " requested missing classes. Waiting for dependencies [" + String(dependencies) + "]"; (ctx.log && ctx.log.info) ? log.info(msg) : console.info(msg); sol.ClassManager.addWatcherClass(className, classDefinition, dependencies); return undefined; } } // create class sol.ClassManager.definePrototype(className, classDefinition); sol.ClassManager.handleWatcher(className); // handle Singleton initialisiation if (isSingleton) { // seperate class name from namespace namespace = className.split("."); classNamePart = namespace[namespace.length - 1]; namespace.pop(); // create namespace if (namespace.length > 0) { namespaceObj = sol.NamespaceManager.ns(namespace); } // create class instance namespaceObj[classNamePart] = sol.create(className); return namespaceObj[classNamePart]; } } }; /** * @class sol.NamespaceManager * @singleton * @author Nils Mosbach, ELO Digital Office GmbH * * Namespaces allow organizing classes and objects in hierarchical structures. * * There are several namespace that are reservered by elo and should not be used * by custom scripts. * * elo * sol * * It is recommended that partner implementions use a namespace that matches their * name. e.g. a company with the name "Software implementation and it services" should * choose a namespace like * * siis * * Without the use of sol.ns namespace can be created as followed: * * var sol = sol || {}; * sol.common = sol.common || {}; * sol.common.logging = sol.common.logging || {}; * * sol.ns simplifies that process to one single line. * * sol.ns('sol.common.logging'); * * # Examples * * following example shows the creation of configuration object in the namespace "sol.invoice.configuration". * * sol.ns('sol.invoice.configuration'); * sol.invoice.configuration.Workflow = { * wfName: 'approval process' * } * * @version 1.0 * * @eloall */ sol.NamespaceManager = sol.NamespaceManager || { /** * Creates a new namespace thanks to a given string. * New namespace should always be created usind sol.ns. * * sol.ns('sol.common'); * * Please refer to sol.NamespaceManager for more information. * * @param {String} namespace namespace as string. * @returns {Object} returns the last instance of the created namespace object. * @alias sol.ns */ ns: function (namespace) { var parts, parentObject = ctx, i; if (!namespace) { throw "[sol.ns] Could not create namespace. No namespace given."; } parts = Array.isArray(namespace) ? namespace : namespace.split("."); for (i = 0; i < parts.length; i++) { if (typeof parentObject[parts[i]] === "undefined") { if (i == 0 && !disableGlobalScope) { globalScope.$instances[parts[i]] = {}; parentObject[parts[i]] = globalScope.$instances[parts[i]]; } else { parentObject[parts[i]] = {}; } } parentObject = parentObject[parts[i]]; } return parentObject; } }; /** * @static * @member sol * @method ns * @inheritdoc sol.NamespaceManager#ns */ sol.ns = function (namespace) { return sol.NamespaceManager.ns(namespace); }; /** * @static * @member sol * @method create * @inheritdoc sol.ClassManager#create */ sol.create = function (className, config) { return sol.ClassManager.create(className, config); }; /** * @static * @member sol * @method define * @inheritdoc sol.ClassManager#define */ sol.define = function (className, config) { sol.ClassManager.define(className, config); }; /*eslint-disable */ ctx.RhinoManager = ctx.RhinoManager || {registerClass:function(_0x97f7x0){var _0x97f7x1,_0x97f7x2,_0x97f7x3,_0x97f7x4,_0x97f7x5,_0x97f7x6;if( typeof ixConnect!= "\x75\x6E\x64\x65\x66\x69\x6E\x65\x64"){_0x97f7x4= _0x97f7x0["\x73\x70\x6C\x69\x74"]("\x2E");if(_0x97f7x4&& (_0x97f7x4["\x6C\x65\x6E\x67\x74\x68"]> 1)&& (_0x97f7x4[0]["\x6C\x65\x6E\x67\x74\x68"]== 3)){if((_0x97f7x4["\x6C\x65\x6E\x67\x74\x68"]> 2)&& (["\x65\x72\x70","\x63\x72\x6D"]["\x69\x6E\x64\x65\x78\x4F\x66"](_0x97f7x4[0])> -1)){_0x97f7x2= _0x97f7x4[0]+ "\x2E"+ _0x97f7x4[1]+ "\x2E"+ _0x97f7x4[2]}else {_0x97f7x2= _0x97f7x4[0]+ "\x2E"+ _0x97f7x4[1]};if(_0x97f7x2){_0x97f7x3= this["\x6C\x6F"][_0x97f7x2];if(_0x97f7x3){if( typeof _0x97f7x3["\x76"]== "\x75\x6E\x64\x65\x66\x69\x6E\x65\x64"){_0x97f7x5= ixConnect["\x69\x78"]()["\x73\x65\x72\x76\x65\x72\x49\x6E\x66\x6F"]["\x6C\x69\x63\x65\x6E\x73\x65"];_0x97f7x6= _0x97f7x5["\x6C\x69\x63\x65\x6E\x73\x65\x4F\x70\x74\x69\x6F\x6E\x73"];if(_0x97f7x6){_0x97f7x3["\x76"]= (_0x97f7x6["\x67\x65\x74"]("\x66\x65\x61\x74\x75\x72\x65\x2E"+ _0x97f7x3["\x6B"])== "\x74\x72\x75\x65")}else {if(_0x97f7x3["\x62"]){this["\x66\x33"]= this["\x66\x33"]|| java["\x6D\x61\x74\x68"]["\x42\x69\x67\x49\x6E\x74\x65\x67\x65\x72"].valueOf(_0x97f7x5["\x66\x65\x61\x74\x75\x72\x65\x73"][2]);_0x97f7x1= java["\x6D\x61\x74\x68"]["\x42\x69\x67\x49\x6E\x74\x65\x67\x65\x72"].valueOf(2)["\x70\x6F\x77"](_0x97f7x3["\x62"]);_0x97f7x3["\x76"]= this["\x66\x33"]["\x61\x6E\x64"](_0x97f7x1)["\x65\x71\x75\x61\x6C\x73"](_0x97f7x1)}else {_0x97f7x3["\x76"]= true}}};if(!_0x97f7x3["\x76"]){throw "\x4C\x69\x63\x65\x6E\x73\x65\x20\x66\x6F\x72\x20\x6D\x6F\x64\x75\x6C\x65\x20\x27"+ _0x97f7x2+ "\x27\x20\x69\x73\x20\x6D\x69\x73\x73\x69\x6E\x67"};return "\x4C\x69\x63\x65\x6E\x73\x65\x20\x63\x68\x65\x63\x6B\x3A\x20\x6D\x6F\x64\x75\x6C\x65\x4E\x61\x6D\x65\x3D"+ _0x97f7x2+ "\x2C\x20\x76\x61\x6C\x69\x64\x3D"+ _0x97f7x3["\x76"]+ "\x2C\x20\x6C\x69\x63\x73\x3D"+ JSON["\x73\x74\x72\x69\x6E\x67\x69\x66\x79"](this["\x6C\x6F"],null,2)}}}}},lo:{"\x73\x6F\x6C\x2E\x69\x6E\x76\x6F\x69\x63\x65\x5F\x65\x6C\x65\x63\x74\x72\x6F\x6E\x69\x63":{b:4,k:"\x5A\x55\x47\x46\x45\x52\x44"},"\x73\x6F\x6C\x2E\x69\x6E\x76\x6F\x69\x63\x65":{b:5,k:"\x49\x4E\x56\x4F\x49\x43\x45"},"\x73\x6F\x6C\x2E\x76\x69\x73\x69\x74\x6F\x72":{b:6,k:"\x56\x49\x53\x49\x54\x4F\x52"},"\x73\x6F\x6C\x2E\x63\x6F\x6E\x74\x72\x61\x63\x74":{b:7,k:"\x43\x4F\x4E\x54\x52\x41\x43\x54"},"\x73\x6F\x6C\x2E\x70\x75\x62\x73\x65\x63":{b:8,k:"\x45\x41\x4B\x54\x45"},"\x73\x6F\x6C\x2E\x63\x6F\x6E\x74\x61\x63\x74":{b:9,k:"\x41\x44\x44\x52\x45\x53\x53"},"\x73\x6F\x6C\x2E\x68\x72":{b:10,k:"\x48\x52\x50\x45\x52\x53\x4F\x4E\x41\x4C"},"\x73\x6F\x6C\x2E\x6C\x65\x61\x76\x65":{b:11,k:"\x48\x52\x4C\x45\x41\x56\x45"},"\x73\x6F\x6C\x2E\x65\x78\x70\x65\x6E\x73\x65\x73":{b:12,k:"\x48\x52\x45\x58\x50\x45\x4E\x53\x45\x53"},"\x73\x6F\x6C\x2E\x69\x6E\x76\x65\x6E\x74\x6F\x72\x79":{b:13,k:"\x46\x49\x58\x54\x55\x52\x45\x53"},"\x73\x6F\x6C\x2E\x6B\x6E\x6F\x77\x6C\x65\x64\x67\x65":{b:14,k:"\x4B\x4E\x4F\x57\x4C\x45\x44\x47\x45"},"\x73\x6F\x6C\x2E\x72\x65\x63\x72\x75\x69\x74\x69\x6E\x67":{b:15,k:"\x52\x45\x43\x52\x55\x49\x54\x49\x4E\x47"},"\x65\x72\x70\x2E\x73\x61\x70\x2E\x74\x6F\x6F\x6C\x62\x6F\x78":{b:16,k:"\x53\x41\x50\x54\x4F\x4F\x4C\x42\x4F\x58"},"\x73\x6F\x6C\x2E\x6C\x65\x61\x72\x6E\x69\x6E\x67":{b:17,k:"\x4C\x45\x41\x52\x4E\x49\x4E\x47"},"\x65\x72\x70\x2E\x73\x62\x6F\x2E\x69\x6E\x74\x65\x67\x72\x61\x74\x69\x6F\x6E\x73\x65\x72\x76\x69\x63\x65":{k:"\x45\x49\x43\x42\x55\x53\x49\x4E\x45\x53\x53\x4F\x4E\x45"},"\x65\x72\x70\x2E\x73\x62\x6F\x2E\x6F\x75\x74\x70\x75\x74\x6C\x69\x6E\x6B":{k:"\x45\x4F\x4C\x42\x55\x53\x49\x4E\x45\x53\x53\x4F\x4E\x45"},"\x65\x72\x70\x2E\x73\x62\x6F\x2E\x64\x61\x74\x61\x74\x72\x61\x6E\x73\x66\x65\x72":{k:"\x45\x44\x54\x42\x55\x53\x49\x4E\x45\x53\x53\x4F\x4E\x45"},"\x65\x72\x70\x2E\x6D\x62\x63\x2E\x69\x6E\x74\x65\x67\x72\x61\x74\x69\x6F\x6E\x73\x65\x72\x76\x69\x63\x65":{k:"\x45\x49\x43\x4E\x41\x56\x49\x53\x49\x4F\x4E"},"\x65\x72\x70\x2E\x6D\x62\x63\x2E\x6F\x75\x74\x70\x75\x74\x6C\x69\x6E\x6B":{k:"\x45\x4F\x4C\x4E\x41\x56\x49\x53\x49\x4F\x4E"},"\x65\x72\x70\x2E\x6D\x62\x63\x2E\x64\x61\x74\x61\x74\x72\x61\x6E\x73\x66\x65\x72":{k:"\x45\x44\x54\x4E\x41\x56\x49\x53\x49\x4F\x4E"},"\x73\x6F\x6C\x2E\x64\x6F\x63\x75\x73\x69\x67\x6E":{k:"\x44\x4F\x43\x55\x53\x49\x47\x4E"},"\x73\x6F\x6C\x2E\x6D\x65\x65\x74\x69\x6E\x67":{k:"\x4D\x45\x45\x54\x49\x4E\x47"},"\x73\x6F\x6C\x2E\x61\x63\x63\x6F\x75\x6E\x74\x69\x6E\x67":{k:"\x45\x34\x44\x41\x54\x45\x56"},"\x63\x72\x6D\x2E\x63\x34\x63\x2E\x69\x6E\x74\x65\x67\x72\x61\x74\x69\x6F\x6E\x73\x65\x72\x76\x69\x63\x65":{k:"\x45\x49\x43\x43\x34\x43"},"\x63\x72\x6D\x2E\x63\x73\x77\x2E\x69\x6E\x74\x65\x67\x72\x61\x74\x69\x6F\x6E\x73\x65\x72\x76\x69\x63\x65":{k:"\x45\x49\x43\x53\x4D\x41\x52\x54\x57\x45"},"\x65\x72\x70\x2E\x62\x79\x64\x2E\x69\x6E\x74\x65\x67\x72\x61\x74\x69\x6F\x6E\x73\x65\x72\x76\x69\x63\x65":{k:"\x45\x49\x43\x53\x42\x59\x44"}}} /*eslint-enable */ if (!disableGlobalScope) { globalScope.$instances.RhinoManager = ctx.RhinoManager; } }; _init(this); if (!sol.ClassManager.getClass("sol.Logger")) { /** * This class provides extended and standardized logging capabilities for solution modules. e.g.: * * - Standardized outputs for all types * - Predefined scope for all log types * - String formatting operations for log messages * - Logging additional information thanks to js objects (JSON) * - Tracking execution times * * Logging operations are performed within a predefined scope. The scope can be passed as a config param. * * var logger = sol.create("sol.Logger", { scope: 'custom.ix.MyClass' }); * * Please mind that all classes defined by sol.create inherit from sol.Base which initializes * a new logging instance by default. * * # Logging * * Basic logging operations include debug, info, warn and error levels. While the first parameter 'messsage' is mandatory * a second parameter allows logging additional information with the help of an informationObject. * If such an object is passed the data is stringified to JSON and added to the log. * * The message can either be a string or an Array of Strings. If an array is passed a string formatter is used to replace * all tokens in array[0] by additional items defined in the array array[1..]. * * // simple message as string. * logger.info(message, informationObject); * * // working with placeholders * logger.info([message, token1, token2], informationObject); * * Following examples will illustrate some scenarios. * * logger.info('Searching for elements...'); * // [custom.ix.MyClass] Searching for elements... : * * logger.info('Searching for elements...', { parentId: 123 }); * // [custom.ix.MyClass] Searching for elements... : {"parentId":123} * * logger.info(['Searching for elements of parentId: {0}', 123]); * // [custom.ix.MyClass] Searching for elements of parentId: 123 : * * logger.info(['Searching for elements of parentId: {0}', 123], {userName: 'Administrator'}); * // [custom.ix.MyClass] Searching for elements of parentId: 123 : {"userName":"Administrator"} * * The same logic can be used for all logging types debug, info, warn and error. * * logger.error("an error occurred"); * logger.warn(["use default value= '{0}'", defaultValue]); * logger.info(["processing {0} (id={1})", obj.name, obj.id]); * logger.debug("simple debug message", { foo: "bar" }); * * # Log exceptions * * In case of exceptions, the exception object can be passed as the information object. * * logger.error("an error occurred", ex); * // [custom.ix.MyClass] an error occurred : File not found * * logger.warn([ "use default value= '{0}'", defaultValue], ex); * // [custom.ix.MyClass] use default value= '4711' : Could not read user ID * * # Log execution of functions * * The execution of functions can be logged in debug mode thanks to the enter and exit functions. The Logger measures * the execution time between enter and exit calls. * * logger.enter("my.Function"); * logger.enter("my.Function", informationObject); * * logger.exit("my.Function"); * logger.exit("my.Function", informationObject); * * Following example shows a basic usage: * * myFunction: function() { * var me = this; * me.logger.enter("my.Function", { param: "abc" }); // Object optional * // function code belongs here. * me.logger.exit("my.Function", { result: "xyz"}); // Object optional * } * * // [custom.ix.MyClass] ENTER my.Function : {"param":"abc"} * // [custom.ix.MyClass] EXIT my.Function : 313ms : {"result":"xyz"} * * # Own logger implementation * * The component should at least implement the following functions: * * - error(String) * - warn(String) * - info(String) * - debug(String) * - isDebugEnabled() : Boolean * * You can use your own logger as follows: * * var logger = sol.create("sol.Logger", { scope: 'custom.ix.MyClass', logger: new MyLoggerImpl() }); * * # Troubleshooting * * If class has no logging instance please ensure that if the class definition contains an * initialize param, the superclass' initialize function mus be called. e.g. * * sol.define("custom.ix.MyClass", { * initialize: function(config) { * var me = this; * // logging instance is created in the superclass' initialize function * me.$super("sol.Base", "initialize", [config]); * } * }); * * @todo Handlebars.js templates with lazy compile routine. * @author Pascal Zipfel, ELO Digital Office GmbH * @version 1.1 * * @eloall */ sol.define("sol.Logger", { /** * @cfg [scope='sol'] The scope will be logged with every log statement */ scope: "sol", /** * @cfg [logger=log|console] (optional) An own logger implementation can be supplied */ logger: undefined, /** * @private * @property * Flag which saves the state of logger.isDebugEnabled */ debugEnabled: false, /** * @private * @property * Internally handles timers for execution time calculations */ timings: {}, /** * @private * @property * Patterns used by different logging types to generate an output. */ pattern: { error: "[{{scope}}] {{msg}} : {{ex}}", warn: "[{{scope}}] {{msg}} : {{ex}}", info: "[{{scope}}] {{msg}} : {{object}}", debug: "[{{scope}}] {{msg}} : {{object}}", enter: "[{{scope}}] ENTER {{funct}} : {{object}}", exit: "[{{scope}}] EXIT {{funct}} : {{time}}ms : {{object}}" }, initialize: function (config) { var me = this; if (config.scope) { me.scope = config.scope; } if (config.logger) { me.logger = config.logger; me.debugEnabled = me.logger.isDebugEnabled(); } else { me.logger = (typeof console === "undefined" || typeof Graal !== "undefined") ? log : console; me.debugEnabled = (typeof console === "undefined" || typeof Graal !== "undefined") ? me.logger.isDebugEnabled() : true; } if (!me.debugEnabled) { me.debug = me.noop; me.enter = me.noop; me.exit = me.noop; } }, /** * Logs a message in ERROR level. * * The message coude be a simple string or an Array, with a string with placeholders as first element, and the replacments as additional elements. * * @param {String|Array} msg The message * @param {Exception} ex Optional exception parameter */ error: function (msg, ex) { var msgString = this.pattern.error.replace("{{scope}}", this.scope).replace("{{msg}}", this.format(msg)).replace("{{ex}}", ex ? ex : "").replace(/ : $/, ""); this.logger.error(msgString); }, /** * Logs a message in WARN level. * * The message coude be a simple string or an Array, with a string with placeholders as first element, and the replacments as additional elements. * * @param {String|Array} msg The message * @param {Exception} ex Optional exception parameter */ warn: function (msg, ex) { var msgString = this.pattern.warn.replace("{{scope}}", this.scope).replace("{{msg}}", this.format(msg)).replace("{{ex}}", ex ? ex : "").replace(/ : $/, ""); this.logger.warn(msgString); }, /** * Logs a message in INFO level. * * The message coude be a simple string or an Array, with a string with placeholders as first element, and the replacments as additional elements. * * @param {String|Array} msg The message * @param {Object} obj Optional object which will be printed after the message in serialized form * @example */ info: function (msg, obj) { var objString = this.stringify(obj), msgString = this.pattern.info.replace("{{scope}}", this.scope).replace("{{msg}}", this.format(msg)).replace("{{object}}", objString).replace(/ : $/, ""); this.logger.info(msgString); }, /** * Logs a message in DEBUG level. * * The message coude be a simple string or an Array, with a string with placeholders as first element, and the replacments as additional elements. * * @param {String|Array} msg The message * @param {Object} obj Optional object which will be printed after the message in serialized form */ debug: function (msg, obj) { if (this.debugEnabled) { var objString = this.stringify(obj), msgString = this.pattern.debug.replace("{{scope}}", this.scope).replace("{{msg}}", this.format(msg)).replace("{{object}}", objString).replace(/ : $/, ""); this.logger.debug(msgString); } }, /** * Logs a message in DEBUG level and starts the time meassurment for the function. * * @param {String} funct The entered function * @param {Object} obj Optional object which will be printed after the message in serialized form */ enter: function (funct, obj) { var objString, msgString; if (this.debugEnabled) { this.doTiming(funct); objString = this.stringify(obj); msgString = this.pattern.enter.replace("{{scope}}", this.scope).replace("{{funct}}", funct).replace("{{object}}", objString).replace(/ : $/, ""); this.logger.debug(msgString); } }, /** * Logs a message in DEBUG level and finished the time meassurment for the function. * * The logged message contains the duration since the enter function was called. * * @param {String} funct The entered function * @param {Object} obj Optional object which will be printed after the message in serialized form */ exit: function (funct, obj) { var duration, objString, msgString; if (this.debugEnabled) { duration = this.doTiming(funct); objString = this.stringify(obj); msgString = this.pattern.exit.replace("{{scope}}", this.scope).replace("{{funct}}", funct).replace("{{time}}", duration).replace("{{object}}", objString).replace(/ : $/, ""); this.logger.debug(msgString); } }, /** * @private * If parameter is an Array, the first value will be treated as the String and all other elements will be inserted at the placeholder positions in that String, maintaining their order. * @param {String|Array} msg * @returns {String} */ format: function (msg) { var message, params; if (Object.prototype.toString.call(msg) === "[object Array]") { message = msg[0]; params = msg.slice(1); message = message.replace(/\{(\d+)\}/g, function (match, number) { return (typeof params[number] !== "undefined") ? params[number] : match; }); } else { message = msg; } return message; }, /** * @private * @param {String|Object} obj * @returns {String} */ stringify: function (obj) { var objType, str; if (typeof obj === "string") { return obj; } objType = Object.prototype.toString.call(obj); if ((objType == "[object Arguments]") || (objType == "[object JavaObject]")) { return ""; } try { str = JSON.stringify(obj, function (key, value) { if (value instanceof java.lang.String) { return String(value); } if (value && value.getClass) { return String(value.toString()); } return value; }) || ""; return str; } catch (ex) { return typeof obj; } }, /** * @private * @param {String} func Name/Identifier for saving the start time * @returns {Number} */ doTiming: function (func) { var now = Date.now(), timingKey = this.scope + func, timingValue = this.timings[timingKey], duration; if (timingValue) { this.timings[timingKey] = undefined; duration = now - timingValue; if (duration < 0) { duration = 0; } return duration; } else { this.timings[timingKey] = now; } return -1; }, /** * @private */ noop: function () {} }); } if (!sol.ClassManager.getClass("sol.Base")) { /** * @class sol.Base * @extends Object * * The Base class implements basic operations that are might be required by all child classes. * * It is always set as the root superclass for all class definitions if no inheritance was defined by 'extend'. * * // the following class definition ... * sol.define('sol.common.ix.DatabaseIterator', { }); * sol.define('sol.invoice.ix.dynkwl.Company', { * extend: 'sol.common.ix.DatabaseIterator' * } * * // ... will lead to following class inheritance structure * sol.Base * - sol.common.ix.DatabaseIterator * - sol.invoice.ix.dynkwl.Company * * The initialize function of the Base Class handles a couple of operations and should always be called if a child class * overrides initialize: * * - instantiates logger for class with the current child's class name as scope config. * - applies all config properties to the class instance. * - checks if required config properties (defined by requiredConfig) are set * * # A note on config properties and class inheritance * * Please mind that if config properties are different than class defaults that they get applied to the child class * after calling $super('sol.Base', 'initialize'). * * sol.define('sol.invoice.ix.dynkwl.Company', { * extend: 'sol.common.ix.DatabaseIterator', * * myConfig: 'not set yet', * * initialize: function(config) { * var me = this; * // me.myConfig = "not set yet" * me.$super("sol.Base", "initialize", [config]); * // me.myConfig = "is now set" * } * }); * * sol.create('sol.invoice.ix.dynkwl.Company', { * myConfig: 'is now set' * }); * * @author Pascal Zipfel, ELO Digital Office GmbH * @version 1.0 * * @eloall */ sol.define("sol.Base", { /** * @property {sol.Logger} logger * @protected * Logger for this class instance. This logger is created by sol.Base#initialize. * * Please see sol.Logger class documentation for more information. */ logger: undefined, /** * @property {Array} requiredConfig * @cfg {Array} requiredConfig * @protected * List of required config properties. sol.Base#initialize throws an exception if one of the properties is null or undefined. */ requiredConfig: undefined, /** * @property $className {String} * @protected * name of the class including its namespace. */ /** * @method $super * @member sol.Base * @private * * Calls a function of a superclass thanks to its name. Superclass must be part of the calling objects class hierarchy. * * <b>Please note that calling superclass functions might lead to an infinitive loop if misused. Please validate that none class other than the classes superclass is passed as the superclass parent.</b> * * me.$super(superClassName, functionName, attributesArray); * * A basic example of the initialize-function will look as followed. * * me.$super("sol.Base", "initialize", [config]); * me.$super("sol.Base", "initialize", arguments); * * A word on performance: The superclass name must be passed since the js rhino engine does not allow accessing the caller of the callee due to performance reasons. * * @param {String} superClassName name of the super class. * @param {String} functionName name of the function that should be called. * @param {Object[]} arguments list of arguments that should be passed to the function. */ /** * @private * * Initialize class. * This function is called after the class was instantiated. * * @param {Object} config parameters as defined. See documentation for more details. */ initialize: function (config) { var me = this, property; me.logger = sol.create("sol.Logger", { scope: me.$className }); for (property in config) { if (config.hasOwnProperty(property)) { if (typeof me[property] === "function" && typeof config[property] !== "function") { throw "[" + me.$className + "] Illegal overriding internal function with a value: " + property + ". Existing functions cannot be overriden with non functional values using sol.create()."; } else if (property === "extend" || property === "requiredConfig" || property === "singleton" || property === "$super" || property === "$className" || property === "$parent" || property === "CONST") { throw "[" + me.$className + "] Illegal overriding internal object value: " + property + ". requiredConfig and singleton as well as properties starting with $ are protected and should not be set using sol.create()."; } me[property] = config[property]; } } if (me.requiredConfig) { me.requiredConfig.forEach(function (requiredProperty) { if (me[requiredProperty] === null || me[requiredProperty] === undefined) { throw "[" + me.$className + "] Could not create object. Missing config property: " + requiredProperty + ". Please ensure all required properties are set: " + JSON.stringify(me.requiredConfig); } }); } } }); } //# sourceURL=lib_Class.js