def _construct_attribute_context_tree(
            self,
            proj_ctx: 'ProjectionContext',
            set_attr_ctx: Optional[bool] = False) -> None:
        """
        Takes all the stored attribute context parameters, creates attribute contexts from them, and then constructs the tree.
        :param proj_ctx: The projection context
        :param set_attr_ctx: Whether to set the created attribute context on the associated resolved attribute
        """

        # Iterate over all the search_for attribute context parameters
        for search_for_attr_ctx_param in self._search_for_to_search_for_attr_ctx_param.values(
        ):
            search_for_attr_ctx = None

            # Fetch all the found attribute context parameters associated with this search_for
            found_attr_ctx_params = self._search_for_attr_ctx_param_to_found_attr_ctx_param[
                search_for_attr_ctx_param]

            # Iterate over all the found attribute context parameters
            for found_attr_ctx_param in found_attr_ctx_params:
                # We should only create the search_for node when search_for and found have different names. Else collapse the nodes together.
                if not StringUtils.equals_with_case(
                        search_for_attr_ctx_param._name,
                        found_attr_ctx_param._name):
                    # Create the attribute context for searchFor if it hasn't been created already and set it as the parent of found
                    if search_for_attr_ctx is None:
                        search_for_attr_ctx = CdmAttributeContext._create_child_under(
                            proj_ctx._projection_directive._res_opt,
                            search_for_attr_ctx_param)
                    found_attr_ctx_param._under = search_for_attr_ctx

                # Fetch the action attribute context parameter associated with this found
                action_attr_ctx_param = self._found_attr_ctx_param_to_action_attr_ctx_param[
                    found_attr_ctx_param]

                # We should only create the found node when found and action have different names. Else collapse the nodes together.
                if not StringUtils.equals_with_case(
                        found_attr_ctx_param._name,
                        action_attr_ctx_param._name):
                    # Create the attribute context for found and set it as the parent of action
                    found_attr_ctx = CdmAttributeContext._create_child_under(
                        proj_ctx._projection_directive._res_opt,
                        found_attr_ctx_param)
                    action_attr_ctx_param._under = found_attr_ctx

                # Create the attribute context for action
                action_attr_ctx = CdmAttributeContext._create_child_under(
                    proj_ctx._projection_directive._res_opt,
                    action_attr_ctx_param)

                # Fetch the resolved attribute that should now point at this action attribute context
                res_attr_from_action = self._action_attr_ctx_param_to_res_attr[
                    action_attr_ctx_param]

                # TODO (jibyun): For now, only set the created attribute context on the resolved attribute when specified to,
                # as pointing the resolved attribute at this attribute context won't work currently for certain operations (Include/Exclude).
                # This will be changed to always run once we work on the attribute context fix.
                if set_attr_ctx:
                    res_attr_from_action.att_ctx = action_attr_ctx
예제 #2
0
    def _build_structure(curr: 'ProjectionAttributeState',
                         top: 'ProjectionAttributeState', attr_name: str,
                         st: 'SearchStructure', found_flag: bool,
                         found_depth: int) -> 'SearchStructure':
        """Build a structure using a stack"""
        if curr:
            st._add(curr)

            if StringUtils.equals_with_case(
                    curr._current_resolved_attribute.resolved_name, attr_name):
                found_flag = True
                st._result.found_flag = True
                st._result.found_depth = found_depth
                st._result.found = curr

            if found_flag and (curr and
                               (curr._previous_state_list is None or
                                (curr._previous_state_list is not None
                                 and len(curr._previous_state_list) == 0))):
                st._result.leaf.append(curr)

            if curr._previous_state_list and len(
                    curr._previous_state_list) > 0:
                for prev in curr._previous_state_list:
                    SearchStructure._build_structure(prev, top, attr_name, st,
                                                     found_flag,
                                                     found_depth + 1)

        return st
예제 #3
0
    def _construct_attribute_context_tree(
            self, proj_ctx: 'ProjectionContext') -> None:
        """
        Takes all the stored attribute context parameters, creates attribute contexts from them, and then constructs the tree.
        :param proj_ctx: The projection context
        """

        # Iterate over all the search_for attribute context parameters
        for search_for_attr_ctx_param in self._search_for_to_search_for_attr_ctx_param.values(
        ):
            # Fetch all the found attribute context parameters associated with this search_for
            found_attr_ctx_params = self._search_for_attr_ctx_param_to_found_attr_ctx_param[
                search_for_attr_ctx_param]

            # Iterate over all the found attribute context parameters
            for found_attr_ctx_param in found_attr_ctx_params:
                # Fetch the action attribute context parameter associated with this found
                action_attr_ctx_param = self._found_attr_ctx_param_to_action_attr_ctx_param[
                    found_attr_ctx_param]

                # We should only create the found node when found and action have different names. Else collapse the nodes together.
                if not StringUtils.equals_with_case(
                        found_attr_ctx_param._name,
                        action_attr_ctx_param._name):
                    # Create the attribute context for found and set it as the parent of action
                    found_attr_ctx = CdmAttributeContext._create_child_under(
                        proj_ctx._projection_directive._res_opt,
                        found_attr_ctx_param)
                    action_attr_ctx_param._under = found_attr_ctx

                # Create the attribute context for action
                action_attr_ctx = CdmAttributeContext._create_child_under(
                    proj_ctx._projection_directive._res_opt,
                    action_attr_ctx_param)

                # Fetch the resolved attribute that should now point at this action attribute context
                res_attr_from_action = self._action_attr_ctx_param_to_res_attr.get(
                    action_attr_ctx_param, None)

                # make sure the lineage of the attribute stays linked up
                # there can be either (or both) a lineageOut and a lineageIn.
                # out lineage is where this attribute came from
                # in lineage should be pointing back at this context as a source
                lineage_out = self._action_attr_ctx_param_to_lineage_out.get(
                    action_attr_ctx_param, None)  # type: CdmAttributeContext
                if lineage_out:
                    if action_attr_ctx:
                        action_attr_ctx._add_lineage(lineage_out)
                    res_attr_from_action.att_ctx = action_attr_ctx  # probably the right context for this resAtt, unless ...

                lineage_in = self._action_attr_ctx_param_to_lineage_in.get(
                    action_attr_ctx_param, None)  # type: CdmAttributeContext
                if lineage_in:
                    if action_attr_ctx:
                        lineage_in._add_lineage(action_attr_ctx)
                    res_attr_from_action.att_ctx = lineage_in  # if there is a lineageIn. it points to us as lineage, so it is best