예제 #1
0
    def fetch_resolved_entity_references(self, res_opt: Optional['ResolveOptions'] = None) -> 'ResolvedEntityReferenceSet':
        res_opt = res_opt if res_opt is not None else ResolveOptions(wrt_doc=self)

        from cdm.resolvedmodel import ResolvedEntityReferenceSet

        rers = ResolvedEntityReferenceSet(res_opt)
        for member in self.members:
            rers.add(member.fetch_resolved_entity_references(res_opt))

        return rers
예제 #2
0
    def fetch_resolved_entity_references(
            self, res_opt: 'ResolveOptions') -> 'ResolvedEntityReferenceSet':
        # this whole resolved entity ref goo will go away when resolved documents are done.
        # for now, it breaks if structured att sets get made.
        from cdm.resolvedmodel import ResolvedEntityReferenceSet
        from cdm.utilities import AttributeResolutionDirectiveSet

        from .cdm_object import CdmObject

        was_previously_resolving = self.ctx.corpus._is_currently_resolving
        self.ctx.corpus._is_currently_resolving = True

        if not res_opt:
            res_opt = ResolveOptions(
                self, self.ctx.corpus.default_resolution_directives)

        res_opt = CdmObject._copy_resolve_options(res_opt)
        res_opt.directives = AttributeResolutionDirectiveSet(
            set(['normalized', 'referenceOnly']))

        ctx = self.ctx
        ent_ref_set_cache = ctx.fetch_cache(self, res_opt, 'entRefSet')
        if not ent_ref_set_cache:
            ent_ref_set_cache = ResolvedEntityReferenceSet(res_opt)

            if not self._resolving_entity_references:
                self._resolving_entity_references = True
                # get from any base class and then 'fix' those to point here instead.
                ext_ref = self.extends_entity
                if ext_ref:
                    ext_def = cast('CdmEntityDefinition',
                                   ext_ref.fetch_object_definition(res_opt))
                    if ext_def:
                        inherited = ext_def.fetch_resolved_entity_references(
                            res_opt)
                        if inherited:
                            for res in inherited.rer_set:
                                res = res.copy()
                                res.referencing.entity = self
                                ent_ref_set_cache.rer_set.append(res)
                if self.attributes:
                    for attribute in self.attributes:
                        # if any refs come back from attributes, they don't know who we are, so they don't set the entity
                        sub = attribute.fetch_resolved_entity_references(
                            res_opt)
                        if sub:
                            for res in sub.rer_set:
                                res.referencing.entity = self

                            ent_ref_set_cache.add(sub)
                ctx.update_cache(self, res_opt, 'entRefSet', ent_ref_set_cache)
                self._resolving_entity_references = False

        self.ctx.corpus._is_currently_resolving = was_previously_resolving
        return ent_ref_set_cache
예제 #3
0
    def fetch_resolved_entity_references(
        self,
        res_opt: Optional['ResolveOptions'] = None
    ) -> 'ResolvedEntityReferenceSet':
        res_opt = res_opt if res_opt is not None else ResolveOptions(
            wrt_doc=self)

        from cdm.resolvedmodel import AttributeResolutionContext, ResolvedEntityReference, ResolvedEntityReferenceSide, ResolvedEntityReferenceSet
        from cdm.utilities import ResolveOptions

        from .cdm_object import CdmObject

        rts_this_att = self._fetch_resolved_traits(res_opt)
        res_guide = self.resolution_guidance

        # this context object holds all of the info about what needs to happen to resolve these attributes
        arc = AttributeResolutionContext(res_opt, res_guide, rts_this_att)

        rel_info = self._get_relationship_info(res_opt, arc)
        if not rel_info.is_by_ref or rel_info.is_array:
            return None

        # only place this is used, so logic here instead of encapsulated.
        # make a set and the one ref it will hold
        rers = ResolvedEntityReferenceSet(res_opt)
        rer = ResolvedEntityReference()
        # referencing attribute(s) come from this attribute
        rer.referencing._rasb.merge_attributes(
            self._fetch_resolved_attributes(res_opt))

        def resolve_side(
                ent_ref: 'CdmEntityReference') -> ResolvedEntityReferenceSide:
            side_other = ResolvedEntityReferenceSide()
            if ent_ref:
                # reference to the other entity, hard part is the attribue name.
                # by convention, this is held in a trait that identifies the key
                side_other.entity = ent_ref.fetch_object_definition(res_opt)
                if side_other.entity:
                    other_attribute = None
                    other_opts = ResolveOptions(wrt_doc=res_opt.wrt_doc,
                                                directives=res_opt.directives)
                    trait = ent_ref._fetch_resolved_traits(other_opts).find(
                        other_opts, 'is.identifiedBy')
                    if trait and trait.parameter_values and trait.parameter_values.length:
                        other_ref = trait.parameter_values.fetch_parameter_value(
                            'attribute').value
                        if isinstance(other_ref, CdmObject):
                            other_attribute = other_ref.fetch_object_definition(
                                other_opts)
                            if other_attribute:
                                side_other._rasb.own_one(
                                    side_other.entity.
                                    _fetch_resolved_attributes(other_opts).get(
                                        other_attribute.get_name()).copy())

            return side_other

        # either several or one entity
        # for now, a sub for the 'select one' idea
        if self.entity.explicit_reference:
            ent_pick_from = self.entity.fetch_object_definition(res_opt)
            atts_pick = ent_pick_from.attributes
            if ent_pick_from and atts_pick:
                for attribute in atts_pick:
                    if attribute.object_type == CdmObjectType.ENTITY_ATTRIBUTE_DEF:
                        entity = attribute.entity
                        rer.referenced.append(resolve_side(entity))
        else:
            rer.referenced.append(resolve_side(self.entity))

        rers.rer_set.append(rer)

        return rers