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 _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)
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)