示例#1
0
 def get_exec_order(self, start_path):
     if start_path == nxt_path.WORLD:
         return []
     start_root_path = nxt_path.get_root_path(start_path)
     exec_order = []
     start_found = False
     root_exec_order = self.get_root_exec_order(start_root_path)
     for root_path in root_exec_order:
         if not start_found and root_path == start_path:
             start_found = True
         node = self.lookup(root_path)
         enabled = nxt_node.get_node_enabled(node)
         if enabled is None:
             enabled = True
         if not enabled:
             continue
         if start_found:
             exec_order += [root_path]
         path_rt_type = LayerReturnTypes.Path
         disabled_desc = []
         for desc_path in self.descendants(node_path=root_path,
                                           ordered=True,
                                           return_type=path_rt_type):
             if not start_found and desc_path == start_path:
                 start_found = True
             desc_node = self.lookup(desc_path)
             enabled = nxt_node.get_node_enabled(desc_node)
             if enabled is None:
                 enabled = True
             if enabled:
                 for potential_ancestor in disabled_desc:
                     if nxt_path.is_ancestor(desc_path, potential_ancestor):
                         enabled = False
                         break
             if not enabled:
                 disabled_desc += [desc_path]
                 continue
             if start_found:
                 exec_order += [desc_path]
     return exec_order
示例#2
0
    def children(self,
                 node_path=nxt_path.WORLD,
                 return_type=LayerReturnTypes.Node,
                 ordered=False,
                 include_implied=False):
        if include_implied and return_type != LayerReturnTypes.Path:
            raise ValueError('When including implied, can only return path. '
                             'Nothing else exists for implicit nodes.')
        children_nodes = []
        children_paths = []
        node_table = []
        name_dict = {}
        if not node_path:
            if return_type in (LayerReturnTypes.Node, LayerReturnTypes.Path,
                               LayerReturnTypes.NodeTable):
                return []
            elif return_type == LayerReturnTypes.NameDict:
                return {}
            elif return_type == LayerReturnTypes.Boolean:
                return False
            else:
                logger.error('Invalid return type provided')
                return None
        child_order = []
        implied_children = []
        # Look up real children cache
        children_cache = self._cached_children.get(node_path)
        if node_path == nxt_path.WORLD:
            children_cache = None
        if children_cache is not None:
            children_nodes = children_cache[LayerReturnTypes.Node][:]
            children_paths = children_cache[LayerReturnTypes.Path][:]
            node_table = children_cache[LayerReturnTypes.NodeTable][:]
            name_dict = copy.copy(children_cache[LayerReturnTypes.NameDict])
            cache_real = False
        else:
            self._cached_children[node_path] = {
                LayerReturnTypes.Node: children_nodes,
                LayerReturnTypes.Path: children_paths,
                LayerReturnTypes.NodeTable: node_table,
                LayerReturnTypes.NameDict: name_dict
            }
            cache_real = True
        # Lookup implied cache
        cache_implied = False
        if include_implied:
            implied_c_cache = self._cached_implied_children.get(node_path)
            if node_path == nxt_path.WORLD:
                implied_c_cache = None
            if implied_c_cache is not None:
                implied_children = implied_c_cache[LayerReturnTypes.Path][:]
                if return_type == LayerReturnTypes.Boolean and not cache_real:
                    return bool(implied_children + children_paths)
            else:
                path_implied = {LayerReturnTypes.Path: implied_children}
                self._cached_implied_children[node_path] = path_implied
                cache_implied = True
        re_cache = cache_implied or cache_real
        if re_cache:
            for path, node in self._nodes_path_as_key.items():
                if cache_real:
                    parent_path = getattr(node,
                                          nxt_node.INTERNAL_ATTRS.PARENT_PATH)
                    if parent_path == node_path:
                        children_nodes += [node]
                        children_paths += [path]
                        node_table += [[path, node]]
                        key = getattr(node, nxt_node.INTERNAL_ATTRS.NAME)
                        name_dict[key] = node
                if not include_implied or not cache_implied:
                    continue
                if nxt_path.is_ancestor(path, node_path):
                    trim_depth = nxt_path.get_path_depth(node_path) + 1
                    trimmed = nxt_path.trim_to_depth(path, trim_depth)
                    if trimmed not in implied_children:
                        implied_children += [trimmed]
        if cache_real:
            k = LayerReturnTypes.Path
            self._cached_children[node_path][k] = children_paths[:]
        if include_implied:
            for imp in implied_children:
                if imp not in children_paths:
                    children_paths += [imp]
        if return_type == LayerReturnTypes.Boolean:
            return bool(children_paths)
        if ordered:
            node = self.lookup(node_path)
            if include_implied and not node:
                child_order = []
            else:
                co_attr = nxt_node.INTERNAL_ATTRS.CHILD_ORDER
                child_order = getattr(node, co_attr)
        if child_order:
            ordered_child_nodes = []
            ordered_child_paths = []
            ordered_node_table = []
            for child_name in child_order:
                # return type NODE
                for n in children_nodes:
                    c_name = getattr(n, nxt_node.INTERNAL_ATTRS.NAME)
                    if c_name == child_name:
                        ordered_child_nodes += [n]
                # return type PATH
                for p in children_paths:
                    if nxt_path.node_name_from_node_path(p) == child_name:
                        ordered_child_paths += [p]
                # return type TABLE
                for item in node_table:
                    p, n = item
                    if nxt_path.node_name_from_node_path(p) == child_name:
                        ordered_node_table += [item]
            # return type NODE
            for n in children_nodes:
                if n not in ordered_child_nodes:
                    ordered_child_nodes += [n]
            children_nodes = ordered_child_nodes
            # return type PATH
            for p in children_paths:
                if p not in ordered_child_paths:
                    ordered_child_paths += [p]
            children_paths = ordered_child_paths
            # return type TABLE
            for item in node_table:
                p, n = item
                if p not in ordered_node_table:
                    ordered_node_table += [item]
            node_table = ordered_node_table

        if return_type == LayerReturnTypes.Node:
            return children_nodes
        elif return_type == LayerReturnTypes.Path:
            return children_paths
        elif return_type == LayerReturnTypes.NodeTable:
            return node_table
        elif return_type == LayerReturnTypes.NameDict:
            return name_dict
        elif return_type == LayerReturnTypes.Boolean:
            return False
        else:
            logger.error('Invalid return type provided')
            return None