Exemple #1
0
def _setup_all():
    """Do all workflow related setup.
    
    This is the entry point of setup from configuration, with the main other
    participating modules being:
    - alchemist/type_info.py
    - alchemist/model.py
    - ui/descriptor/localization.py
    """
    log.info(
        "adapters._setup_all() ------------------------------------------")
    # cleared by each call to zope.app.testing.placelesssetup.tearDown()
    register_generic_workflow_adapters()

    # system and archetypes
    for type_key, ti in capi.iter_type_info():
        # retrieve the domain class and associate domain class with this type
        utils.inisetattr(ti, "domain_model", retrieve_domain_model(type_key))
        # load/get workflow instance (if any) and associate with type
        load_workflow(type_key, ti)

    # custom types
    # - first register/update each type in types.xml
    register_custom_types()
    for type_key, ti in capi.iter_type_info(scope="custom"):
        # load/get workflow instance (if any) and associate with type
        load_workflow(type_key, ti)

    # check/regenerate zcml directives for workflows - needs to be when and
    # right-after *all* workflows are loaded (to pre-empt further application
    # loading with possibly stale permission configuration).
    from bungeni.core.workflow import xmlimport
    xmlimport.zcml_check_regenerate()
Exemple #2
0
def generate_table_schema_interface(ti):
    '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
    def get_domain_interfaces(domain_model):
        """Return the domain bases for an interface as well as a filtered 
        implements only list (base interfaces removed).
        
        Note that for 2nd level (mapped) domain classes i.e. those that inherit
        from another domain class e.g. Event(Doc), Office(Group), 
        OfficeMember(GroupMembership), an IIModelInterface-providing 
        I*TableSchema interface had already been created (for base class) and 
        assigned to the super class--and that interface will match as one of 
        the domain_base interfaces here.
        """
        domain_bases = []
        domain_implements = []
        for iface in interface.implementedBy(domain_model):
            if IIModelInterface.providedBy(iface):
                domain_bases.append(iface)
            else:
                domain_implements.append(iface)
        domain_bases = tuple(domain_bases) or (IAlchemistContent,)
        return domain_bases, domain_implements
    bases, implements = get_domain_interfaces(ti.domain_model)
    '''

    # derived_table_schema:
    # - ALWAYS dynamically generated
    # - directlyProvides IIModelInterface (by virtue of IAlchemistContent)
    type_key = naming.polymorphic_identity(ti.domain_model)
    # use the class's mapper select table as input for the transformation
    table_schema_interface_name = naming.table_schema_interface_name(type_key)
    domain_table = utils.get_local_table(ti.domain_model)

    derived_table_schema = transmute(
        domain_table,
        annotation=ti.descriptor_model,
        interface_name=table_schema_interface_name,
        __module__=INTERFACE_MODULE.__name__,
        #_generated_by="bungeni.alchemist.catalyst.generate_table_schema_interface"
        #bases=bases)
        bases=(IAlchemistContent, ))

    # apply, register on type_info, set on module
    interface.classImplements(ti.domain_model, derived_table_schema)
    utils.inisetattr(ti, "derived_table_schema", derived_table_schema)
    setattr(INTERFACE_MODULE, table_schema_interface_name,
            derived_table_schema)
    log.info("generate_table_schema_interface: %s", derived_table_schema)

    # defensive sanity check - that derived_table_schema is precisely the FIRST
    # resolving IIModelInterface-providing interface implemented by domain_model
    # !+ this failing does not necessarily mean an incorrectness
    for iface in interface.implementedBy(ti.domain_model):
        if IIModelInterface.providedBy(iface):
            assert iface is derived_table_schema, (ti.domain_model, iface,
                                                   id(iface),
                                                   derived_table_schema,
                                                   id(derived_table_schema))
            break
    '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
def _setup_all():
    """Do all workflow related setup.
    
    This is the entry point of setup from configuration, with the main other
    participating modules being:
    - alchemist/type_info.py
    - alchemist/model.py
    - ui/descriptor/localization.py
    """
    log.info("adapters._setup_all() ------------------------------------------")
    # cleared by each call to zope.app.testing.placelesssetup.tearDown()
    register_generic_workflow_adapters()
    
    # system and archetypes
    for type_key, ti in capi.iter_type_info():
        # retrieve the domain class and associate domain class with this type
        utils.inisetattr(ti, "domain_model", retrieve_domain_model(type_key))
        # load/get workflow instance (if any) and associate with type
        load_workflow(type_key, ti)
    
    # custom types
    # - first register/update each type in types.xml
    register_custom_types()
    for type_key, ti in capi.iter_type_info(scope="custom"):
        # load/get workflow instance (if any) and associate with type
        load_workflow(type_key, ti)
    
    # check/regenerate zcml directives for workflows - needs to be when and 
    # right-after *all* workflows are loaded (to pre-empt further application 
    # loading with possibly stale permission configuration).
    from bungeni.core.workflow import xmlimport
    xmlimport.zcml_check_regenerate()
def generate_table_schema_interface(ti):
    '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
    def get_domain_interfaces(domain_model):
        """Return the domain bases for an interface as well as a filtered 
        implements only list (base interfaces removed).
        
        Note that for 2nd level (mapped) domain classes i.e. those that inherit
        from another domain class e.g. Event(Doc), Office(Group), 
        OfficeMember(GroupMembership), an IIModelInterface-providing 
        I*TableSchema interface had already been created (for base class) and 
        assigned to the super class--and that interface will match as one of 
        the domain_base interfaces here.
        """
        domain_bases = []
        domain_implements = []
        for iface in interface.implementedBy(domain_model):
            if IIModelInterface.providedBy(iface):
                domain_bases.append(iface)
            else:
                domain_implements.append(iface)
        domain_bases = tuple(domain_bases) or (IAlchemistContent,)
        return domain_bases, domain_implements
    bases, implements = get_domain_interfaces(ti.domain_model)
    '''
    
    # derived_table_schema:
    # - ALWAYS dynamically generated
    # - directlyProvides IIModelInterface (by virtue of IAlchemistContent)
    type_key = naming.polymorphic_identity(ti.domain_model)
    # use the class's mapper select table as input for the transformation
    table_schema_interface_name = naming.table_schema_interface_name(type_key)
    domain_table = utils.get_local_table(ti.domain_model)
    
    derived_table_schema = transmute(
        domain_table,
        annotation=ti.descriptor_model,
        interface_name=table_schema_interface_name,
        __module__=INTERFACE_MODULE.__name__,
        #_generated_by="bungeni.alchemist.catalyst.generate_table_schema_interface"
        #bases=bases)
        bases=(IAlchemistContent,))
    
    # apply, register on type_info, set on module
    interface.classImplements(ti.domain_model, derived_table_schema)
    utils.inisetattr(ti, "derived_table_schema", derived_table_schema)
    setattr(INTERFACE_MODULE, table_schema_interface_name, derived_table_schema)
    log.info("generate_table_schema_interface: %s", derived_table_schema)
    
    # defensive sanity check - that derived_table_schema is precisely the FIRST
    # resolving IIModelInterface-providing interface implemented by domain_model
    # !+ this failing does not necessarily mean an incorrectness
    for iface in interface.implementedBy(ti.domain_model):
        if IIModelInterface.providedBy(iface):
            assert iface is derived_table_schema, (ti.domain_model, 
                iface, id(iface), 
                derived_table_schema, id(derived_table_schema))
            break
    
    '''!+DO_NOT_REORDER_USER_APPLIED_INTERFACES
def catalyse_system_descriptors(module):
    """Catalyze system descriptor classes (with by-name-convention associated 
    model class) in specified module.
    
    Called when ui.descriptor is initially imported, so before descriptors for 
    custom types have been created (that happens on first call to 
    localization.localize_descriptors on application created event).
    
    !+CATALYSE_SYSTEM_DESCRIPTORS(mr, feb-2013) drop this, reworking it into
    catalysing on first time to localize each descriptor.
    """
    import sys
    import inspect
    from bungeni.alchemist.descriptor import IModelDescriptor
    from bungeni.models import domain
    from bungeni.capi import capi
    from bungeni.ui.utils import debug
    
    def descriptor_classes():
        """A generator of descriptor classes in this module, preserving the
        order of definition.
        """
        # dir() returns names in alphabetical order
        decorated = []
        for key in dir(module):
            cls = getattr(module, key)
            try:
                assert IModelDescriptor.implementedBy(cls)
                # we decorate with the source code line number for the cls
                decorated.append((inspect.getsourcelines(cls)[1], cls))
            except (TypeError, AttributeError, AssertionError):
                debug.log_exc(sys.exc_info(), log_handler=log.debug)
        # we yield each cls in order of definition
        for cls in [ cls for (line_num, cls) in sorted(decorated) ]:
            yield cls
    
    def is_model_mapped(domain_model):
        # try get mapper to force UnmappedClassError
        try:
            orm.class_mapper(domain_model)
            return True
        except orm.exc.UnmappedClassError:
            # unmapped class e.g. Address, Version
            return False
    
    for descriptor_model in descriptor_classes():
        descriptor_name = descriptor_model.__name__
        type_key = naming.type_key("descriptor_class_name", descriptor_name)
        # Associate each descriptor to the dedicated domain type via naming 
        # convention, and only catalysze (descriptor, model) pairs 
        # for which the domain type is mapped. Otherwise, ignore.
        domain_model = getattr(domain, naming.model_name(type_key), None)
        if not (domain_model and is_model_mapped(domain_model)):
            log.warn("Not catalysing: %s", descriptor_name)
            continue
        # type_info, register descriptor_model, domain_model
        ti = capi.get_type_info(type_key)
        utils.inisetattr(ti, "domain_model", domain_model)
        utils.inisetattr(ti, "descriptor_model", descriptor_model)
        # catalyse each (domain_model, descriptor_model) pair
        catalyse(ti)
    
    # !+remove?
    m = "\n\nDone all setup of system types... running with:\n\n%s\n\n" % (
            "\n\n".join(sorted(
                [ "%s: %s" % (key, ti) for key, ti in capi.iter_type_info() ])
            ))
    log.debug(m)
Exemple #6
0
def catalyse_system_descriptors(module):
    """Catalyze system descriptor classes (with by-name-convention associated 
    model class) in specified module.
    
    Called when ui.descriptor is initially imported, so before descriptors for 
    custom types have been created (that happens on first call to 
    localization.localize_descriptors on application created event).
    
    !+CATALYSE_SYSTEM_DESCRIPTORS(mr, feb-2013) drop this, reworking it into
    catalysing on first time to localize each descriptor.
    """
    import sys
    import inspect
    from bungeni.alchemist.descriptor import IModelDescriptor
    from bungeni.capi import capi
    from bungeni.ui.utils import debug
    
    def descriptor_classes():
        """A generator of descriptor classes in this module, preserving the
        order of definition.
        """
        # dir() returns names in alphabetical order
        decorated = []
        for key in dir(module):
            cls = getattr(module, key)
            try:
                assert IModelDescriptor.implementedBy(cls)
                # we decorate with the source code line number for the cls
                decorated.append((inspect.getsourcelines(cls)[1], cls))
            except (TypeError, AttributeError, AssertionError):
                debug.log_exc(sys.exc_info(), log_handler=log.debug)
        # we yield each cls in order of definition
        for cls in [ cls for (line_num, cls) in sorted(decorated) ]:
            yield cls
    
    def is_model_mapped(domain_model):
        # try get mapper to force UnmappedClassError
        try:
            orm.class_mapper(domain_model)
            return True
        except orm.exc.UnmappedClassError:
            # unmapped class e.g. Version
            return False
    
    for descriptor_model in descriptor_classes():
        descriptor_name = descriptor_model.__name__
        type_key = naming.type_key("descriptor_class_name", descriptor_name)
        # Associate each descriptor to the dedicated domain type via naming 
        # convention, and only catalyse (descriptor, model) pairs 
        # for which the domain type is mapped. Otherwise, ignore.
        domain_model = getattr(MODEL_MODULE, naming.model_name(type_key), None)
        if not (domain_model and is_model_mapped(domain_model)):
            log.warn("Not catalysing: %s", descriptor_name)
            continue
        # type_info, register descriptor_model, domain_model
        ti = capi.get_type_info(type_key)
        utils.inisetattr(ti, "domain_model", domain_model)
        utils.inisetattr(ti, "descriptor_model", descriptor_model)
        # catalyse each (domain_model, descriptor_model) pair
        catalyse(ti)
    
    # !+remove?
    m = "\n\nDone all setup of system types... running with:\n\n%s\n\n" % (
            "\n\n".join(sorted(
                [ "%s: %s" % (key, ti) for key, ti in capi.iter_type_info() ])
            ))
    log.debug(m)