in objectModel/Python/cdm/objectmodel/cdm_attribute_context.py [0:0]
def _finalize_attribute_context(self, res_opt: ResolveOptions, path_start: str, doc_home: CdmDocumentDefinition,
doc_from: CdmDocumentDefinition, moniker_for_doc_from: str, finished: bool):
# run over the attCtx tree again and 'fix it' fix means replace the parent and lineage reference path strings with
# final values from new home and set the inDocument and fix any references to definitions
# keep track of the paths to documents for fixing symbol refs. expensive to compute
found_doc_paths = OrderedDict()
if moniker_for_doc_from and not moniker_for_doc_from.isspace():
moniker_for_doc_from = '{}/'.format(moniker_for_doc_from)
# first step makes sure every node in the tree has a good path for itself and a good document
# second pass uses the paths from nodes to fix references to other nodes
def _fix_att_ctx_node_paths(sub_item: CdmObject, path_from: str) -> None:
ac = cast(CdmAttributeContext, sub_item)
if ac is None:
return
ac.in_document = doc_home
# fix up the reference to definition. need to get path from this document to the
# add moniker if this is a reference
if ac.definition:
ac.definition.in_document = doc_home
if ac.definition and ac.definition.named_reference:
# need the real path to this thing from the explicitRef held in the portable reference
# the real path is {monikerFrom/}{path from 'from' document to document holding the explicit ref/{declaredPath of explicitRef}}
# if we have never looked up the path between docs, do that now
doc_from_def = ac.definition._portable_reference.in_document # if all parts not set, this is a broken portal ref!
path_between_docs = found_doc_paths[doc_from_def] if doc_from_def in found_doc_paths else None
if path_between_docs is None:
path_between_docs = doc_from._import_path_to_doc(doc_from_def)
if path_between_docs is None:
# hmm. hmm.
path_between_docs = ''
found_doc_paths[doc_from] = path_between_docs
cast('CdmObjectReference', ac.definition)._localize_portable_reference('{}{}'.format(moniker_for_doc_from, path_between_docs))
# doc of parent ref
if ac.parent:
ac.parent.in_document = doc_home
# doc of lineage refs
if ac.lineage:
for lin in ac.lineage:
lin.in_document = doc_home
divider = '/' if not ac.at_corpus_path or not path_from.endswith('/') else ''
ac.at_corpus_path = '{}{}{}'.format(path_from, divider, ac.name)
if not ac.contents:
return
# look at all children
for sub_sub in ac.contents:
if sub_sub.object_type == CdmObjectType.ATTRIBUTE_CONTEXT_DEF:
_fix_att_ctx_node_paths(sub_sub, ac.at_corpus_path)
_fix_att_ctx_node_paths(self, path_start)
# now fix any lineage and parent references
def _fix_att_ctx_node_lineage(sub_item) -> None:
ac = cast(CdmAttributeContext, sub_item) # type: CdmAttributeContext
if not ac:
return
# for debugLindeage, write id
# ac.name = '{}({})'.format(ac.name, ac.id)
# parent ref
if ac.parent and ac.parent.explicit_reference:
ac.parent.named_reference = cast(CdmAttributeContext, ac.parent.explicit_reference).at_corpus_path
# for debugLindeage, write id
# ac.parent.named_reference = cast(CdmAttributeContext, ac.parent.explicit_reference).at_corpus_path + '(' + ac.parent.explicit_reference.id + ')'
# fix lineage
if ac.lineage:
for lin in ac.lineage:
if lin.explicit_reference:
# use the new path as the ref
lin.named_reference = cast(CdmAttributeContext, lin.explicit_reference).at_corpus_path
# for debugLindeage, write id
# lin.named_reference = cast(CdmAttributeContext, lin.explicit_reference).at_corpus_path + '(' + lin.explicit_reference.id + ')'
if not ac.contents:
return
# look at all children
for sub_sub in ac.contents:
_fix_att_ctx_node_lineage(sub_sub)
_fix_att_ctx_node_lineage(self)
if finished:
res_opt._save_resolutions_on_copy = False
res_opt._map_old_ctx_to_new_ctx = None
return True