Example #1
0
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)
Example #2
0
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)
Example #3
0
def serialize_cls(cls, depth=1):
    """(cls:ModelDescriptor) -> [str]
    
    Assumption: cls (subclass of ModelDescriptor) is localizable.
    """
    type_key = naming.type_key("descriptor_class_name", cls.__name__)
    _acc = []
    for f in cls.fields:
        _acc.extend(serialize_field(f, depth+1))
    _acc.extend(serialize_integrity(
            cls.schema_invariants, cls.custom_validators, depth+1))
    
    acc = []
    ind = INDENT * depth
    acc.append(ind)
    if _acc:
        if cls.order != 999: # default "not ordered":
            acc.append('%s<descriptor name="%s" order="%s">' % (
                    ind, type_key, cls.order))
        else:
            acc.append('%s<descriptor name="%s">' % (ind, type_key))
        acc.extend(_acc)
        acc.append('%s</descriptor>' % (ind))
    else:
        acc.append('%s<descriptor name="%s" />' % (ind, type_key))
    return acc
Example #4
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(title=_title,
                  description=_title,
                  action=url.absoluteURL(item, request),
                  selected=False,
                  icon=None,
                  extra={},
                  submenu=None))
     return results
Example #5
0
def reset_zope_schema_properties_on_model_interface(descriptor_cls):
    type_key = naming.type_key("descriptor_class_name",
                               descriptor_cls.__name__)
    ti = capi.get_type_info(type_key)
    domain_model = ti.domain_model
    sast = alchemist.sa2zs.SQLAlchemySchemaTranslator()
    domain_table = alchemist.utils.get_local_table(domain_model)
    # zope.schema field property map
    zsfp_map = sast.generate_fields(domain_table, descriptor_cls)
    # apply manually overridden field properties
    sast.apply_properties(zsfp_map, descriptor_cls)
    # stuff back onto derived_table_schema
    derived_table_schema = ti.derived_table_schema
    assert set(derived_table_schema.names(all=False)) == set(zsfp_map), \
        "Incosistency in descriptor %r field lists:\n old:%s\n new:%s" % (
            type_key,
            sorted(set(derived_table_schema.names(all=False))),
            sorted(set(zsfp_map)))
    for name in derived_table_schema.names(all=False):
        # !+ zsfp == descriptor_cls.fields_by_name[name].property
        zsfp = zsfp_map[name]
        # !+property.__name__ needed downstream by
        # zope.formlib.form.FormField __init__() does assert name !?!
        zsfp.__name__ = name
        # !+ cannot simply set the property directly on derived_table_schema:
        #   derived_table_schema[f.name] = zsfp
        # as this gives:
        #   *** TypeError: 'InterfaceClass' object does not support item assignment
        # So we have to workaround it !!
        derived_table_schema._InterfaceClass__attrs[name] = zsfp
    # and we need to notify (only once) that the schema has changed
    derived_table_schema.changed("localize_descriptors")
def reset_zope_schema_properties_on_model_interface(descriptor_cls):
    type_key = naming.type_key("descriptor_class_name", descriptor_cls.__name__)
    ti = capi.get_type_info(type_key)
    domain_model = ti.domain_model
    sast = alchemist.sa2zs.SQLAlchemySchemaTranslator()
    domain_table = alchemist.utils.get_local_table(domain_model)
    # zope.schema field property map
    zsfp_map = sast.generate_fields(domain_table, descriptor_cls)
    # apply manually overridden field properties
    sast.apply_properties(zsfp_map, descriptor_cls)
    # stuff back onto derived_table_schema
    derived_table_schema = ti.derived_table_schema
    assert set(derived_table_schema.names(all=False)) == set(zsfp_map), \
        "Incosistency in descriptor %r field lists:\n old:%s\n new:%s" % (
            type_key, 
            sorted(set(derived_table_schema.names(all=False))), 
            sorted(set(zsfp_map)))
    for name in derived_table_schema.names(all=False):
        # !+ zsfp == descriptor_cls.fields_by_name[name].property
        zsfp = zsfp_map[name]
        # !+property.__name__ needed downstream by 
        # zope.formlib.form.FormField __init__() does assert name !?!
        zsfp.__name__ = name
        # !+ cannot simply set the property directly on derived_table_schema:
        #   derived_table_schema[f.name] = zsfp
        # as this gives: 
        #   *** TypeError: 'InterfaceClass' object does not support item assignment
        # So we have to workaround it !!
        derived_table_schema._InterfaceClass__attrs[name] = zsfp
    # and we need to notify (only once) that the schema has changed 
    derived_table_schema.changed("localize_descriptors")
Example #7
0
 def permission_type_key(self):
     if self.custom:
         # custom types ALWAYS have a type_key-bound workflow instance - that
         # may therefore have a different name than workflow_key e.g. Office
         # uses the "group" workflow, that is type-relative reloaded as the
         # "office" workflow instance.
         return self.workflow.name
     # system types ALWAYS use workflow_key - even if multiple types use the
     # same workflow e.g. UserAddress & GroupAddress.
     # if no workflow, compute type_key from domain_model
     # #!+REDUNDANT(mb, 2012) This type key is already known during type
     # setup i.e. TYPE_REGISTRY
     return (self.workflow_key
             or naming.type_key("model_name", self.domain_model.__name__))
Example #8
0
 def permission_type_key(self):
     if self.custom:
         # custom types ALWAYS have a type_key-bound workflow instance - that
         # may therefore have a different name than workflow_key e.g. Office
         # uses the "group" workflow, that is type-relative reloaded as the
         # "office" workflow instance.
         return self.workflow.name
     # system types ALWAYS use workflow_key - even if multiple types use the 
     # same workflow e.g. UserAddress & GroupAddress. 
     # if no workflow, compute type_key from domain_model
     # #!+REDUNDANT(mb, 2012) This type key is already known during type
     # setup i.e. TYPE_REGISTRY
     return (self.workflow_key or 
         naming.type_key("model_name", self.domain_model.__name__)
     )
Example #9
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                                                   IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(
                 title=_title,
                 description=_title,
                 action=url.absoluteURL(item, request),
                 selected=False,
                 icon=None,
                 extra={"id": "nav_calendar_content_%s" % key},
                 submenu=None,
             ))
     return results
Example #10
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                 IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={"id": "nav_calendar_content_%s" % key},
             submenu=None,
         ))
     return results
Example #11
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={},
             submenu=None
             
         ))
     return results
Example #12
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.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)
Example #13
0
 def display_name(cls):
     cls_name = naming.model_name(
         naming.type_key("descriptor_class_name", cls.__name__))
     return naming.split_camel(cls_name) # !+unicode
Example #14
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)