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 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 _get(discriminator): """Get the TypeInfo instance for discriminator, that may be any of: type_key: str (the lowercase underscore-separated of domain cls name) workflow: an instance of Workflow, provides IWorkflow interface: provides IInterface domain model: provides IBungeniContent domain model instance: type provides IBungeniContent descriptor: provides IModelDescriptor Raise KeyError if no entry matched. Usage: capi.get_type_info(discriminator) """ if discriminator is None: m = "type_info._get discriminator is None" log.error(m) raise ValueError(m) discri = removeSecurityProxy(discriminator) getter = None # !+IALCHEMISTCONTENT normalize trickier discriminator cases to type_key if IIModelInterface.providedBy(discri): discri = naming.type_key("table_schema_interface_name", discri.__name__) elif IInterface.providedBy(discri): discri = naming.type_key("model_interface_name", discri.__name__) elif type(discri) is type and issubclass(discri, domain.Entity): discri = naming.polymorphic_identity(discri) elif isinstance(discri, domain.Entity): discri = naming.polymorphic_identity(type(discri)) if isinstance(discri, basestring): getter = _get_by_type_key #elif IInterface.providedBy(discri): # getter = _get_by_interface #!+elif interfaces.IBungeniContent.implementedBy(discri): #elif issubclass(discri, domain.Entity): # getter = _get_by_model #!+elif interfaces.IBungeniContent.providedBy(discri): #elif isinstance(discri, domain.Entity): # getter = _get_by_instance elif IWorkflow.providedBy(discri): getter = _get_by_workflow elif IModelDescriptor.implementedBy(discri): getter = _get_by_descriptor_model if getter is not None: ti = getter(discri) if ti is not None: return ti else: m = "No type registered for discriminator: %r" % (discriminator) else: m = "Invalid type info lookup discriminator: %r" % (discriminator) from bungeni.utils import probing log.debug(probing.interfaces(discriminator)) log.debug(m) raise KeyError(m)
def _get(discriminator): """Get the TypeInfo instance for discriminator, that may be any of: type_key: str (the lowercase underscore-separated of domain cls name) workflow: an instance of Workflow, provides IWorkflow interface: provides IInterface domain model: provides IBungeniContent domain model instance: type provides IBungeniContent descriptor: provides IModelDescriptor Raise KeyError if no entry matched. Usage: capi.get_type_info(discriminator) """ if discriminator is None: m = "type_info._get discriminator is None" log.error(m) raise ValueError(m) discri = removeSecurityProxy(discriminator) getter = None # !+IALCHEMISTCONTENT normalize trickier discriminator cases to type_key if IIModelInterface.providedBy(discri): discri = naming.type_key("table_schema_interface_name", discri.__name__) elif IInterface.providedBy(discri): discri = naming.type_key("model_interface_name", discri.__name__) elif type(discri) is type and issubclass(discri, domain.Entity): discri = naming.polymorphic_identity(discri) elif isinstance(discri, domain.Entity): discri = naming.polymorphic_identity(type(discri)) if isinstance(discri, basestring): getter = _get_by_type_key #elif IInterface.providedBy(discri): # getter = _get_by_interface #!+elif interfaces.IBungeniContent.implementedBy(discri): #elif issubclass(discri, domain.Entity): # getter = _get_by_model #!+elif interfaces.IBungeniContent.providedBy(discri): #elif isinstance(discri, domain.Entity): # getter = _get_by_instance elif IWorkflow.providedBy(discri): getter = _get_by_workflow elif IModelDescriptor.implementedBy(discri): getter = _get_by_descriptor_model if getter is not None: ti = getter(discri) if ti is not None: return ti else: m = "No type registered for discriminator: %r" % (discriminator) else: m = "Invalid type info lookup discriminator: %r" % (discriminator) from bungeni.ui.utils import debug log.debug(debug.interfaces(discriminator)) log.debug(m) raise KeyError(m)
def queryModelInterface(cls): """We can passed in a class or an interface. """ if not IInterface.providedBy(cls): candidates = list(interface.implementedBy(cls)) ifaces = filter(IIModelInterface.providedBy, candidates) #import pdb; pdb.set_trace() if not ifaces: for i in candidates: if issubclass(i, IAlchemistContent): ifaces.append(i) if not ifaces: raise SyntaxError("No Model Interface on Domain Object") if ifaces: assert len(ifaces)==1, "Multiple Model Interfaces on Domain Object" #import pdb; pdb.set_trace() cls = ifaces[0] else: assert IIModelInterface.providedBy(cls), "Invalid Interface" return cls
def queryModelInterface(cls): """We can passed in a class or an interface. """ if not IInterface.providedBy(cls): candidates = list(interface.implementedBy(cls)) ifaces = filter(IIModelInterface.providedBy, candidates) #import pdb; pdb.set_trace() if not ifaces: for i in candidates: if issubclass(i, IAlchemistContent): ifaces.append(i) if not ifaces: raise SyntaxError("No Model Interface on Domain Object") if ifaces: assert len( ifaces) == 1, "Multiple Model Interfaces on Domain Object" #import pdb; pdb.set_trace() cls = ifaces[0] else: assert IIModelInterface.providedBy(cls), "Invalid Interface" return cls
def queryModelInterface(cls): """This queries the domain model class for the exclusively alchemist IIModelInterface interface. If cls is already such an interface it itself is returned. """ if not IInterface.providedBy(cls): candidates = list(interface.implementedBy(cls)) ifaces = filter(IIModelInterface.providedBy, candidates) #import pdb; pdb.set_trace() if not ifaces: for i in candidates: if issubclass(i, IAlchemistContent): ifaces.append(i) if not ifaces: raise SyntaxError("No Model Interface on Domain Object [%s]" % (cls)) if ifaces: assert len(ifaces)==1, "Multiple Model Interfaces on Domain Object" #import pdb; pdb.set_trace() return ifaces[0] else: assert IIModelInterface.providedBy(cls), "Invalid Interface" return cls
def GenerateDomainInterface(ctx, interface_name=None): # when called from zcml, most likely we'll get a class not an instance # if it is a class go ahead and call instantiate it if isinstance(ctx.descriptor, type): ctx.descriptor = ctx.descriptor() # if the interface module is none, then use the nearest one to the domain class if ctx.interface_module is None: ctx.interface_module = _get_interface_module_for(ctx) # interface for domain model if not interface_name: interface_name = "I%s"%(ctx.domain_model.__name__) if ctx.echo: ctx.logger.debug("%s: generated interface %s.%s " % ( ctx.domain_model.__name__, ctx.interface_module.__name__, interface_name)) from alchemist.catalyst.domain import getDomainInterfaces #!+ALCHEMIST_INTERNAL bases, implements = getDomainInterfaces(ctx.domain_model) # use the class"s mapper select table as input for the transformation domain_mapper = orm.class_mapper(ctx.domain_model) ## 0.4 and 0.5 compatibility, 0.5 has the table as local_table (select_table) is none lazy gen? #domain_table = getattr(domain_mapper, "local_table", domain_mapper.select_table) # The 0.6 has no attribute select_table attribute. We still have 0.4 # compitability thought domain_table = (domain_mapper.local_table if sa_version[1] >= 5 else domain_mapper.select_table) # if the domain model already implements a model interface, use it # instead of generating a new one for iface in interface.implementedBy(ctx.domain_model): if (IIModelInterface.providedBy(iface) and iface.__name__ == interface_name ): domain_interface = iface break else: domain_interface = sa2zs.transmute( domain_table, annotation=ctx.descriptor, interface_name = interface_name, __module__ = ctx.interface_module.__name__, bases=bases) # if we're replacing an existing interface, make sure the new # interface implements it old = getattr(ctx.interface_module, interface_name, None) if old is not None: implements.append(old) implements.insert(0, domain_interface) # ensure interfaces are unique, preserving the order #implements = [ ifc for i,ifc in enumerate(implements) # if implements.index(ifc)==i ] # # XXX: Oooh, strangely the above does not work... it turns out that # implements contains seemingly repeated interfaces e.g. the first and last # interfaces are both "<InterfaceClass bungeni.models.interfaces.IReport>" # but, they are not the same! So, to compare unique we use the string # representation of each interface: # str_implements = map(str, implements) # implements = [ ifc for i,ifc in enumerate(implements) # if str_implements.index(str(ifc))==i ] # Ooops making the interfaces unique breaks other things downstream :( interface.classImplementsOnly(ctx.domain_model, *implements) setattr(ctx.interface_module, interface_name, domain_interface) ctx.domain_interface = domain_interface
def GenerateDomainInterface(ctx, interface_name=None): # when called from zcml, most likely we'll get a class not an instance # if it is a class go ahead and call instantiate it if isinstance(ctx.descriptor, type): ctx.descriptor = ctx.descriptor() # if the interface module is none, then use the nearest one to the domain class if ctx.interface_module is None: ctx.interface_module = _get_interface_module_for(ctx) # interface for domain model if not interface_name: interface_name = "I%s" % (ctx.domain_model.__name__) if ctx.echo: ctx.logger.debug("%s: generated interface %s.%s " % (ctx.domain_model.__name__, ctx.interface_module.__name__, interface_name)) from alchemist.catalyst.domain import getDomainInterfaces #!+ALCHEMIST_INTERNAL bases, implements = getDomainInterfaces(ctx.domain_model) # use the class"s mapper select table as input for the transformation domain_mapper = orm.class_mapper(ctx.domain_model) ## 0.4 and 0.5 compatibility, 0.5 has the table as local_table (select_table) is none lazy gen? #domain_table = getattr(domain_mapper, "local_table", domain_mapper.select_table) # The 0.6 has no attribute select_table attribute. We still have 0.4 # compitability thought domain_table = (domain_mapper.local_table if sa_version[1] >= 5 else domain_mapper.select_table) # if the domain model already implements a model interface, use it # instead of generating a new one for iface in interface.implementedBy(ctx.domain_model): if (IIModelInterface.providedBy(iface) and iface.__name__ == interface_name): domain_interface = iface break else: domain_interface = sa2zs.transmute( domain_table, annotation=ctx.descriptor, interface_name=interface_name, __module__=ctx.interface_module.__name__, bases=bases) # if we're replacing an existing interface, make sure the new # interface implements it old = getattr(ctx.interface_module, interface_name, None) if old is not None: implements.append(old) implements.insert(0, domain_interface) # ensure interfaces are unique, preserving the order #implements = [ ifc for i,ifc in enumerate(implements) # if implements.index(ifc)==i ] # # XXX: Oooh, strangely the above does not work... it turns out that # implements contains seemingly repeated interfaces e.g. the first and last # interfaces are both "<InterfaceClass bungeni.models.interfaces.IReport>" # but, they are not the same! So, to compare unique we use the string # representation of each interface: # str_implements = map(str, implements) # implements = [ ifc for i,ifc in enumerate(implements) # if str_implements.index(str(ifc))==i ] # Ooops making the interfaces unique breaks other things downstream :( interface.classImplementsOnly(ctx.domain_model, *implements) setattr(ctx.interface_module, interface_name, domain_interface) ctx.domain_interface = domain_interface