def apply_customization_workflow(name): """Apply customizations, features as per configuration from a workflow. Must (currently) be run after db setup. """ # support to infer/get the domain class from the workflow name def camel(name): """Convert an underscore-separated word to CamelCase. """ return "".join([s.capitalize() for s in name.split("_")]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel( get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) # !+RENAME_TO_CONVENTION get_domain_kls.non_conventional = { "address": "address", # !+ use common base cls for User & Group addresses "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } # get the domain class kls = get_domain_kls(name) # We "mark" the domain class with IWorkflowed, to be able to # register/lookup adapters generically on this single interface. classImplements(kls, IWorkflowed) # dynamic features from workflow wf = get_workflow(name) # note: versionable implies auditable if wf.auditable or wf.versionable: # decorate the kls if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) # modify schema/mapping as needed schema.configurable_schema(kls) orm.configurable_mappings(kls) # create/set module-level dedicated auditor singleton for auditable kls bungeni.core.audit.set_auditor(kls)
def apply_customization_workflow(name): """Apply customizations, features as per configuration from a workflow. Must (currently) be run after db setup. """ # support to infer/get the domain class from the workflow name def camel(name): """Convert an underscore-separated word to CamelCase. """ return "".join([ s.capitalize() for s in name.split("_") ]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel( get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) # !+RENAME_TO_CONVENTION get_domain_kls.non_conventional = { "address": "address", # !+ use common base cls for User & Group addresses "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } # get the domain class kls = get_domain_kls(name) # We "mark" the domain class with IWorkflowed, to be able to # register/lookup adapters generically on this single interface. classImplements(kls, IWorkflowed) # dynamic features from workflow wf = get_workflow(name) # note: versionable implies auditable if wf.auditable or wf.versionable: # decorate the kls if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) # modify schema/mapping as needed schema.configurable_schema(kls) orm.configurable_mappings(kls) # create/set module-level dedicated auditor singleton for auditable kls bungeni.core.audit.set_auditor(kls)
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows")): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # # if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # Normally this is done by applying the iface to the target type, but # at this point may may not be unambiguously determined--so, we instead # "mark" the interface itself... by simply adding IWorkflowed as an # inheritance ancestor to iface (if it is not already): if IWorkflowed not in iface.__bases__: iface.__bases__ = (IWorkflowed,) + iface.__bases__ # apply customizations, features as per configuration of the document type def camel(name): """Convert an underscore-separated word to CamelCase.""" return "".join([s.capitalize() for s in name.split("_")]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel(get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) # !+RENAME_TO_CONVENTION get_domain_kls.non_conventional = { "address": "user_address", # "group_address"? "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } if wf.auditable or wf.versionable: kls = get_domain_kls(name) if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) schema.configurable_schema(kls) orm.configurable_mappings(kls) bungeni.core.audit.set_auditor(kls) kn = kls.__name__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface)
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows") ): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # Normally this is done by applying the iface to the target type, but # at this point may may not be unambiguously determined--so, we instead # "mark" the interface itself... by simply adding IWorkflowed as an # inheritance ancestor to iface (if it is not already): if (IWorkflowed not in iface.__bases__): iface.__bases__ = (IWorkflowed,) + iface.__bases__ # apply customizations, features as per configuration of the document type def camel(name): """Convert an underscore-separated word to CamelCase.""" return "".join([ s.capitalize() for s in name.split("_") ]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel( get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) get_domain_kls.non_conventional = { "address": "user_address", # "group_address"? "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } if wf.auditable or wf.versionable: kls = get_domain_kls(name) if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) schema.configurable_schema(kls) orm.configurable_mappings(kls) bungeni.core.audit.set_auditor(kls) kn = kls.__name__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface) # !+VERSION_WORKFLOW(mr, apr-2011) if name == "version": component.provideAdapter(bungeni.core.version.ContextVersioned, (interfaces.IVersionable,), bungeni.core.interfaces.IVersioned)