child = node_maker.make_node_from_serialized(child_data)
self.children[name] = child
+ def is_leaf_subtree(self):
+ return False
class _DirectorySubTree(object):
def set_base_data(self, data):
self.filename = data
+ def is_leaf_subtree(self):
+ return False
+
class LocalFileSubTree(_DirectorySubTree):
node_class = LocalFileSubTreeNode
def get_uri(self):
return self.uri
+ def is_leaf_subtree(self):
+ return False
+
class CHKDirectorySubTree(_DirectorySubTree):
# maybe mutable, maybe not
def set_write_capability(self, write_cap):
self.write_cap = write_cap
+ def is_leaf_subtree(self):
+ return False
+
class SSKDirectorySubTree(_DirectorySubTree):
node_class = SSKDirectorySubTreeNode
def get_uri(self):
return self.uri
+ def is_leaf_subtree(self):
+ return True
+
class SSKFileNode(object):
implements(INode, IFileNode)
prefix = "SSKFile"
def get_write_capability(self):
return self.write_cap
+ def is_leaf_subtree(self):
+ return True
+
provides that same make_node_from_serialized function to create any
internal child nodes that might be necessary."""
+ def is_leaf_subtree():
+ """Return True if this node does not refer to a traversable
+ subtree. When searching for the node that describes a path, the
+ search will stop at the first leaf node found. IFileNodes should
+ return True here.
+ """
+# TODO: there is a slightly confusing mixture of IDirectoryNodes and all
+# other kinds of nodes. It is convenient to mix them because that way list()
+# can point at nodes of all sorts, but IDirectoryNodes are very different
+# than the rest (because they to not represent distinct subtrees). There
+# might be a better way to factor this.
+
+# TODO: 'node' is a problematic term here. It refers to nodes in the graph of
+# connected subtrees. It also refers to nodes in the graph of directories and
+# links within a single subtree. And the interface named INode is
+# unfortunately a homonym with "inode", the data structure we previously used
+# to represent information about an uploaded file which was too large to keep
+# locally (the list of blockids), which meant the inode itself was uploaded.
+# We no longer use inodes, but using a word that sounds just like it may
+# cause confusion.
+
class IFileNode(Interface):
"""This is a file which can be retrieved."""
# TODO: not sure which of these to provide.. should URIs contain "CHK" or
def set_base_data(self, data):
self.handle = data
+ def is_leaf_subtree(self):
+ return False
+
class _BaseRedirection(object):
implements(ISubTree)
def set_base_data(self, data):
self.url = data
+ def is_leaf_subtree(self):
+ return False
+
class HTTPRedirection(_BaseRedirection):
node_class = HTTPRedirectionNode
def _get_closest_node_1(self, subtree, path):
(found_path, node, remaining_path) = subtree.get_node_for_path(path)
parent_is_mutable = subtree.is_mutable()
- if IDirectoryNode.providedBy(node):
+ if IDirectoryNode.providedBy(node) or node.is_leaf_subtree():
# traversal done
return (node, remaining_path)
# otherwise, we must open and recurse into a new subtree
{"c": child2, "d": child3})
d.addCallback(_listed4)
- #d.addCallback(lambda res: v._get_file_uri(["b","c"]))
- #d.addCallback(self.failUnlessEqual, "uri2")
+ d.addCallback(lambda res: v._get_file_uri(["b","c"]))
+ d.addCallback(self.failUnlessEqual, "uri2")
d.addCallback(lambda res: v.list(["bogus"]))
def _listed_bogus(res):