//@include lib_Class.js /** * Document generation. * * This class can be used to render different kinds of documents from templates. * * To be more flexible, it uses a data collector, to collect the data which can be included in the document, and a renderer to render the resulting document. * * #Data collection * Data collection can either be implemented with a class or with a registered function. * * #Rendering * For rendering a class has to be specified. This class needs to implement a `render` function which has a name and the data (result from data collector) as arguments. * * #Ordering * The ordering of the data, should be determined by the data collector. Anyway, there are possible scenarios (e.g. reusing a generic data collector) * where it will be necessary to apply a different ordering. To accomplish this, a {@link #compareFct compare function} can be implemented. * This function will be applied an the data collector result after the collection. * It will be called with two {@link sol.common.ObjectFormatter.TemplateSord TemplateSord} as arguments (see {@link #compareFct}). * * #Configuration * The configuration for the used modules has to be defined during construction of the `DocumentGenerator`. * The defined objects `collectorConfig` and `rendererConfig` will be handed directly to the used modules and therefor their structure is dependent on the used module. * * #Examples * * The first example will generate a word document with the data returned by the `ParentDataCollector`: * * var generator = sol.create("sol.common.as.DocumentGenerator", { * name: name, * dataCollector: "RF_sol_pubsec_service_ParentDataCollector", * renderer: "sol.common.as.renderer.Word", * collectorConfig: { * objId: me.objId, * returnDataDefinition: true * }, * rendererConfig: { * objId: me.objId, * templateId: me.templateId * } * }); * var result = generator.process(); * * The next example will generate a PDF report with all child elements having a defined mask. The result of the data collector will be sorted using the `compareFct`: * * var generator = sol.create("sol.common.as.DocumentGenerator", { * name: name, * dataCollector: "sol.common.ix.services.ChildrenDataCollector", * renderer: "sol.common.as.renderer.Fop", * collectorConfig: { * parentId: me.parentId, * endLevel: -1, * objKeys: [], * totalCount: 50000, * sordKeys: ['ownerName', 'name', 'maskName', 'maskId', 'id', 'guid', 'parentId', 'XDateIso', 'IDateIso'], * maskName: me.config.filingPlan.maskName, * formatter: "sol.common.ObjectFormatter.TemplateSord" * }, * rendererConfig: { * targetId: me.targetId, * templateId: me.templateId * }, * compareFct: function (templateSord1, templateSord2) { * var result; * try { * result = templateSord1.objKeys.FILING_PLAN_REFERENCE.localeCompare(templateSord2.objKeys.FILING_PLAN_REFERENCE); * } catch (ex) { * result = 0; * } * return result; * } * }); * var result = generator.process(); * * #DocumentGenerator result * The result object is the object returned by the `render` function of the renderer. * * @author PZ, ELO Digital Office GmbH * @version 1.1 * * @eloas * @requires sol.common.ObjectUtils * @requires sol.common.ObjectFormatter * @requires sol.common.StringUtils * @requires sol.common.IxUtils * @requires sol.common.SordUtils */ sol.define("sol.common.as.DocumentGenerator", { requiredConfig: ["dataCollector", "renderer", "name"], /** * @cfg {String} dataCollector (required) */ /** * @cfg {Boolean} returnData * Return the data in `result.data` */ /** * @cfg {String} renderer (required) */ /** * @cfg {String} name (required) * The name for the document */ /** * @cfg {Object} collectorConfig * The configuration handed to the renderer module/function */ /** * @cfg {Object} rendererConfig * The configuration handed to the renderer module */ /** * @cfg {Function} compareFct * Function to sort the `dataCollector` result. * * The function will be called with to {@link sol.common.ObjectFormatter.TemplateSord TemplateSord} objects * and has to return `-1` if first TemplateSord is bigger then the second one, `1` in the opposite case, or `0` if they are equal. * * function (templateSord1, templateSord2) { * return templateSord1.objKeys.FILING_PLAN_REFERENCE.localeCompare(templateSord2.objKeys.FILING_PLAN_REFERENCE); * } */ /** * @cfg {Boolean} restrictRightsToCurrentUser * Restricts the rights of the document to the current user */ /** * @cfg {Object} additionalSordData * Definitions of additional Sord data to be provided, e.g. filter data for reports * * additionalSordData: [{ * objId: me.objId, * propertyName: "settings" * }] */ /** * @cfg {String} additionalSordData[].objId * Object ID of the Sord whose data is to be provided */ /** * @cfg {String} additionalSordData[].propertyName * Name of the property in which the additional data is provided */ initialize: function (config) { var me = this; me.$super("sol.Base", "initialize", [config]); me.initDataCollector(config); me.initRenderer(config); }, process: function () { var me = this, data, result, additionalSord, additionalTplSord, i, additionalSordDataDef; data = me.dataCollector.collect(); if (sol.common.ObjectUtils.isFunction(me.compareFct) && data && data.sords && (data.sords.length > 0)) { data.sords.sort(me.compareFct); } me.logger.debug(["additionalSordData: config={0}", JSON.stringify(me.additionalSordData) || ""]); if (me.additionalSordData) { for (i = 0; i < me.additionalSordData.length; i++) { additionalSordDataDef = me.additionalSordData[i]; if (additionalSordDataDef && additionalSordDataDef.objId && additionalSordDataDef.propertyName) { additionalSord = sol.common.RepoUtils.getSord(additionalSordDataDef.objId); additionalTplSord = sol.common.SordUtils.getTemplateSord(additionalSord).sord; me.logger.debug(["additionalSordData: propertyName={0}, data={1}", additionalSordDataDef.propertyName, JSON.stringify(additionalTplSord) || ""]); data[additionalSordDataDef.propertyName] = additionalTplSord; } } } result = me.renderer.render(me.name, data); if (result.objId && me.restrictRightsToCurrentUser) { sol.common.AclUtils.changeRightsInBackground(result.objId, { users: [EM_USERID], rights: { r: true, w: true, d: true, e: true, l: true, p: true }, mode: "SET" }); } if (me.returnData) { result.data = data; } return result; }, /** * @private * @param {Object} config */ initDataCollector: function (config) { var me = this; if (!sol.common.ObjectUtils.isObject(me.dataCollector)) { if (sol.common.StringUtils.startsWith(me.dataCollector, "RF_")) { me.dataCollector = { _conf: config.collectorConfig, _rf: me.dataCollector, collect: function () { var me = this; return sol.common.IxUtils.execute(me._rf, me._conf); } }; } else { me.dataCollector = sol.create(me.dataCollector, config.collectorConfig); } } if (!sol.common.ObjectUtils.isFunction(me.dataCollector.collect)) { throw "dataCollector has to define a 'collect' function"; } }, /** * @private * @param {Object} config */ initRenderer: function (config) { var me = this; if (!sol.common.ObjectUtils.isObject(me.renderer)) { me.renderer = sol.create(me.renderer, config.rendererConfig); } if (!sol.common.ObjectUtils.isFunction(me.renderer.render)) { throw "renderer has to define a 'render' function"; } } });