def _extract_resolved_attributes(self, proj_ctx: 'ProjectionContext') -> 'ResolvedAttributeSet': """Create resolved attribute set based on the CurrentResolvedAttribute array""" resolved_attribute_set = ResolvedAttributeSet() resolved_attribute_set.attribute_context = proj_ctx._current_attribute_context for pas in proj_ctx._current_attribute_state_set._states: resolved_attribute_set.merge(pas._current_resolved_attribute, pas._current_resolved_attribute.att_ctx) return resolved_attribute_set
def _extract_resolved_attributes( self, proj_ctx: 'ProjectionContext', att_ctx_under: CdmAttributeContext) -> 'ResolvedAttributeSet': """Create resolved attribute set based on the CurrentResolvedAttribute array""" resolved_attribute_set = ResolvedAttributeSet() resolved_attribute_set.attribute_context = att_ctx_under if not proj_ctx: logger.error(self.ctx, self._TAG, '_extract_resolved_attributes', self.at_corpus_path, CdmLogCode.ERR_PROJ_FAILED_TO_RESOLVE) return resolved_attribute_set for pas in proj_ctx._current_attribute_state_set._states: resolved_attribute_set.merge(pas._current_resolved_attribute) return resolved_attribute_set
def associate_tree_copy_with_attributes(self, res_opt: ResolveOptions, ras: ResolvedAttributeSet) -> bool: # deep copy the tree. while doing this also collect a map from old attCtx to new equivalent # this is where the returned tree fits in cached_ctx = ras.attribute_context if cached_ctx._copy_attribute_context_tree(res_opt, self) is None: return False ras.attribute_context = self # run over the resolved attributes in the copy and use the map to swap the old ctx for the new version def _fix_resolve_attribute_ctx(ras_sub: ResolvedAttributeSet) -> None: for ra in ras_sub._set: ra.att_ctx = res_opt._map_old_ctx_to_new_ctx[ra.att_ctx] # the target for a resolved att can be a typeAttribute OR it can be another resolvedAttributeSet (meaning a group) if isinstance(ra.target, ResolvedAttributeSet): cast(ResolvedAttributeSet, ra.target).attribute_context = ra.att_ctx _fix_resolve_attribute_ctx( cast(ResolvedAttributeSet, ra.target)) _fix_resolve_attribute_ctx(ras) # now fix any lineage references def _fix_att_ctx_node_lineage( ac: CdmAttributeContext, ac_parent: Optional[CdmAttributeContext] = None) -> None: if ac is None: return if ac_parent and ac.parent and ac.parent.explicit_reference: ac.parent.explicit_reference = ac_parent if ac.lineage and len(ac.lineage) > 0: # fix lineage for lin in ac.lineage: if lin.explicit_reference: # swap the actual object for the one in the new tree lin.explicit_reference = res_opt._map_old_ctx_to_new_ctx[ cast(CdmAttributeContext, lin.explicit_reference)] if not ac.contents: return # look at all children for sub_sub in ac.contents: _fix_att_ctx_node_lineage(sub_sub, ac) _fix_att_ctx_node_lineage(self, None) return True
def _fetch_resolved_attributes( self, res_opt: 'ResolveOptions', acp_in_context: Optional['AttributeContextParameters'] = None ) -> 'ResolvedAttributeSet': from cdm.resolvedmodel import ResolvedAttributeSet from cdm.utilities import SymbolSet from .cdm_attribute_context import CdmAttributeContext from .cdm_corpus_def import CdmCorpusDefinition kind = 'rasb' ctx = self.ctx cache_tag = ctx.corpus._fetch_definition_cache_tag( res_opt, self, kind, 'ctx' if acp_in_context else '') rasb_cache = ctx.cache.get(cache_tag) if cache_tag else None under_ctx = None # store the previous symbol set, we will need to add it with # children found from the constructResolvedTraits call curr_sym_ref_set = res_opt.symbol_ref_set or SymbolSet() res_opt.symbol_ref_set = SymbolSet() from_moniker = res_opt._from_moniker res_opt._from_moniker = None if not rasb_cache: if self._resolving_attributes: # re-entered self attribute through some kind of self or looping reference. return ResolvedAttributeSet() self._resolving_attributes = True # if a new context node is needed for these attributes, make it now if acp_in_context: under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) rasb_cache = self._construct_resolved_attributes( res_opt, under_ctx) self._resolving_attributes = False # register set of possible docs odef = self.fetch_object_definition(res_opt) if odef is not None: ctx.corpus._register_definition_reference_symbols( odef, kind, res_opt.symbol_ref_set) # get the new cache tag now that we have the list of symbols cache_tag = ctx.corpus._fetch_definition_cache_tag( res_opt, self, kind, 'ctx' if acp_in_context else '') # save this as the cached version if cache_tag: ctx.cache[cache_tag] = rasb_cache if from_moniker and acp_in_context and cast( 'CdmObjectReference', self).named_reference: # create a fresh context old_context = acp_in_context.under.contents[-1] acp_in_context.under.contents.pop() under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) old_context._copy_attribute_context_tree( res_opt, under_ctx, rasb_cache.ras, None, from_moniker) else: # get the SymbolSet for this cached object and pass that back key = CdmCorpusDefinition._fetch_cache_key_from_object(self, kind) res_opt.symbol_ref_set = ctx.corpus._definition_reference_symbols.get( key) # cache found. if we are building a context, then fix what we got instead of making a new one if acp_in_context: # make the new context under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) rasb_cache.ras.attribute_context._copy_attribute_context_tree( res_opt, under_ctx, rasb_cache.ras, None, from_moniker) # merge child reference symbols set with current curr_sym_ref_set.merge(res_opt.symbol_ref_set) res_opt.symbol_ref_set = curr_sym_ref_set return rasb_cache.ras
def _fetch_resolved_attributes( self, res_opt: 'ResolveOptions', acp_in_context: Optional['AttributeContextParameters'] = None ) -> 'ResolvedAttributeSet': from cdm.resolvedmodel import ResolvedAttributeSet from cdm.utilities import SymbolSet from .cdm_attribute_context import CdmAttributeContext from .cdm_corpus_def import CdmCorpusDefinition was_previously_resolving = self.ctx.corpus._is_currently_resolving self.ctx.corpus._is_currently_resolving = True if not res_opt: res_opt = ResolveOptions(self) kind = 'rasb' ctx = self.ctx cache_tag = ctx.corpus._fetch_definition_cache_tag( res_opt, self, kind, 'ctx' if acp_in_context else '') rasb_cache = ctx._cache.get(cache_tag) if cache_tag else None under_ctx = None # store the previous symbol set, we will need to add it with # children found from the constructResolvedTraits call curr_sym_ref_set = res_opt._symbol_ref_set or SymbolSet() res_opt._symbol_ref_set = SymbolSet() # get the moniker that was found and needs to be appended to all # refs in the children attribute context nodes from_moniker = res_opt._from_moniker res_opt._from_moniker = None if not rasb_cache: if self._resolving_attributes: # re-entered self attribute through some kind of self or looping reference. self.ctx.corpus._is_currently_resolving = was_previously_resolving return ResolvedAttributeSet() self._resolving_attributes = True # if a new context node is needed for these attributes, make it now if acp_in_context: under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) rasb_cache = self._construct_resolved_attributes( res_opt, under_ctx) if rasb_cache: self._resolving_attributes = False # register set of possible docs odef = self.fetch_object_definition(res_opt) if odef is not None: ctx.corpus._register_definition_reference_symbols( odef, kind, res_opt._symbol_ref_set) # get the new cache tag now that we have the list of symbols cache_tag = ctx.corpus._fetch_definition_cache_tag( res_opt, self, kind, 'ctx' if acp_in_context else '') # save this as the cached version if cache_tag: ctx._cache[cache_tag] = rasb_cache if from_moniker and acp_in_context and cast( 'CdmObjectReference', self).named_reference: # create a fresh context old_context = acp_in_context._under.contents[-1] acp_in_context._under.contents.pop( len(acp_in_context._under.contents) - 1) under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) new_context = old_context._copy_attribute_context_tree( res_opt, under_ctx, rasb_cache.ras, None, from_moniker) # since THIS should be a refererence to a thing found in a moniker document, it already has a moniker in the reference # this function just added that same moniker to everything in the sub-tree but now this one symbol has too many # remove one moniker_path_added = from_moniker + '/' if new_context.definition and new_context.definition.named_reference and new_context.definition.named_reference.startswith( moniker_path_added): # slice it off the front new_context.definition.named_reference = new_context.definition.named_reference[ len(moniker_path_added):] else: # get the SymbolSet for this cached object and pass that back key = CdmCorpusDefinition._fetch_cache_key_from_object(self, kind) res_opt._symbol_ref_set = ctx.corpus._definition_reference_symbols.get( key) # cache found. if we are building a context, then fix what we got instead of making a new one if acp_in_context: # make the new context under_ctx = CdmAttributeContext._create_child_under( res_opt, acp_in_context) rasb_cache.ras.attribute_context._copy_attribute_context_tree( res_opt, under_ctx, rasb_cache.ras, None, from_moniker) # merge child reference symbols set with current curr_sym_ref_set._merge(res_opt._symbol_ref_set) res_opt._symbol_ref_set = curr_sym_ref_set self.ctx.corpus._is_currently_resolving = was_previously_resolving return rasb_cache.ras if rasb_cache else rasb_cache