Exemple #1
0
 def test_needs_container_parent(self):
     needs_cp = set(eschema.type for eschema in self.schema.entities()
                    if utils.needs_container_parent(eschema))
     self.assertEqual([
         'CWAttribute', 'CWRelation', 'CWSourceSchemaConfig', 'Card',
         'Folder', 'RQLExpression'
     ], sorted(needs_cp))
Exemple #2
0
 def parent(self):
     if needs_container_parent(self.entity.e_schema):
         parent = self.entity.container_parent
         return parent[0] if parent else None
     try:
         rdef = first_parent_rdef(self.entity.e_schema)
         rtype, role = rdef.rtype.type, neg_role(rdef.composite)
     except StopIteration:
         self.debug('ContainerProtocol.parent stopped on %s', self.entity)
         return None
     parent = self.entity.related(rtype=rtype, role=role, entities=True)
     if parent:
         return parent[0]
Exemple #3
0
 def _container_parent_rdefs(self):
     """Compute a mapping from rtype to subject/object for use by the
     container hook. The hook will notice when the from/to etypes
     are in this mapping and compute the effective container_parent
     relation.
     """
     cprdefs = defaultdict(set)
     inner_rdefs = self.inner_rdefs
     for etype in self.etypes:
         eschema = self.schema[etype]
         if not utils.needs_container_parent(eschema):
             continue
         # let's compute the parent rdefs of this container
         for parent_rdef in utils.parent_rdefs(eschema):
             if parent_rdef not in inner_rdefs:
                 continue
             cprdefs[parent_rdef.rtype.type].add(
                 (parent_rdef.subject.type, parent_rdef.object.type))
     return dict(cprdefs)
Exemple #4
0
    def define_container(self, schema):
        """ Produce the necessary schema relations of a container:

        * (<container_rtype>, etype, cetype) for each container etype
        * (container_etype, etype, 'CWEType') for each container etype
        * an optional (if needed) (container_parent, etype, parent etype)
        """
        assert utils.fsschema(schema), \
            'this method is expected to be called only on filesystem schema (in schema.py)'
        assert not getattr(schema, '_%s_define_container' % self.cetype, False), \
            'this method is expected to be called only once on a schema (in schema.py)'
        setattr(schema, '_%s_define_container' % self.cetype, True)

        self.bind(schema)

        if self.crtype not in schema:
            # ease pluggability of container in existing applications
            schema.add_relation_type(RelationType(self.crtype, inlined=True))
            cw_schema.META_RTYPES.add(self.crtype)
        else:
            logger.warning(
                '%r is already defined in the schema - you probably want '
                'to let it to the container cube', self.crtype)
        crschema = schema[self.crtype]
        cetype_rschema = schema['container_etype']

        for etype in self.etypes:

            # populate <container_rtype>
            if (etype, self.cetype) not in crschema.rdefs:
                # checking this will help adding containers to existing applications
                # and reusing the container rtype
                schema.add_relation_def(
                    RelationDefinition(etype,
                                       self.crtype,
                                       self.cetype,
                                       cardinality='?*'))
            else:
                logger.warning(
                    '%r - %r - %r rdef is already defined in the schema '
                    '- you probably want to let it to the container cube',
                    etype, self.crtype, self.cetype)

            # populate container_etype
            if (etype, 'CWEType') not in cetype_rschema.rdefs:
                schema.add_relation_def(
                    RelationDefinition(etype,
                                       'container_etype',
                                       'CWEType',
                                       cardinality='?*'))

            # populate container_parent
            eschema = schema[etype]
            if utils.needs_container_parent(eschema):
                cparent_rschema = schema['container_parent']
                # we take a list because iterating over the schema while
                # we're mutating parts of it won't work
                peschemas = list(utils.parent_eschemas(eschema))
                for peschema in peschemas:
                    petype = peschema.type
                    if (etype, petype) in cparent_rschema.rdefs:
                        continue
                    schema.add_relation_def(
                        RelationDefinition(etype,
                                           'container_parent',
                                           petype,
                                           cardinality='?*'))
 def test_needs_container_parent(self):
     schema = self.vreg.schema
     for etype in ('Diamond', 'Left', 'Right', 'Mess'):
         self.assertFalse(utils.needs_container_parent(schema[etype]))
     self.assertTrue(utils.needs_container_parent(schema['Bottom']))