class _DerivedTestItemVisitor(_TestItemVisitor, object): def test1Overridden(self, _): return False test1 = VisitSlot((test1Overridden, (SimpleMock, )), inherits="test1") def test2Hidden(self, node, para): return node.value == para test2 = VisitSlot((test2Hidden, [_TestItem]))
class _TestItemVisitor(object): """ Mock visitor to test L{ItemVisitorBase<datafinder.core.item.visitor.base.ItemVisitorBase>}. Two visit slots are defined: C{test1} and C{test2} both of which only have a valid implementation for L{SimpleMock<datafinder_test.mocks.SimpleMock>}. """ def test1ReturnsNodeValue(self, node): """ Visitor slot implementation for C{SimpleMock}. @param node: The visited node. @type node: C{SimpleMock} @return: The value of the node (C{node.value}). """ return node.value def test1ReturnsFalse(self, _): """ Visitor slot implementation for C{_FailTestItem}. @param node: The visited node. @type node: C{SimpleMock} @return: C{False} """ return False test1 = VisitSlot((test1ReturnsNodeValue, [SimpleMock]), (test1ReturnsFalse, [_TestItem])) def test2ChecksNodeValueForPara(self, node, para): """ Visitor slot implementation for C{SimpleMock} with extra parameter which is compared to the mocks value. @param node: The visited node. @type node: C{SimpleMock} @param para: A parameter to be passed. @type para: Boolean @return: Returns whether the node value (C{node.value}) equals the given parameter. @rtype: Boolean """ return node.value == para test2 = VisitSlot((test2ChecksNodeValueForPara, [SimpleMock]))
class _TestItemTreeWalker(ItemTreeWalkerBase): """ Mock tree walker class to test L{ItemTreeWalkerBase<datafinder.core.item.visitor.base.ItemTreeWalkerBase>}. """ def __init__(self, mode=-1): """ Constructor. """ ItemTreeWalkerBase.__init__(self, mode=mode) self.sequence = list() def reset(self): """ Reset the list of walked items. """ self.sequence = list() def handleData(self, node): """ Visitor slot C{handle} for all nodes expect links. """ self.sequence.append(node.name) def handleLink(self, node): """ Visitor slot C{handle} for link nodes. @return: False """ self.sequence.append("*" + node.name) handle = VisitSlot( (handleData, [ItemBase, ItemRoot, ItemCollection, ItemLeaf]), (handleLink, [ItemLink]))
def testExceptions(self): """ Check whether exceptions are raised just as expected. """ self.assertRaises(ValueError, _EmptyItemTreeWalker, mode=0) walker = _EmptyItemTreeWalker() self.assertRaises(AttributeError, walker.walk, self.testRoot) # No handler slot _EmptyItemTreeWalker.handle = VisitSlot(inherits="handle") self.assertRaises(AttributeError, walker.walk, self.testRoot) # No slot for type
class ItemTreeWalker(ItemTreeWalkerBase, object): """ This class uses the L{ItemTreeWalkerBase<datafinder.core.item.visitor.base.ItemTreeWalkerBase>} protocol to implement a recursive walk algorithm. """ def __init__(self, stopTraversalStates=None, stopProcessStates=None, defaultProperties=None): """ Constructor. Cares for switching to pre-order mode. @param stopTraversalStates: List of states that are used to prevent traversal of specific collections. Default: C{None} @type stopTraversalStates: C{list} of C{unicode} @param stopProcessStates: List of states that are used to prevent processing a specific items. Default: C{None} @type stopProcessStates: C{list} of C{unicode} @param defaultProperties: Optional list of properties which are set for every item. Default: C{None} @type defaultProperties: C{list} of L{Property<datafinder.core.item.property.Property>} """ super(ItemTreeWalker, self).__init__(-1, stopTraversalStates, stopProcessStates) self._defaultProperties = defaultProperties self.__items = list() def walk(self, node): """ @see: L{walk<datafinder.core.item.visitor.base.ItemTreeWalkerBase.walk>} method to add further post-processing. """ super(ItemTreeWalker, self).walk(node) return self.__items def _handle(self, item): """ Generic handle method. """ if not self._defaultProperties is None: item.updateProperties(self._defaultProperties) self.__items.append(item) handle = VisitSlot( (_handle, [ItemCollection, ItemLink, ItemRoot, ItemLeaf]))
properties.append( Property(dataFormatPropertyDefinition, leaf.dataFormat.name)) if not self._determinePropertiesCallback is None: properties.extend(self._determinePropertiesCallback(leaf)) if not self._defaultProperties is None: properties.extend(self._defaultProperties) return properties def _importCollection(self, collection): """ Retrieves the content of a collection. """ importName = self._determineImportName(collection) importedCollection = self._itemFactory.createCollection( importName, self._pwd) properties = collection.properties.values()[:] if not self._determinePropertiesCallback is None: properties.extend(self._determinePropertiesCallback(collection)) if not self._defaultProperties is None: properties.extend(self._defaultProperties) try: importedCollection.create(properties) except CoreError, error: importedCollection.invalidate() raise error self._pwd = importedCollection handle = VisitSlot((_importLink, [ItemLink]), (_importLeaf, [ItemLeaf]), (_importCollection, [ItemCollection]), (lambda self, _: None, [ItemRoot]))
class ActionCheckTreeWalker(ItemTreeWalkerBase, ActionCheckVisitor): """ This class does essentially the same as L{ActionCheckVisitor<datafinder.core.item.visitor.checks.ActionCheckVisitor>} but extends the checks to any children of the item due to its nature as tree walker. @ivar handle: Visitor slot that does the actual handling. @type handle: C{VisitSlot} """ def __init__(self, resolveLinks=False, hasCustomMetadataSupport=False, hasSearchSupport=False): """ Constructor. @param resolveLinks: Select whether links should be resolved or not. @type resolveLinks: boolean """ ActionCheckVisitor.__init__(self, resolveLinks, hasCustomMetadataSupport, hasSearchSupport) ItemTreeWalkerBase.__init__(self, mode=-1) # enforce pre-order scheme self.affectedItems = list() self._path = list() def check(self, item): """ Run checks. This method cares for resetting the capabilities dictionary first. It then starts walking the tree and updates the capabilities for each node it hits. @param item: The item to be checked @type item: L{ItemBase<datafinder.core.item.base.ItemBase>} """ self._initCapabilities() if not item.ignoreChecks: self.affectedItems = list() self.walk(item) self.affectedItems.remove(item) def walk(self, node): """ Re-implementation of the C{walk} slot for any item. Simply cares for appending current node to the list of affected items and calling the base implementation of this slot. """ if node.state in [ constants.ITEM_STATE_ARCHIVED, constants.ITEM_STATE_ARCHIVED_READONLY ]: currentCapabilities = self.capabilities.copy( ) #ignoring capabilities of archive members self.affectedItems.append(node) super(ActionCheckTreeWalker, self).walk(node) if node.state in [ constants.ITEM_STATE_ARCHIVED, constants.ITEM_STATE_ARCHIVED_READONLY ]: self.capabilities = currentCapabilities self.handle(node) def handleLink(self, item): """ Implementation of the C{handle} slot for L{ItemLink<datafinder.core.item.link.ItemLink>}. """ if self.resolveLinks and item.name not in self._path: self._path.append(item.name) item = item.linkTarget self.walk(item) self._path = self._path[:-1] handle = VisitSlot((handleLink, [ItemLink]), inherits="handle")
self.handle(item) else: self._checkPrivileges(item) self._checkDataState(item) def handleBase(self, item): """ Implementation of the C{handle} slot for L{ItemBase<datafinder.core.item.base.ItemBase>}. """ if item.isLink: self.handleLink(item) else: self.handleDataNode(item) handle = VisitSlot((handleDataNode, [ItemRoot, ItemCollection, ItemLeaf]), (handleLink, [ItemLink]), (handleBase, [ItemBase])) def canAddChildren(self, item): """ Convenience method to check whether an item can be created below. @note: The sanity checks are run again when this method is called. @param item: The item to be checked. @type item: L{ItemBase<datafinder.core.item.base.ItemBase>} """ self.check(item) return self.capabilities[ActionCheckVisitor.CAPABILITY_ADD_CHILDREN] def canDelete(self, item):