コード例 #1
0
    def readItem(self, view, afterLoadHooks):

        status = self.status
        withSchema = (status & Item.CORESCHEMA) != 0
        isContainer = (status & Item.CONTAINER) != 0

        status &= Item.CORESCHEMA
        kind = self._kind(self.uKind, withSchema, view, afterLoadHooks)
        parent = self._parent(self.uParent, withSchema, view, afterLoadHooks)
        cls = self._class(self.moduleName, self.className, withSchema, kind,
                          view, afterLoadHooks)

        values = Values(None)
        references = References(None)

        self._values(values, references, self.uValues, kind, withSchema, view,
                     afterLoadHooks)

        instance = view._reuseItemInstance(self.uItem)
        if instance is not None:
            if cls is not type(instance):
                instance.__class__ = cls
            item = self.item = instance
            status |= item._status & item.PINNED
        else:
            item = self.item = cls.__new__(cls)

        item._fillItem(self.name,
                       parent,
                       kind,
                       uuid=self.uItem,
                       values=values,
                       references=references,
                       afterLoadHooks=afterLoadHooks,
                       version=self.version,
                       status=status,
                       update=False)

        if isContainer:
            item._children = view._createChildren(item, False)

        values._setItem(item)
        references._setItem(item)

        for name, value in values.iteritems():
            if isinstance(value, ItemValue):
                value._setOwner(item, name)

        if kind is not None:
            afterLoadHooks.append(lambda view: kind._setupClass(cls))

        if hasattr(cls, 'onItemLoad'):
            afterLoadHooks.append(item.onItemLoad)

        return item
コード例 #2
0
    def instantiateItem(self, name, parent, uuid,
                        cls=None, version=0, withInitialValues=False):
        """
        Instantiate an existing item of this kind.

        This method is intended to help in instantiating an existing item,
        that is an item in this or another repository for which there
        already exists a UUID.

        The item's constructor is not invoked, the item's onItemLoad
        method is invoked if defined.

        @param name: The name of the item. It must be unique among the names
        this item's siblings. C{name} may be C{None}.
        @type name: a string or C{None} to create an anonymous item.
        @param parent: The parent of this item. All items require a parent
        unless they are a repository root in which case C{parent} is a
        repository view.
        @type parent: an item or the item's repository view
        @param uuid: The uuid for the item.
        @type uuid: L{UUID<chandlerdb.util.uuid.UUID>}
        @param cls: an optional python class to instantiate the item with,
        defaults to the class set on this kind.
        @type cls: a python new style class, that is, a type instance
        @param version: the optional version of this item instance, zero by
        default.
        @type version: integer
        @param withInitialValues: optionally set the initial values for
        attributes as specified in this Kind's attribute definitions.
        @type withInitialValues: boolean
        """

        if cls is None:
            cls = self.getItemClass()

        values = Values(None)
        references = References(None)

        item = cls.__new__(cls)
        item._fillItem(name, parent, self,
                       uuid=uuid, version=version,
                       values=values, references=references)

        values._setItem(item)
        references._setItem(item)
        self._setupClass(cls)

        if withInitialValues:
            self.getInitialValues(item, values, references)

        if hasattr(cls, 'onItemLoad'):
            item.onItemLoad(self.itsView)

        return item
コード例 #3
0
ファイル: DBItemIO.py プロジェクト: HackLinux/chandler-1
    def readItem(self, view, afterLoadHooks):

        status = self.status
        withSchema = (status & Item.CORESCHEMA) != 0
        isContainer = (status & Item.CONTAINER) != 0

        status &= Item.CORESCHEMA
        kind = self._kind(self.uKind, withSchema, view, afterLoadHooks)
        parent = self._parent(self.uParent, withSchema, view, afterLoadHooks)
        cls = self._class(self.moduleName, self.className, withSchema, kind,
                          view, afterLoadHooks)

        values = Values(None)
        references = References(None)

        self._values(values, references, self.uValues, kind,
                     withSchema, view, afterLoadHooks)

        instance = view._reuseItemInstance(self.uItem)
        if instance is not None:
            if cls is not type(instance):
                instance.__class__ = cls
            item = self.item = instance
            status |= item._status & item.PINNED
        else:
            item = self.item = cls.__new__(cls)

        item._fillItem(self.name, parent, kind,
                       uuid=self.uItem,
                       values=values,
                       references=references,
                       afterLoadHooks=afterLoadHooks,
                       version=self.version,
                       status=status,
                       update=False)

        if isContainer:
            item._children = view._createChildren(item, False)
            
        values._setItem(item)
        references._setItem(item)

        for name, value in values.iteritems():
            if isinstance(value, ItemValue):
                value._setOwner(item, name)

        if kind is not None:
            afterLoadHooks.append(lambda view: kind._setupClass(cls))

        if hasattr(cls, 'onItemLoad'):
            afterLoadHooks.append(item.onItemLoad)

        return item
コード例 #4
0
    def itemStart(self, itemHandler, attrs):

        super(ItemHandler, self).itemStart(itemHandler, attrs)

        if self.values is None:
            self.values = Values(None)
        if self.references is None:
            self.references = References(None)

        self.refs = []
        self.name = None
        self.cls = None
        self.parentRef = None
        self.isContainer = False
        self.uuid = UUID(attrs.get('uuid'))
        self.version = int(attrs.get('version', '0'))
        self.update = update = attrs.get('update')
        self.delete = delete = attrs.get('delete')

        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item

        if update is not None:
            item = _find(update)
        elif delete is not None:
            item = _find(delete)
        else:
            item = None

        if item is not None:
            self.item = item
            self.cls = type(item)
            self.version = item._version
            self.name = item.itsName
            self.kind = item.itsKind
            self.uuid = item.itsUUID
            self.parent = item.itsParent
コード例 #5
0
ファイル: ItemHandler.py プロジェクト: HackLinux/chandler-1
    def itemStart(self, itemHandler, attrs):

        super(ItemHandler, self).itemStart(itemHandler, attrs)

        if self.values is None:
            self.values = Values(None)
        if self.references is None:
            self.references = References(None)

        self.refs = []
        self.name = None
        self.cls = None
        self.parentRef = None
        self.isContainer = False
        self.uuid = UUID(attrs.get('uuid'))
        self.version = int(attrs.get('version', '0'))
        self.update = update = attrs.get('update')
        self.delete = delete = attrs.get('delete')

        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item

        if update is not None:
            item = _find(update)
        elif delete is not None:
            item = _find(delete)
        else:
            item = None

        if item is not None:
            self.item = item
            self.cls = type(item)
            self.version = item._version
            self.name = item.itsName
            self.kind = item.itsKind
            self.uuid = item.itsUUID
            self.parent = item.itsParent
コード例 #6
0
ファイル: ItemHandler.py プロジェクト: HackLinux/chandler-1
class ItemHandler(ValueHandler):
    """
    A SAX ContentHandler implementation responsible for loading items.
    """
    
    def __init__(self, repository, parent, afterLoadHooks, new):

        super(ItemHandler, self).__init__(repository)

        self.loading = repository.isLoading()
        self.parent = parent
        self.afterLoadHooks = afterLoadHooks
        self.item = None
        self.new = new
        self.values = None
        self.references = None
        
    def refStart(self, itemHandler, attrs):

        if self.tags[-1] == 'item':
            name = attrs['name']
            attribute = self.getAttribute(name)
            self.attributes.append(attribute)

            flags = attrs.get('flags', None)
            if flags is not None:
                flags = int(flags)
                self.references._setFlags(name, flags)
                readOnly = flags & Values.READONLY
            else:
                readOnly = False

            cardinality = self.getCardinality(attribute, attrs)
            if cardinality != 'single':
                if cardinality == 'dict':
                    self.repository.logger.warning("Warning, 'dict' cardinality for reference attribute %s on %s is deprecated, use 'list' instead", name, self.name or self.uuid)
                self._setupRefList(name, attribute, readOnly, attrs)

    def _setupRefList(self, name, attribute, readOnly, attrs):

        refList = None
        otherName = self.getOtherName(name, attribute, attrs)

        if 'uuid' in attrs:
            uuid = UUID(attrs['uuid'])
        else:
            uuid = None

        if self.update and attrs.get('operation') == 'append':
            refList = self.item._references.get(name)

        if refList is None:
            refList = self.repository._createRefList(None, name, otherName,
                                                     True, readOnly, self.new,
                                                     uuid)
                
        self.collections.append(refList)

    def itemStart(self, itemHandler, attrs):

        super(ItemHandler, self).itemStart(itemHandler, attrs)

        if self.values is None:
            self.values = Values(None)
        if self.references is None:
            self.references = References(None)

        self.refs = []
        self.name = None
        self.cls = None
        self.parentRef = None
        self.isContainer = False
        self.uuid = UUID(attrs.get('uuid'))
        self.version = int(attrs.get('version', '0'))
        self.update = update = attrs.get('update')
        self.delete = delete = attrs.get('delete')

        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item

        if update is not None:
            item = _find(update)
        elif delete is not None:
            item = _find(delete)
        else:
            item = None

        if item is not None:
            self.item = item
            self.cls = type(item)
            self.version = item._version
            self.name = item.itsName
            self.kind = item.itsKind
            self.uuid = item.itsUUID
            self.parent = item.itsParent

    def itemEnd(self, itemHandler, attrs):

        from repository.item.Item import Item
        
        if self.withSchema:
            status = Item.CORESCHEMA
        else:
            status = 0

        cls = self.cls
        if cls is None:
            if self.kind is None:
                cls = Item
            else:
                cls = self.kind.getItemClass()

        instance = self.repository._reuseItemInstance(self.uuid)
        if instance is not None:
            if cls is not type(instance):
                raise TypeError, 'Class for item has changed from %s to %s' %(type(instance), cls)
            item = self.item = instance
            status |= item._status & item.PINNED
            instance = None

        elif self.update or self.delete:
            item = self.item
            values = item._values
            references = item._references

            for name, value in self.values.iteritems():
                values[name] = value
                item.setDirty(Item.VDIRTY, name, values, noMonitors=True)
            self.values = values

            for name, value in self.references.iteritems():
                if not isinstance(value, dict):
                    dirty = Item.VDIRTY
                    item.setAttributeValue(name, value, references,
                                           None, False)
                else:
                    dirty = Item.RDIRTY
                    references[name] = value
                item.setDirty(dirty, name, references, noMonitors=True)
            self.references = references

            status = item._status | Item.NDIRTY

        else:
            item = self.item = cls.__new__(cls)

        item._fillItem(self.name, self.parent, self.kind, uuid = self.uuid,
                       values = self.values, references = self.references,
                       afterLoadHooks = self.afterLoadHooks,
                       version = self.version, status = status,
                       update = self.update)

        if self.isContainer and item._children is None:
            item._children = self.repository._createChildren(item, self.new)

        if not (self.update or self.delete):
            self.repository._registerItem(item)
            self.values._setItem(item)
            self.references._setItem(item)

        for attribute, value in self.values.iteritems():
            if isinstance(value, ItemValue):
                value._setOwner(item, attribute)

        for refArgs in self.refs:
            other = refArgs._setItem(item)
            if self.loading:
                refArgs._setRef()
            elif other is None:
                self.afterLoadHooks.append(refArgs._setValue)
            else:
                refArgs._setValue(self.repository)

        self.afterLoadHooks.append(self.setupClass)
        if hasattr(cls, 'onItemLoad'):
            self.afterLoadHooks.append(item.onItemLoad)
        if self.delete:
            self.afterLoadHooks.append(item.delete)

    def setupClass(self, view):

        if self.update and isinstance(self.item, Kind):
            self.item.flushCaches('attributes', True)
        elif self.kind is not None:
            self.kind._setupClass(type(self.item))

    def kindEnd(self, itemHandler, attrs):

        assert not self.item

        super(ItemHandler, self).kindEnd(itemHandler, attrs)
        if self.kind is None:
            if self.withSchema:
                self.afterLoadHooks.append(self._setKind)
            else:
                raise ValueError, "While loading %s, kind %s not found" %(self.name or self.uuid, self.kindRef)

    def _setKind(self, view):

        if self.item._kind is None:
            self.kind = view.find(self.kindRef)
            if self.kind is None:
                raise ValueError, 'Kind %s not found' %(self.kindRef)
            else:
                self.item._kind = self.kind

    def parentEnd(self, itemHandler, attrs):

        if attrs['type'] == 'uuid':
            self.parentRef = UUID(self.data)
        else:
            self.parentRef = Path(self.data)

        self.isContainer = attrs.get('container', 'False') == 'True'
        self.parent = self.repository.find(self.parentRef)

        if self.parent is None:
            self.afterLoadHooks.append(self._move)

    def _move(self, view):

        if self.item._parent is None:
            self.parent = view.find(self.parentRef)
            if self.parent is None:
                raise ValueError, 'Parent %s not found' %(self.parentRef)
            else:
                self.item.move(self.parent)

    def classEnd(self, itemHandler, attrs):

        self.cls = ClassLoader.loadClass(self.data, attrs['module'])

    def nameEnd(self, itemHandler, attrs):

        self.name = self.data

    def refEnd(self, itemHandler, attrs):

        if self.tags[-1] == 'item':
            attribute = self.attributes.pop()
            cardinality = self.getCardinality(attribute, attrs)
            otherCard = attrs.get('otherCard', None)
            
        else:
            cardinality = 'single'
            otherCard = self.tagAttrs[-1].get('otherCard', None)

        if cardinality == 'single':     # cardinality of tag
            typeName = attrs.get('type', 'path')

            if typeName == 'path':
                ref = Path(self.data)
            elif typeName == 'none':
                self.references[attrs['name']] = None
                return
            else:
                ref = UUID(self.data)

            if self.collections:
                refList = self.collections[-1]
                self.refs.append(RefArgs(refList._name, None,
                                         refList._otherName, ref,
                                         otherCard=otherCard,
                                         otherAlias=attrs.get('otherAlias'),
                                         previous=self.refName(attrs, 'previous'),
                                         next=self.refName(attrs, 'next'),
                                         alias=attrs.get('alias')))
            else:
                name = attrs['name']
                otherName = self.getOtherName(name, self.getAttribute(name),
                                              attrs)
                self.refs.append(RefArgs(name, None, otherName, ref,
                                         otherCard=otherCard,
                                         otherAlias=attrs.get('otherAlias')))
        else:
            value = self.collections.pop()
            self.references[attrs['name']] = value
            if value._indexes:
                self.afterLoadHooks.append(value._restoreIndexes)

    def indexEnd(self, itemHandler, attrs):

        if not self.collections:
            raise ValueError, self.tagAttrs[-1]['name']

        refList = self.collections[-1]
        kwds = attrs.copy()
        del kwds['type']
        del kwds['name']
        refList.addIndex(attrs['name'], attrs['type'], **kwds)

    def refName(self, attrs, attr):

        try:
            return self.makeValue(attrs.get(attr + 'Type', 'str'), attrs[attr])
        except KeyError:
            return None

    def getOtherName(self, name, attribute, attrs):

        otherName = attrs.get('otherName')

        if otherName is None and attribute is not None:
            otherName = self.kind.getOtherName(name, None, None, None)

        if otherName is None:
            raise TypeError, 'Undefined other endpoint for %s.%s of kind %s' %(self.name or self.uuid, name, self.kind.itsPath)

        return otherName
コード例 #7
0
class ItemHandler(ValueHandler):
    """
    A SAX ContentHandler implementation responsible for loading items.
    """
    def __init__(self, repository, parent, afterLoadHooks, new):

        super(ItemHandler, self).__init__(repository)

        self.loading = repository.isLoading()
        self.parent = parent
        self.afterLoadHooks = afterLoadHooks
        self.item = None
        self.new = new
        self.values = None
        self.references = None

    def refStart(self, itemHandler, attrs):

        if self.tags[-1] == 'item':
            name = attrs['name']
            attribute = self.getAttribute(name)
            self.attributes.append(attribute)

            flags = attrs.get('flags', None)
            if flags is not None:
                flags = int(flags)
                self.references._setFlags(name, flags)
                readOnly = flags & Values.READONLY
            else:
                readOnly = False

            cardinality = self.getCardinality(attribute, attrs)
            if cardinality != 'single':
                if cardinality == 'dict':
                    self.repository.logger.warning(
                        "Warning, 'dict' cardinality for reference attribute %s on %s is deprecated, use 'list' instead",
                        name, self.name or self.uuid)
                self._setupRefList(name, attribute, readOnly, attrs)

    def _setupRefList(self, name, attribute, readOnly, attrs):

        refList = None
        otherName = self.getOtherName(name, attribute, attrs)

        if 'uuid' in attrs:
            uuid = UUID(attrs['uuid'])
        else:
            uuid = None

        if self.update and attrs.get('operation') == 'append':
            refList = self.item._references.get(name)

        if refList is None:
            refList = self.repository._createRefList(None, name, otherName,
                                                     True, readOnly, self.new,
                                                     uuid)

        self.collections.append(refList)

    def itemStart(self, itemHandler, attrs):

        super(ItemHandler, self).itemStart(itemHandler, attrs)

        if self.values is None:
            self.values = Values(None)
        if self.references is None:
            self.references = References(None)

        self.refs = []
        self.name = None
        self.cls = None
        self.parentRef = None
        self.isContainer = False
        self.uuid = UUID(attrs.get('uuid'))
        self.version = int(attrs.get('version', '0'))
        self.update = update = attrs.get('update')
        self.delete = delete = attrs.get('delete')

        def _find(spec):

            typeAttr = attrs.get('type', 'path')
            if typeAttr == 'path':
                item = self.parent.find(Path(spec))
            elif typeAttr == 'uuid':
                item = self.parent.find(UUID(spec))
            else:
                raise TypeError, typeAttr

            if item is None:
                raise NoSuchItemError, (spec, self.version)

            return item

        if update is not None:
            item = _find(update)
        elif delete is not None:
            item = _find(delete)
        else:
            item = None

        if item is not None:
            self.item = item
            self.cls = type(item)
            self.version = item._version
            self.name = item.itsName
            self.kind = item.itsKind
            self.uuid = item.itsUUID
            self.parent = item.itsParent

    def itemEnd(self, itemHandler, attrs):

        from repository.item.Item import Item

        if self.withSchema:
            status = Item.CORESCHEMA
        else:
            status = 0

        cls = self.cls
        if cls is None:
            if self.kind is None:
                cls = Item
            else:
                cls = self.kind.getItemClass()

        instance = self.repository._reuseItemInstance(self.uuid)
        if instance is not None:
            if cls is not type(instance):
                raise TypeError, 'Class for item has changed from %s to %s' % (
                    type(instance), cls)
            item = self.item = instance
            status |= item._status & item.PINNED
            instance = None

        elif self.update or self.delete:
            item = self.item
            values = item._values
            references = item._references

            for name, value in self.values.iteritems():
                values[name] = value
                item.setDirty(Item.VDIRTY, name, values, noMonitors=True)
            self.values = values

            for name, value in self.references.iteritems():
                if not isinstance(value, dict):
                    dirty = Item.VDIRTY
                    item.setAttributeValue(name, value, references, None,
                                           False)
                else:
                    dirty = Item.RDIRTY
                    references[name] = value
                item.setDirty(dirty, name, references, noMonitors=True)
            self.references = references

            status = item._status | Item.NDIRTY

        else:
            item = self.item = cls.__new__(cls)

        item._fillItem(self.name,
                       self.parent,
                       self.kind,
                       uuid=self.uuid,
                       values=self.values,
                       references=self.references,
                       afterLoadHooks=self.afterLoadHooks,
                       version=self.version,
                       status=status,
                       update=self.update)

        if self.isContainer and item._children is None:
            item._children = self.repository._createChildren(item, self.new)

        if not (self.update or self.delete):
            self.repository._registerItem(item)
            self.values._setItem(item)
            self.references._setItem(item)

        for attribute, value in self.values.iteritems():
            if isinstance(value, ItemValue):
                value._setOwner(item, attribute)

        for refArgs in self.refs:
            other = refArgs._setItem(item)
            if self.loading:
                refArgs._setRef()
            elif other is None:
                self.afterLoadHooks.append(refArgs._setValue)
            else:
                refArgs._setValue(self.repository)

        self.afterLoadHooks.append(self.setupClass)
        if hasattr(cls, 'onItemLoad'):
            self.afterLoadHooks.append(item.onItemLoad)
        if self.delete:
            self.afterLoadHooks.append(item.delete)

    def setupClass(self, view):

        if self.update and isinstance(self.item, Kind):
            self.item.flushCaches('attributes', True)
        elif self.kind is not None:
            self.kind._setupClass(type(self.item))

    def kindEnd(self, itemHandler, attrs):

        assert not self.item

        super(ItemHandler, self).kindEnd(itemHandler, attrs)
        if self.kind is None:
            if self.withSchema:
                self.afterLoadHooks.append(self._setKind)
            else:
                raise ValueError, "While loading %s, kind %s not found" % (
                    self.name or self.uuid, self.kindRef)

    def _setKind(self, view):

        if self.item._kind is None:
            self.kind = view.find(self.kindRef)
            if self.kind is None:
                raise ValueError, 'Kind %s not found' % (self.kindRef)
            else:
                self.item._kind = self.kind

    def parentEnd(self, itemHandler, attrs):

        if attrs['type'] == 'uuid':
            self.parentRef = UUID(self.data)
        else:
            self.parentRef = Path(self.data)

        self.isContainer = attrs.get('container', 'False') == 'True'
        self.parent = self.repository.find(self.parentRef)

        if self.parent is None:
            self.afterLoadHooks.append(self._move)

    def _move(self, view):

        if self.item._parent is None:
            self.parent = view.find(self.parentRef)
            if self.parent is None:
                raise ValueError, 'Parent %s not found' % (self.parentRef)
            else:
                self.item.move(self.parent)

    def classEnd(self, itemHandler, attrs):

        self.cls = ClassLoader.loadClass(self.data, attrs['module'])

    def nameEnd(self, itemHandler, attrs):

        self.name = self.data

    def refEnd(self, itemHandler, attrs):

        if self.tags[-1] == 'item':
            attribute = self.attributes.pop()
            cardinality = self.getCardinality(attribute, attrs)
            otherCard = attrs.get('otherCard', None)

        else:
            cardinality = 'single'
            otherCard = self.tagAttrs[-1].get('otherCard', None)

        if cardinality == 'single':  # cardinality of tag
            typeName = attrs.get('type', 'path')

            if typeName == 'path':
                ref = Path(self.data)
            elif typeName == 'none':
                self.references[attrs['name']] = None
                return
            else:
                ref = UUID(self.data)

            if self.collections:
                refList = self.collections[-1]
                self.refs.append(
                    RefArgs(refList._name,
                            None,
                            refList._otherName,
                            ref,
                            otherCard=otherCard,
                            otherAlias=attrs.get('otherAlias'),
                            previous=self.refName(attrs, 'previous'),
                            next=self.refName(attrs, 'next'),
                            alias=attrs.get('alias')))
            else:
                name = attrs['name']
                otherName = self.getOtherName(name, self.getAttribute(name),
                                              attrs)
                self.refs.append(
                    RefArgs(name,
                            None,
                            otherName,
                            ref,
                            otherCard=otherCard,
                            otherAlias=attrs.get('otherAlias')))
        else:
            value = self.collections.pop()
            self.references[attrs['name']] = value
            if value._indexes:
                self.afterLoadHooks.append(value._restoreIndexes)

    def indexEnd(self, itemHandler, attrs):

        if not self.collections:
            raise ValueError, self.tagAttrs[-1]['name']

        refList = self.collections[-1]
        kwds = attrs.copy()
        del kwds['type']
        del kwds['name']
        refList.addIndex(attrs['name'], attrs['type'], **kwds)

    def refName(self, attrs, attr):

        try:
            return self.makeValue(attrs.get(attr + 'Type', 'str'), attrs[attr])
        except KeyError:
            return None

    def getOtherName(self, name, attribute, attrs):

        otherName = attrs.get('otherName')

        if otherName is None and attribute is not None:
            otherName = self.kind.getOtherName(name, None, None, None)

        if otherName is None:
            raise TypeError, 'Undefined other endpoint for %s.%s of kind %s' % (
                self.name or self.uuid, name, self.kind.itsPath)

        return otherName