예제 #1
0
def load_workflow(type_key, ti):
    """Load (from XML definition), set the workflow instance, and setup (once).
    """
    if ti.workflow_key is None:
        return
    assert ti.workflow is None
    workflow_file_key = ti.workflow_key  # workflow file name

    # workflow_name -> what becomes workflow.name (and ti.permissions_type_key)
    workflow_name = workflow_file_key
    if ti.custom and type_key != workflow_file_key:
        workflow_name = type_key
    # !+ only (non-custom type) "address" wf is multi-used by user_address/group_address

    try:
        # retrieve
        ti.workflow = Workflow.get_singleton(workflow_name)
        log.warn("Already Loaded WORKFLOW: %s.xml as %r - %s" %
                 (workflow_file_key, workflow_name, ti.workflow))
    except KeyError:
        # load
        ti.workflow = xmlimport.load(workflow_file_key, workflow_name)
        log.info("Loaded WORKFLOW: %s.xml as %r - %s" %
                 (workflow_file_key, workflow_name, ti.workflow))
        # debug info
        for state_key, state in ti.workflow.states.items():
            log.debug("   STATE: %s %s" % (state_key, state))
            for p in state.permissions:
                log.debug("          %s" % (p, ))

    # setup
    if ti.workflow:
        apply_customization_workflow(type_key, ti)
        register_specific_workflow_adapter(ti)
예제 #2
0
def load_workflow(module, kls):
    name = module.__name__.rsplit('.')[-1]
    wf = xmlimport.load("%s/%s.xml" % (path, name))
    events.register_workflow_transitions(wf, kls)
    module.wf = wf
    module.states = wf.states
    _log = log.debug
    _log("WORKFLOW: %s %s" % (name, wf))
    for state_key, state in wf.states.items():
        _log("   STATE: %s %s" % (state_key, state))
        for p in state.permissions:
            _log("          %s" % (p, ))
    return wf
예제 #3
0
def load_workflow(name, 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 get_workflow._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, ))
        # Workflow instances as utilities
        provideUtilityWorkflow(wf, name)
    else:
        wf = get_workflow(name)
        log.warn("Already Loaded WORKFLOW : %s %s" % (name, wf))
예제 #4
0
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.
    #
    # A simple way to "mark" the supplied iface with IWorkflowed is to
    # "add" IWorkflowed as an inheritance ancestor to iface:
    if (IWorkflowed not in iface.__bases__):
        iface.__bases__ = (IWorkflowed, ) + iface.__bases__

    # 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)
예제 #5
0
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)