示例#1
0
    def _copy(self, orig, copyPolicy, copyFn):

        item = self._item
        for name, value in orig._dict.iteritems():
            if isinstance(value, ItemValue):
                value = value._copy(item, name, copyPolicy, copyFn)
                value._setOwner(item, name)
                self[name] = value

            elif isitemref(value):
                policy = (copyPolicy or
                          item.getAttributeAspect(name, 'copyPolicy',
                                                  False, None, 'copy'))
                other = value(True)
                if isitemref(other):
                    self[name] = value
                else:
                    copyOther = copyFn(item, other, policy)
                    if copyOther is not Nil:
                        self[name] = copyOther.itsRef

            else:
                self[name] = value

            self._copyFlags(orig, name)
    def _removeRef(self, name, other, dictKey=None):

        value = self._dict.get(name, self)
        if value is self:
            return

        item = self._item
        if value is other:
            if other not in (None, Empty) and other._isRefs():
                deferred = item.itsView.isDeferringDelete()
                other.clear(deferred)
                dirty = CItem.RDIRTY
                if not deferred:
                    del self[name]
            else:
                dirty = CItem.VDIRTY
                del self[name]
            item.setDirty(dirty, name, self, True)
            item._fireChanges('remove', name)
        elif (isitemref(value) and other not in (None, Empty)
              and value.itsUUID == other.itsUUID):
            del self[name]
            item.setDirty(CItem.VDIRTY, name, self, True)
            item._fireChanges('remove', name)
        elif value._isRefs():
            return value._removeRef(other, dictKey)
        else:
            raise BadRefError, (self._item, name, other, value)
示例#3
0
    def _removeRef(self, name, other, dictKey=None):

        value = self._dict.get(name, self)
        if value is self:
            return

        item = self._item
        if value is other:
            if other not in (None, Empty) and other._isRefs():
                deferred = item.itsView.isDeferringDelete()
                other.clear(deferred)
                dirty = CItem.RDIRTY
                if not deferred:
                    del self[name]
            else:
                dirty = CItem.VDIRTY
                del self[name]
            item.setDirty(dirty, name, self, True)
            item._fireChanges('remove', name)
        elif (isitemref(value) and
              other not in (None, Empty) and
              value.itsUUID == other.itsUUID):
            del self[name]
            item.setDirty(CItem.VDIRTY, name, self, True)
            item._fireChanges('remove', name)
        elif value._isRefs():
            return value._removeRef(other, dictKey)
        else:
            raise BadRefError, (self._item, name, other, value)
    def check(self, repair=False):

        item = self._item
        logger = item.itsView.logger
        result = True

        for key, value in self._dict.iteritems():
            if isitemref(value):
                value = value(True)
                if isitemref(value):
                    logger.error("Dangling reference %s on %s.%s", value,
                                 item._repr_(), key)
                    result = False
                    continue

            attrCard = item.getAttributeAspect(key, 'cardinality', False, None,
                                               'single')
            if attrCard == 'single':
                check = self._checkCardinality(logger, key, value, None,
                                               'single', repair)
                if check:
                    check = self._checkRef(logger, key, value, repair)
            elif attrCard == 'list':
                check = self._checkCardinality(logger, key, value, RefList,
                                               'list', repair)
                if check and value:
                    check = value._check(logger, item, key, repair)
            elif attrCard == 'dict':
                check = self._checkCardinality(logger, key, value, RefDict,
                                               'dict', repair)
                if check and value:
                    check = value._check(logger, item, key, repair)
            elif attrCard == 'set':
                from chandlerdb.item.Sets import AbstractSet
                check = self._checkCardinality(logger, key, value, AbstractSet,
                                               'set', repair)
                if check:
                    check = value._check(logger, item, key, repair)
            else:
                logger.error(
                    "Attribute %s on %s is using a cardinality, '%s', which is not supported, use 'list' instead",
                    key, self._item.itsPath, attrCard)
                check = False

            result = result and check

        return result
示例#5
0
    def iterValues(self, item):
        def append(values, value):
            if not (value is None or isitemref(value)):
                if isitem(value) or isinstance(value, RefList):
                    values.append(value)
                elif isinstance(value, PersistentCollection):
                    values.append(value._iterItems())
                elif isinstance(value, AbstractSet):
                    values.append(value)
                else:
                    raise TypeError, type(value)

        value = item
        for name in self.attribute:
            if isinstance(value, PersistentCollection):
                values = []
                for v in value._iterItems():
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, RefList):
                values = []
                for v in value:
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, AbstractSet):
                values = []
                for v in value:
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, list):
                values = []
                for v in value:
                    if isitem(v):
                        append(values,
                               v.getAttributeValue(name, None, None, None))
                    else:
                        for i in v:
                            append(values,
                                   i.getAttributeValue(name, None, None, None))
                value = values
            else:
                value = value.getAttributeValue(name, None, None, None)
                if value is None or isitemref(value):
                    break
                if not (isitem(value) or isinstance(
                        value, (PersistentCollection, RefList, AbstractSet))):
                    value = None
                    break

        if value is None:
            return []

        if isitem(value):
            return [value]

        if isinstance(value, PersistentCollection):
            return value._iterItems()

        return value
示例#6
0
    def iterValues(self, item):

        def append(values, value):
            if not (value is None or isitemref(value)):
                if isitem(value) or isinstance(value, RefList):
                    values.append(value)
                elif isinstance(value, PersistentCollection):
                    values.append(value._iterItems())
                elif isinstance(value, AbstractSet):
                    values.append(value)
                else:
                    raise TypeError, type(value)

        value = item
        for name in self.attribute:
            if isinstance(value, PersistentCollection):
                values = []
                for v in value._iterItems():
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, RefList):
                values = []
                for v in value:
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, AbstractSet):
                values = []
                for v in value:
                    append(values, v.getAttributeValue(name, None, None, None))
                value = values
            elif isinstance(value, list):
                values = []
                for v in value:
                    if isitem(v):
                        append(values, v.getAttributeValue(name, None, None, None))
                    else:
                        for i in v:
                            append(values, i.getAttributeValue(name, None, None, None))
                value = values
            else:
                value = value.getAttributeValue(name, None, None, None)
                if value is None or isitemref(value):
                    break
                if not (isitem(value) or
                        isinstance(value, (PersistentCollection,
                                           RefList, AbstractSet))):
                    value = None
                    break

        if value is None:
            return []

        if isitem(value):
            return [value]

        if isinstance(value, PersistentCollection):
            return value._iterItems()

        return value
def isDead(item):
    """
    Return True if the item is None, an itemref, stale, or deferred.
    
    """
    return (item is None or isitemref(item) or
            (item.itsStatus & DEAD_FLAGS) != 0
           )
示例#8
0
    def check(self, repair=False):

        item = self._item
        logger = item.itsView.logger
        result = True

        for key, value in self._dict.iteritems():
            if isitemref(value):
                value = value(True)
                if isitemref(value):
                    logger.error("Dangling reference %s on %s.%s", value,
                                 item._repr_(), key)
                    result = False
                    continue
                
            attrCard = item.getAttributeAspect(key, 'cardinality',
                                               False, None, 'single')
            if attrCard == 'single':
                check = self._checkCardinality(logger, key, value,
                                               None, 'single', repair)
                if check:
                    check = self._checkRef(logger, key, value, repair)
            elif attrCard == 'list':
                check = self._checkCardinality(logger, key, value,
                                               RefList, 'list', repair)
                if check and value:
                    check = value._check(logger, item, key, repair)
            elif attrCard == 'dict':
                check = self._checkCardinality(logger, key, value,
                                               RefDict, 'dict', repair)
                if check and value:
                    check = value._check(logger, item, key, repair)
            elif attrCard == 'set':
                from chandlerdb.item.Sets import AbstractSet
                check = self._checkCardinality(logger, key, value,
                                               AbstractSet, 'set', repair)
                if check:
                    check = value._check(logger, item, key, repair)
            else:
                logger.error("Attribute %s on %s is using a cardinality, '%s', which is not supported, use 'list' instead", key, self._item.itsPath, attrCard)
                check = False

            result = result and check

        return result
示例#9
0
 def append(values, value):
     if not (value is None or isitemref(value)):
         if isitem(value) or isinstance(value, RefList):
             values.append(value)
         elif isinstance(value, PersistentCollection):
             values.append(value._iterItems())
         elif isinstance(value, AbstractSet):
             values.append(value)
         else:
             raise TypeError, type(value)
示例#10
0
 def append(values, value):
     if not (value is None or isitemref(value)):
         if isitem(value) or isinstance(value, RefList):
             values.append(value)
         elif isinstance(value, PersistentCollection):
             values.append(value._iterItems())
         elif isinstance(value, AbstractSet):
             values.append(value)
         else:
             raise TypeError, type(value)
示例#11
0
    def _copy(self, orig, copyPolicy, copyFn):

        item = self._item
        for name, value in orig._dict.iteritems():
            policy = copyPolicy or item.getAttributeAspect(name, 'copyPolicy')
            if value not in (None, Empty) and value._isRefs():
                value._copy(item, name, policy, copyFn)
            else:
                if isitemref(value):
                    value = value()
                orig._copyRef(item, name, value, policy, copyFn)
            self._copyFlags(orig, name)
示例#12
0
 def append(values, value):
     if value is not None:
         if isuuid(value) or isinstance(value, RefList):
             values.append(value)
         elif isitem(value) or isitemref(value):
             values.append(value.itsUUID)
         elif isinstance(value, PersistentCollection):
             values.extend(value._iterKeys())
         elif isinstance(value, AbstractSet):
             values.append(value)
         else:
             raise TypeError, type(value)
示例#13
0
    def _copy(self, orig, copyPolicy, copyFn):

        item = self._item
        for name, value in orig._dict.iteritems():
            policy = copyPolicy or item.getAttributeAspect(name, 'copyPolicy')
            if value not in (None, Empty) and value._isRefs():
                value._copy(item, name, policy, copyFn)
            else:
                if isitemref(value):
                    value = value()
                orig._copyRef(item, name, value, policy, copyFn)
            self._copyFlags(orig, name)
示例#14
0
 def append(values, value):
     if value is not None:
         if isuuid(value) or isinstance(value, RefList):
             values.append(value)
         elif isitem(value) or isitemref(value):
             values.append(value.itsUUID)
         elif isinstance(value, PersistentCollection):
             values.extend(value._iterKeys())
         elif isinstance(value, AbstractSet):
             values.append(value)
         else:
             raise TypeError, type(value)
    def _iterKeys(self, keys=None):

        if keys is None:
            keys = set()
        for value in self._itervalues():
            if isitemref(value):
                key = value.itsUUID
                if key not in keys:
                    keys.add(key)
                    yield key
            elif isinstance(value, PersistentCollection):
                for v in value._iterKeys(keys):
                    yield v
示例#16
0
    def _copy(self, orig, copyPolicy, copyFn):

        item = self._item
        for name, value in orig._dict.iteritems():
            if isinstance(value, ItemValue):
                value = value._copy(item, name, copyPolicy, copyFn)
                value._setOwner(item, name)
                self[name] = value

            elif isitemref(value):
                policy = (copyPolicy or item.getAttributeAspect(
                    name, 'copyPolicy', False, None, 'copy'))
                other = value(True)
                if isitemref(other):
                    self[name] = value
                else:
                    copyOther = copyFn(item, other, policy)
                    if copyOther is not Nil:
                        self[name] = copyOther.itsRef

            else:
                self[name] = value

            self._copyFlags(orig, name)
示例#17
0
    def refCount(self, name, loaded):

        count = 0

        value = self._dict.get(name)
        if value not in (None, Empty):
            if isitemref(value):
                if not loaded:
                    count += 1
                elif isitem(value.itsItem):
                    count += 1
            elif value._isRefs():
                count += value.refCount(loaded)

        return count
    def _iterItems(self, items=None):

        if items is None:
            items = {}
        for value in self._itervalues():
            if isitemref(value):
                item = value(True)
                if isitem(item):
                    uuid = item.itsUUID
                    if uuid not in items:
                        items[uuid] = item
                        yield item
            elif isinstance(value, PersistentCollection):
                for v in value._iterItems(items):
                    yield v
示例#19
0
    def recognizes(self, value):

        if value is None:
            return True

        if isitemref(value):
            item = value(True)
            if isitem(item):
                return item.isItemOf(self)
            return True

        if isitem(value):
            return value.isItemOf(self)
    
        return False
示例#20
0
    def refCount(self, name, loaded):

        count = 0

        value = self._dict.get(name)
        if value not in (None, Empty):
            if isitemref(value):
                if not loaded:
                    count += 1
                elif isitem(value.itsItem):
                    count += 1
            elif value._isRefs():
                count += value.refCount(loaded)

        return count
示例#21
0
    def recognizes(self, value):

        if value is None:
            return True

        if isitemref(value):
            item = value(True)
            if isitem(item):
                return item.isItemOf(self)
            return True

        if isitem(value):
            return value.isItemOf(self)

        return False
    def useValue(self, value):

        if isitem(value):
            return value.itsRef
        if isinstance(value, PersistentCollection):
            return value
        if isitemref(value):
            return value

        if isinstance(value, list):
            return [self.useValue(v) for v in value]
        elif isinstance(value, set):
            return set([self.useValue(v) for v in value])
        elif isinstance(value, tuple):
            return tuple([self.useValue(v) for v in value])
        elif isinstance(value, dict):
            d = {}
            for k, v in value.itervalues():
                d[k] = self.useValue(v)
            return d
        else:
            return value
示例#23
0
    def exportProcess(self, dom, key, element, changes, keys):

        view = self.itsView
        kind = view.kindForKey(key)

        attributes = changes.get(key, ())
        if attributes:
            attributes = tuple(attributes[0])

        if keys is None:
            keys = set()

        if key in keys:
            dom.openElement(element, kind.itsName, uuid=key.str64())
            dom.closeElement(element, kind.itsName)
            return None

        keys.add(key)

        pairs = [(name, Nil) for name in attributes]
        pairs.append((pim.Stamp.stamp_types.name, ()))
        values = list(view.findValues(key, *pairs))

        stampClasses = values.pop()
        elementName, classes = self._getElementName(kind, stampClasses)

        attrs = { 'class': classes, 'uuid': key.str64() }
        item = dom.openElement(element, elementName, **attrs)

        for attrName, attrValue in izip(attributes, values):
            if attrValue is Nil:
                dom.openElement(item, 'value', name=attrName, status='nil')
                dom.closeElement(item, 'value')

            else:
                attribute = kind.getAttribute(attrName) 
                attrType = attribute.getAspect('type')
                cardinality = attribute.getAspect('cardinality')
                otherName = attribute.getAspect('otherName', None)

                if otherName:
                    value = dom.openElement(item, 'value', name=attrName)

                    if isuuid(attrValue):
                        self.exportProcess(dom, attrValue, value,
                                           changes, keys)
                    elif cardinality == 'list':
                        for attrKey in attrValue.iterkeys():
                            self.exportProcess(dom, attrKey, value,
                                               changes, keys)

                    dom.closeElement(item, 'value')
                else:
                    if cardinality == 'single':
                        if isitemref(attrValue):
                            value = dom.openElement(item, 'value', name=attrName)
                            attrValue = attrValue.itsUUID
                            self.exportProcess(dom, attrValue, value,
                                               changes, keys)
                            dom.closeElement(item, 'value')
                        else:
                            mimetype, encoding, attrValue = utility.serializeLiteral(self.itsView, attrValue, attrType)

                            attrs = { 'name': attrName }
                            if mimetype:
                                attrs['mimetype'] = mimetype
                            if encoding:
                                attrs['encoding'] = encoding
                                attrValue = unicode(attrValue, encoding)
                            else:
                                attrValue = unicode(attrValue, 'utf-8')

                            dom.openElement(item, 'value',
                                            content=attrValue, **attrs)
                            dom.closeElement(item, 'value')

                    elif cardinality == 'list':
                        value = dom.openElement(item, 'value', name=attrName)
                        for v in attrValue:
                            attrs = {}
                            mimetype, encoding, v = utility.serializeLiteral(self.itsView, v, attrType)

                            if mimetype:
                                attrs['mimetype'] = mimetype
                            if encoding:
                                attrs['encoding'] = encoding
                                v = unicode(v, encoding)
                            else:
                                v = unicode(v, 'utf-8')

                            dom.openElement(value, 'value', content=v, **attrs)
                            dom.closeElement(value, 'value')
                        dom.closeElement(item, 'value')

        dom.closeElement(element, elementName)
示例#24
0
    def _applyChanges(self, view, flag, dirties, ask, newChanges, changes,
                      conflicts, dangling):

        item = self._item
        if flag == CItem.RDIRTY:
            for name, (card, valueChanges) in newChanges[flag].iteritems():
                value = self.get(name, Nil)
                if card == 'set':
                    if not (changes is None or value == valueChanges):
                        if name in dirties:
                            view._e_3_overlap(MergeError.REF, item, name)

                elif card == 'nil':
                    # conflict: removed value wins over changes coming in
                    if value is not Nil:
                        value._clearRefs()
                        del self[name]
                        self._setDirty(name)

                elif card == 'empty':
                    # conflict: removed value wins over changes coming in
                    if value is not Empty:
                        value._clearRefs()
                        self[name] = Empty
                        self._setDirty(name)

                elif name in dirties:
                    if value is Nil and valueChanges:
                        # conflict: changes lose over removed value coming in
                        otherName = item.itsKind.getOtherName(name, item)
                        if ask(MergeError.DELETE, name, valueChanges):
                            for uValue in valueChanges:
                                dangling.append(
                                    (uValue, otherName, item.itsUUID))
                        else:
                            view._e_1_overlap(MergeError.DELETE, item, name)
                    elif valueChanges:
                        if changes is None:
                            if card == 'dict':
                                for key, vc in valueChanges.iteritems():
                                    refList = value._refList(key)
                                    refList._applyChanges(vc, (), ask)
                            else:
                                value._applyChanges(valueChanges, (), ask)
                        else:
                            if card == 'dict':
                                for key, vc in valueChanges.iteritems():
                                    c = changes[flag][name].get(key, ())
                                    refList = value._refList(key)
                                    refList._applyChanges(vc, c, ask)
                            else:
                                value._applyChanges(valueChanges,
                                                    changes[flag][name], ask)
                        self._setDirty(name)

                elif card == 'dict':
                    if value is Nil:
                        kind = item.itsKind
                        otherName = kind.getOtherName(name, item)
                        self[name] = value = RefDict(item, name, otherName)
                    for key, vc in valueChanges.iteritems():
                        refList = value._refList(key)
                        refList._applyChanges(vc, (), ask)
                    self._setDirty(name)
                else:
                    if value is Nil:
                        self[name] = value = item._refList(name)
                    value._applyChanges(valueChanges, (), ask)
                    self._setDirty(name)

        elif flag == CItem.VDIRTY:
            for name, (isRef, newValue) in newChanges[flag].iteritems():
                if isRef:
                    value = self._dict.get(name, Nil)
                    if not (isitemref(value) or value in (None, Nil)):
                        continue

                    if newValue != value:
                        if isitemref(newValue):
                            newValue = newValue()

                        if name in dirties:
                            nextValue = ask(MergeError.REF, name, newValue)
                            if value not in (Nil, None):
                                kind = item.itsKind
                                otherName = kind.getOtherName(name, item)
                                dangling.append(
                                    (value.itsUUID, otherName, item.itsUUID))
                            if nextValue is not newValue:
                                conflicts.append(
                                    (item.itsUUID, name, nextValue))

                        if newValue is Nil:
                            if isitemref(value):
                                value = value()
                            self._removeRef(name, value)

                        else:
                            self._setRef(name, newValue)
                            self._setDirty(name)
示例#25
0
    def _collectChanges(self, view, flag, dirties, newChanges, changes,
                        indexChanges, version, newVersion):

        item = self._item

        if flag == CItem.RDIRTY:
            for name in self._getDirties():
                if item.getAttributeAspect(name, 'cardinality') == 'single':
                    continue

                value = self._dict.get(name, Nil)

                if name in dirties:
                    if value is Nil:
                        # if both side removed the value, let it pass
                        # this is enforced in _applyChanges
                        newChanges[name] = ('nil', Nil)
                    elif value is Empty:
                        newChanges[name] = ('empty', Empty)
                    elif value._isRefs():
                        if value._isSet():
                            newChanges[name] = ('set', value)
                            changes[name] = {}
                            value._collectIndexChanges(view, name,
                                                       indexChanges)
                        elif value._isDict():
                            newChanges[name] = \
                                ('dict',
                                 dict((key, dict(refList._iterChanges()))
                                      for key, refList in value.iteritems()))
                            changes[name] = \
                                dict((key, dict(refList._iterHistory(version, newVersion))) for key, refList in value.iteritems())
                        else:
                            newChanges[name] = \
                                ('list', dict(value._iterChanges()))
                            changes[name] = dict(
                                value._iterHistory(version, newVersion))
                            value._collectIndexChanges(view, name,
                                                       indexChanges)
                else:
                    if value is Nil:
                        newChanges[name] = ('nil', Nil)
                    elif value is Empty:
                        newChanges[name] = ('empty', Empty)
                    elif value._isRefs():
                        if value._isSet():
                            newChanges[name] = ('set', value)
                            value._collectIndexChanges(view, name,
                                                       indexChanges)
                        elif value._isDict():
                            newChanges[name] = \
                                ('dict',
                                 dict((key, dict(refList._iterChanges()))
                                      for key, refList in value.iteritems()))
                        else:
                            newChanges[name] = ('list',
                                                dict(value._iterChanges()))
                            value._collectIndexChanges(view, name,
                                                       indexChanges)

        elif flag == CItem.VDIRTY:
            for name in self._getDirties():
                if item.getAttributeAspect(name, 'cardinality') != 'single':
                    continue

                value = self._dict.get(name, Nil)
                if not (isitemref(value) or value in (None, Nil)):
                    continue
                newChanges[name] = (True, value)
示例#26
0
    def iterKeys(self, key, firstValue=Default):

        view = self.itsView

        def append(values, value):
            if value is not None:
                if isuuid(value) or isinstance(value, RefList):
                    values.append(value)
                elif isitem(value) or isitemref(value):
                    values.append(value.itsUUID)
                elif isinstance(value, PersistentCollection):
                    values.extend(value._iterKeys())
                elif isinstance(value, AbstractSet):
                    values.append(value)
                else:
                    raise TypeError, type(value)

        if firstValue is not Default:
            names = self.attribute[1:]
            value = firstValue
        else:
            names = self.attribute
            value = key

        for name in names:
            if isinstance(value, PersistentCollection):
                values = []
                for v in value._iterKeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, RefList):
                values = []
                for v in value.iterkeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, AbstractSet):
                values = []
                for v in value.iterkeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, list):
                values = []
                for v in value:
                    if isuuid(v):
                        append(values, view.findValue(v, name, None))
                    else:
                        for k in v.iterkeys():
                            append(values, view.findValue(k, name, None))
                value = values
            else:
                value = view.findValue(value, name, None)
                if value is None:
                    break
                if isitemref(value) or isitem(value):
                    value = value.itsUUID
                elif not (isuuid(value) or
                          isinstance(value, (PersistentCollection,
                                             RefList, AbstractSet))):
                    value = None
                    break

        if value is None:
            return []

        if isuuid(value):
            return [value]

        if isitemref(value) or isitem(value):
            return [value.itsUUID]

        if isinstance(value, PersistentCollection):
            return value._iterKeys()

        if isinstance(value, RefList):
            return value.iterkeys()

        return value
示例#27
0
    def iterKeys(self, key, firstValue=Default):

        view = self.itsView

        def append(values, value):
            if value is not None:
                if isuuid(value) or isinstance(value, RefList):
                    values.append(value)
                elif isitem(value) or isitemref(value):
                    values.append(value.itsUUID)
                elif isinstance(value, PersistentCollection):
                    values.extend(value._iterKeys())
                elif isinstance(value, AbstractSet):
                    values.append(value)
                else:
                    raise TypeError, type(value)

        if firstValue is not Default:
            names = self.attribute[1:]
            value = firstValue
        else:
            names = self.attribute
            value = key

        for name in names:
            if isinstance(value, PersistentCollection):
                values = []
                for v in value._iterKeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, RefList):
                values = []
                for v in value.iterkeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, AbstractSet):
                values = []
                for v in value.iterkeys():
                    append(values, view.findValue(v, name, None))
                value = values
            elif isinstance(value, list):
                values = []
                for v in value:
                    if isuuid(v):
                        append(values, view.findValue(v, name, None))
                    else:
                        for k in v.iterkeys():
                            append(values, view.findValue(k, name, None))
                value = values
            else:
                value = view.findValue(value, name, None)
                if value is None:
                    break
                if isitemref(value) or isitem(value):
                    value = value.itsUUID
                elif not (isuuid(value) or isinstance(
                        value, (PersistentCollection, RefList, AbstractSet))):
                    value = None
                    break

        if value is None:
            return []

        if isuuid(value):
            return [value]

        if isitemref(value) or isitem(value):
            return [value.itsUUID]

        if isinstance(value, PersistentCollection):
            return value._iterKeys()

        if isinstance(value, RefList):
            return value.iterkeys()

        return value
示例#28
0
    def _ref(self, item, name, value, version, flags, withSchema, attribute):

        self.indexes = []
        uValue = UUID()
        self.values.append((name, uValue))
        size = 0

        record = Record(Record.UUID, attribute.itsUUID, Record.BYTE, flags)

        refRecord = Record()
        if withSchema:
            refRecord += (Record.SYMBOL, name)

        if value is None:
            refRecord += (Record.BYTE, (DBItemWriter.NONE | DBItemWriter.REF
                                        | DBItemWriter.SINGLE))

        elif value is Empty:
            refRecord += (Record.BYTE, (DBItemWriter.NONE | DBItemWriter.REF
                                        | DBItemWriter.LIST))

        elif isuuid(value):
            if withSchema:
                raise AssertionError, 'withSchema is True'
            refRecord += (Record.BYTE, DBItemWriter.SINGLE | DBItemWriter.REF,
                          Record.UUID, value)

        elif isitemref(value):
            refRecord += (Record.BYTE, DBItemWriter.SINGLE | DBItemWriter.REF,
                          Record.UUID, value.itsUUID)

        elif value._isRefs():
            attrCard = attribute.c.cardinality
            if attrCard == 'list':
                flags = DBItemWriter.LIST | DBItemWriter.REF
                if withSchema:
                    flags |= DBItemWriter.TYPED
                refRecord += (Record.BYTE, flags, Record.UUID, value.uuid)
                if withSchema:
                    refRecord += (Record.SYMBOL,
                                  item.itsKind.getOtherName(name, item))
                size += value._saveValues(version)

            elif attrCard == 'set':
                refRecord += (Record.BYTE, DBItemWriter.SET | DBItemWriter.REF,
                              Record.STRING, value.makeString(value))

            elif attrCard == 'dict':
                flags = DBItemWriter.DICT | DBItemWriter.REF
                if withSchema:
                    flags |= DBItemWriter.TYPED
                refRecord += (Record.BYTE, flags)
                if withSchema:
                    refRecord += (Record.SYMBOL,
                                  item.itsKind.getOtherName(name, item))
                refRecord += (Record.SHORT, len(value._dict))
                for key, refList in value._dict.iteritems():
                    refRecord += (Record.UUID_OR_SYMBOL, key, Record.UUID,
                                  refList.uuid)
                    if refList._isDirty():
                        size += refList._saveValues(version)

            else:
                raise NotImplementedError, attrCard

            if attrCard != 'dict':
                size += self.writeIndexes(refRecord, item, version, value)

        else:
            raise TypeError, value

        record += (Record.RECORD, refRecord, Record.RECORD, Record())

        indexRecord = Record()
        for uuid in self.indexes:
            indexRecord += (Record.UUID, uuid)
        record += (Record.RECORD, indexRecord)

        size += self.store._values.c.saveValue(item.itsUUID, uValue, record)

        return size
def FilterGone(list):
    return [x for x in list if not isitemref(x)]
示例#30
0
    def _collectChanges(self, view, flag, dirties,
                        newChanges, changes, indexChanges, version, newVersion):
        
        item = self._item

        if flag == CItem.RDIRTY:
            for name in self._getDirties():
                if item.getAttributeAspect(name, 'cardinality') == 'single':
                    continue

                value = self._dict.get(name, Nil)

                if name in dirties:
                    if value is Nil:
                        # if both side removed the value, let it pass
                        # this is enforced in _applyChanges
                        newChanges[name] = ('nil', Nil)
                    elif value is Empty:
                        newChanges[name] = ('empty', Empty)
                    elif value._isRefs():
                        if value._isSet():
                            newChanges[name] = ('set', value)
                            changes[name] = {}
                            value._collectIndexChanges(view, name, indexChanges)
                        elif value._isDict():
                            newChanges[name] = \
                                ('dict', 
                                 dict((key, dict(refList._iterChanges()))
                                      for key, refList in value.iteritems()))
                            changes[name] = \
                                dict((key, dict(refList._iterHistory(version, newVersion))) for key, refList in value.iteritems())
                        else:
                            newChanges[name] = \
                                ('list', dict(value._iterChanges()))
                            changes[name] = dict(value._iterHistory(version,
                                                                    newVersion))
                            value._collectIndexChanges(view, name, indexChanges)
                else:
                    if value is Nil:
                        newChanges[name] = ('nil', Nil)
                    elif value is Empty:
                        newChanges[name] = ('empty', Empty)
                    elif value._isRefs():
                        if value._isSet():
                            newChanges[name] = ('set', value)
                            value._collectIndexChanges(view, name, indexChanges)
                        elif value._isDict():
                            newChanges[name] = \
                                ('dict', 
                                 dict((key, dict(refList._iterChanges()))
                                      for key, refList in value.iteritems()))
                        else:
                            newChanges[name] = ('list',
                                                dict(value._iterChanges()))
                            value._collectIndexChanges(view, name, indexChanges)

        elif flag == CItem.VDIRTY:
            for name in self._getDirties():
                if item.getAttributeAspect(name, 'cardinality') != 'single':
                    continue

                value = self._dict.get(name, Nil)
                if not (isitemref(value) or value in (None, Nil)):
                    continue
                newChanges[name] = (True, value)
示例#31
0
def FilterGone(list):
    return [x for x in list if not isitemref(x)]
def RenderItem(item, urlRoot):

    result = ""
    # For Kinds, display their attributes (except for the internal ones
    # like notFoundAttributes):
    isKind = \
     (item.itsKind and "//Schema/Core/Kind" == str(item.itsKind.itsPath))

    path = "<a href=%s>[top]</a>" % toLink(urlRoot, "/")
    i = 2
    for part in item.itsPath[1:-1]:
        path += " &gt; <a href=%s>%s</a>" % (toLink(urlRoot,
                                                    item.itsPath[:i]), part)
        i += 1

    result += "<div class='path'>%s &gt; <span class='itemname'>%s</span>" % (
        path, item.itsName)

    try:
        result += " (<a href=%s>%s</a>)" % (toLink(
            urlRoot, item.itsKind.itsPath), item.itsKind.itsName)
    except:
        pass
    result += "</div>\n"

    try:
        description = item.description
        result += "<div class='subheader'><b>Description:</b> %s</div>\n" % description
    except:
        pass

    try:
        issues = item.issues
        result += "<div class='subheader'><b>Issues:</b>\n<ul></div>\n"
        for issue in issues:
            result += "<li>%s\n" % issue
        result += "</ul></p>\n"
    except:
        pass

    result += "<div class='children'><b>Child items:</b> "
    children = {}

    for child in item.iterChildren():
        # if isinstance(child, Kind) or isinstance(child, Attribute) or isinstance(child, Type) or isinstance(child, Cloud) or isinstance(child, Endpoint) or isinstance(child, Parcel):
        name = child.itsName
        if name is None: name = str(child.itsUUID)
        children[name] = child
    keys = children.keys()

    keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
    output = []
    for key in keys:
        child = children[key]
        output.append("<a href=%s>%s</a>" %
                      (toLink(urlRoot, child.itsPath), key))
    if not output:
        result += " None"
    else:
        result += (", ".join(output))
    result += "</div>\n"

    if isKind:
        result += "<table width=100% border=0 cellpadding=4 cellspacing=0>\n"
        result += "<tr class='toprow'>"
        result += "<td colspan=7><b>Attributes defined for this kind:</b></td>"
        result += "</tr>\n"

        result += "<tr class='headingsrow'>\n"
        result += "<td valign=top><b>Attribute</b> (inherited from)</td>\n"
        result += "<td valign=top><b>Description / Issues</b></td>\n"
        result += "<td valign=top><b>Cardinality</b></td>\n"
        result += "<td valign=top><b>Type</b></td>\n"
        result += "<td valign=top><b>Initial&nbsp;Value</b></td>\n"
        result += "<td valign=top><b>Required?</b></td>\n"
        result += "</tr>\n"
        count = 0
        displayedAttrs = {}
        for name, attr, kind in item.iterAttributes():
            if name is None: name = "Anonymous"
            displayedAttrs[name] = (attr, kind)
        keys = displayedAttrs.keys()
        keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
        for key in keys:
            attribute, kind = displayedAttrs[key]
            result += oddEvenRow(count)
            other = getattr(attribute, 'otherName', "")
            if other: other = " (inverse: '%s')" % other
            else: other = ""
            if kind is not item:
                inherited = " (from <a href=%s>%s</a>)" % (toLink(
                    urlRoot, kind.itsPath), kind.itsName)
            else:
                inherited = ""
            result += "<td valign=top><a href=%s>%s</a>%s%s</td>\n" % \
             (toLink(urlRoot, attribute.itsPath), key, inherited, other)
            result += "<td valign=top>%s" % \
             (getattr(attribute, 'description', "&nbsp;"))
            try:
                issues = attribute.issues
                result += "<p>Issues:<ul>"
                for issue in issues:
                    result += "<li>%s\n" % issue
                result += "</ul></p>"
            except:
                pass
            result += "</td>\n"
            cardinality = getattr(attribute, 'cardinality', 'single')
            result += "<td valign=top>%s</td>\n" % (cardinality)
            attrType = getattr(attribute, 'type', None)
            if attrType:
                result += "<td valign=top><a href=%s>%s</a></td>\n" % \
                 (toLink(urlRoot, attrType.itsPath), attrType.itsName)
            else:
                result += "<td valign=top>N/A</td>\n"
            if attribute.hasLocalAttributeValue('initialValue'):
                result += "<td valign=top>%s</td>\n" % (
                    attribute.initialValue, )
            else:
                result += "<td valign=top>N/A</td>\n"
            if attribute.required: result += "<td valign=top>Yes</td>\n"
            else: result += "<td valign=top>No</td>\n"

            result += "</tr>\n"
            count += 1
        result += "</table>\n"
        result += "<br />\n"

    result += "<table width=100% border=0 cellpadding=4 cellspacing=0>\n"
    result += "<tr class='toprow'>\n"
    result += "<td colspan=2><b>Attribute values for this item:</b></td>\n"
    result += "</tr>\n"
    result += "<tr class='headingsrow'>\n"
    result += "<td valign=top><b>Attribute</b></td>\n"
    result += "<td valign=top><b>Value</b></td>\n"
    result += "</tr>\n"
    count = 0

    displayedAttrs = {}
    for (name, value) in item.iterAttributeValues():
        if name is None: name = "Anonymous"
        displayedAttrs[name] = value

    keys = displayedAttrs.keys()
    keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
    for name in keys:
        value = displayedAttrs[name]

        if name == "attributes" or \
           name == "notFoundAttributes" or \
           name == "inheritedAttributes":
            pass

        elif name == "originalValues":
            pass

        elif isinstance(value, RefList):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            output = []
            for j in value:
                output.append("<a href=%s>%s</a>" % \
                 (toLink(urlRoot, j.itsPath), j.itsName))
            result += (", ".join(output))

            result += "</td></tr>\n"
            count += 1

        elif isinstance(value, list):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            result += "<ul>"
            for j in value:
                try:
                    result += "<li>%s <a href=%s>%s</a><br>\n" % (
                        j.itsName, toLink(urlRoot, j.itsPath), j.itsPath)
                except:
                    result += "<li>%s (%s)<br>\n" % (clean(j), clean(type(j)))
            result += "</ul>"
            result += "</td></tr>\n"
            count += 1

        elif isinstance(value, dict):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            for key in value.keys():
                try:
                    result += "%s: %s <a href=%s>%s</a><br>" % \
                     (key, value[key].itsName, toLink(urlRoot,
                     value[key].itsPath), value[key].itsPath)
                except:
                    result += "%s: %s (%s)<br>" % (key, clean(
                        value[key]), clean(type(value[key])))

            result += "</td></tr>\n"
            count += 1

        elif isitemref(value):
            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            target = getattr(item, name, None)
            if target is not None:
                result += "<a href=%s>%s</a><br>" % (toLink(
                    urlRoot, target.itsPath), target.itsName)
            else:
                result += " None"
            result += "</td></tr>\n"
            count += 1

        else:

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            try:
                result += "<a href=%s>%s</a><br>" % (toLink(
                    urlRoot, value.itsPath), value.itsName)
            except:
                result += "%s (%s)<br>" % (clean(value), clean(type(value)))

            result += "</td></tr>\n"
            count += 1
    result += "</table>\n"

    if isKind:

        # Cloud info
        result += "<br />\n"
        result += RenderClouds(item, urlRoot)

    return result
示例#33
0
    def exportProcess(self, dom, key, element, changes, keys):

        view = self.itsView
        kind = view.kindForKey(key)

        attributes = changes.get(key, ())
        if attributes:
            attributes = tuple(attributes[0])

        if keys is None:
            keys = set()

        if key in keys:
            dom.openElement(element, kind.itsName, uuid=key.str64())
            dom.closeElement(element, kind.itsName)
            return None

        keys.add(key)

        pairs = [(name, Nil) for name in attributes]
        pairs.append((pim.Stamp.stamp_types.name, ()))
        values = list(view.findValues(key, *pairs))

        stampClasses = values.pop()
        elementName, classes = self._getElementName(kind, stampClasses)

        attrs = {'class': classes, 'uuid': key.str64()}
        item = dom.openElement(element, elementName, **attrs)

        for attrName, attrValue in izip(attributes, values):
            if attrValue is Nil:
                dom.openElement(item, 'value', name=attrName, status='nil')
                dom.closeElement(item, 'value')

            else:
                attribute = kind.getAttribute(attrName)
                attrType = attribute.getAspect('type')
                cardinality = attribute.getAspect('cardinality')
                otherName = attribute.getAspect('otherName', None)

                if otherName:
                    value = dom.openElement(item, 'value', name=attrName)

                    if isuuid(attrValue):
                        self.exportProcess(dom, attrValue, value, changes,
                                           keys)
                    elif cardinality == 'list':
                        for attrKey in attrValue.iterkeys():
                            self.exportProcess(dom, attrKey, value, changes,
                                               keys)

                    dom.closeElement(item, 'value')
                else:
                    if cardinality == 'single':
                        if isitemref(attrValue):
                            value = dom.openElement(item,
                                                    'value',
                                                    name=attrName)
                            attrValue = attrValue.itsUUID
                            self.exportProcess(dom, attrValue, value, changes,
                                               keys)
                            dom.closeElement(item, 'value')
                        else:
                            mimetype, encoding, attrValue = utility.serializeLiteral(
                                self.itsView, attrValue, attrType)

                            attrs = {'name': attrName}
                            if mimetype:
                                attrs['mimetype'] = mimetype
                            if encoding:
                                attrs['encoding'] = encoding
                                attrValue = unicode(attrValue, encoding)
                            else:
                                attrValue = unicode(attrValue, 'utf-8')

                            dom.openElement(item,
                                            'value',
                                            content=attrValue,
                                            **attrs)
                            dom.closeElement(item, 'value')

                    elif cardinality == 'list':
                        value = dom.openElement(item, 'value', name=attrName)
                        for v in attrValue:
                            attrs = {}
                            mimetype, encoding, v = utility.serializeLiteral(
                                self.itsView, v, attrType)

                            if mimetype:
                                attrs['mimetype'] = mimetype
                            if encoding:
                                attrs['encoding'] = encoding
                                v = unicode(v, encoding)
                            else:
                                v = unicode(v, 'utf-8')

                            dom.openElement(value, 'value', content=v, **attrs)
                            dom.closeElement(value, 'value')
                        dom.closeElement(item, 'value')

        dom.closeElement(element, elementName)
    def restoreValue(self, value):

        if self._owner is not Nil and isitemref(value):
            return value(True)

        return value
示例#35
0
    def _ref(self, item, name, value, version, flags, withSchema, attribute):

        self.indexes = []
        uValue = UUID()
        self.values.append((name, uValue))
        size = 0

        record = Record(Record.UUID, attribute.itsUUID, Record.BYTE, flags)

        refRecord = Record()
        if withSchema:
            refRecord += (Record.SYMBOL, name)

        if value is None:
            refRecord += (Record.BYTE, (DBItemWriter.NONE | DBItemWriter.REF | DBItemWriter.SINGLE))

        elif value is Empty:
            refRecord += (Record.BYTE, (DBItemWriter.NONE | DBItemWriter.REF | DBItemWriter.LIST))

        elif isuuid(value):
            if withSchema:
                raise AssertionError, "withSchema is True"
            refRecord += (Record.BYTE, DBItemWriter.SINGLE | DBItemWriter.REF, Record.UUID, value)

        elif isitemref(value):
            refRecord += (Record.BYTE, DBItemWriter.SINGLE | DBItemWriter.REF, Record.UUID, value.itsUUID)

        elif value._isRefs():
            attrCard = attribute.c.cardinality
            if attrCard == "list":
                flags = DBItemWriter.LIST | DBItemWriter.REF
                if withSchema:
                    flags |= DBItemWriter.TYPED
                refRecord += (Record.BYTE, flags, Record.UUID, value.uuid)
                if withSchema:
                    refRecord += (Record.SYMBOL, item.itsKind.getOtherName(name, item))
                size += value._saveValues(version)

            elif attrCard == "set":
                refRecord += (Record.BYTE, DBItemWriter.SET | DBItemWriter.REF, Record.STRING, value.makeString(value))

            elif attrCard == "dict":
                flags = DBItemWriter.DICT | DBItemWriter.REF
                if withSchema:
                    flags |= DBItemWriter.TYPED
                refRecord += (Record.BYTE, flags)
                if withSchema:
                    refRecord += (Record.SYMBOL, item.itsKind.getOtherName(name, item))
                refRecord += (Record.SHORT, len(value._dict))
                for key, refList in value._dict.iteritems():
                    refRecord += (Record.UUID_OR_SYMBOL, key, Record.UUID, refList.uuid)
                    if refList._isDirty():
                        size += refList._saveValues(version)

            else:
                raise NotImplementedError, attrCard

            if attrCard != "dict":
                size += self.writeIndexes(refRecord, item, version, value)

        else:
            raise TypeError, value

        record += (Record.RECORD, refRecord, Record.RECORD, Record())

        indexRecord = Record()
        for uuid in self.indexes:
            indexRecord += (Record.UUID, uuid)
        record += (Record.RECORD, indexRecord)

        size += self.store._values.c.saveValue(item.itsUUID, uValue, record)

        return size
示例#36
0
    def _applyChanges(self, view, flag, dirties, ask, newChanges, changes,
                      conflicts, dangling):

        item = self._item
        if flag == CItem.RDIRTY:
            for name, (card, valueChanges) in newChanges[flag].iteritems():
                value = self.get(name, Nil)
                if card == 'set':
                    if not (changes is None or value == valueChanges):
                        if name in dirties:
                            view._e_3_overlap(MergeError.REF, item, name)

                elif card == 'nil':
                    # conflict: removed value wins over changes coming in
                    if value is not Nil:
                        value._clearRefs()
                        del self[name]
                        self._setDirty(name)

                elif card == 'empty':
                    # conflict: removed value wins over changes coming in
                    if value is not Empty:
                        value._clearRefs()
                        self[name] = Empty
                        self._setDirty(name)

                elif name in dirties:
                    if value is Nil and valueChanges:
                        # conflict: changes lose over removed value coming in
                        otherName = item.itsKind.getOtherName(name, item)
                        if ask(MergeError.DELETE, name, valueChanges):
                            for uValue in valueChanges:
                                dangling.append((uValue, otherName,
                                                 item.itsUUID))
                        else:
                            view._e_1_overlap(MergeError.DELETE, item, name)
                    elif valueChanges:
                        if changes is None:
                            if card == 'dict':
                                for key, vc in valueChanges.iteritems():
                                    refList = value._refList(key)
                                    refList._applyChanges(vc, (), ask)
                            else:
                                value._applyChanges(valueChanges, (), ask)
                        else:
                            if card == 'dict':
                                for key, vc in valueChanges.iteritems():
                                    c = changes[flag][name].get(key, ())
                                    refList = value._refList(key)
                                    refList._applyChanges(vc, c, ask)
                            else:
                                value._applyChanges(valueChanges,
                                                    changes[flag][name], ask)
                        self._setDirty(name)

                elif card == 'dict':
                    if value is Nil:
                        kind = item.itsKind
                        otherName = kind.getOtherName(name, item)
                        self[name] = value = RefDict(item, name, otherName)
                    for key, vc in valueChanges.iteritems():
                        refList = value._refList(key)
                        refList._applyChanges(vc, (), ask)
                    self._setDirty(name)
                else:
                    if value is Nil:
                        self[name] = value = item._refList(name)
                    value._applyChanges(valueChanges, (), ask)
                    self._setDirty(name)

        elif flag == CItem.VDIRTY:
            for name, (isRef, newValue) in newChanges[flag].iteritems():
                if isRef:
                    value = self._dict.get(name, Nil)
                    if not (isitemref(value) or value in (None, Nil)):
                        continue

                    if newValue != value:
                        if isitemref(newValue):
                            newValue = newValue()

                        if name in dirties:
                            nextValue = ask(MergeError.REF, name, newValue)
                            if value not in (Nil, None):
                                kind = item.itsKind
                                otherName = kind.getOtherName(name, item)
                                dangling.append((value.itsUUID, otherName,
                                                 item.itsUUID))
                            if nextValue is not newValue:
                                conflicts.append((item.itsUUID,
                                                  name, nextValue))

                        if newValue is Nil:
                            if isitemref(value):
                                value = value()
                            self._removeRef(name, value)

                        else:
                            self._setRef(name, newValue)
                            self._setDirty(name)
示例#37
0
def RenderItem(item, urlRoot):

    result = ""
    # For Kinds, display their attributes (except for the internal ones
    # like notFoundAttributes):
    isKind = \
     (item.itsKind and "//Schema/Core/Kind" == str(item.itsKind.itsPath))

    path = "<a href=%s>[top]</a>" % toLink(urlRoot, "/")
    i = 2
    for part in item.itsPath[1:-1]:
        path += " &gt; <a href=%s>%s</a>" % (toLink(urlRoot, item.itsPath[:i]), part)
        i += 1

    result += "<div class='path'>%s &gt; <span class='itemname'>%s</span>" % (path, item.itsName)

    try: result += " (<a href=%s>%s</a>)" % (toLink(urlRoot, item.itsKind.itsPath), item.itsKind.itsName)
    except: pass
    result += "</div>\n"

    try:
        description = item.description
        result += "<div class='subheader'><b>Description:</b> %s</div>\n" % description
    except:
        pass

    try:
        issues = item.issues
        result += "<div class='subheader'><b>Issues:</b>\n<ul></div>\n"
        for issue in issues:
            result += "<li>%s\n" % issue
        result += "</ul></p>\n"
    except: pass

    result += "<div class='children'><b>Child items:</b> "
    children = {}

    for child in item.iterChildren():
        # if isinstance(child, Kind) or isinstance(child, Attribute) or isinstance(child, Type) or isinstance(child, Cloud) or isinstance(child, Endpoint) or isinstance(child, Parcel):
        name = child.itsName
        if name is None: name = str(child.itsUUID)
        children[name] = child
    keys = children.keys()

    keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
    output = []
    for key in keys:
        child = children[key]
        output.append("<a href=%s>%s</a>" % (toLink(urlRoot, child.itsPath), key))
    if not output:
        result += " None"
    else:
        result += (", ".join(output))
    result += "</div>\n"


    if isKind:
        result += "<table width=100% border=0 cellpadding=4 cellspacing=0>\n"
        result += "<tr class='toprow'>"
        result += "<td colspan=7><b>Attributes defined for this kind:</b></td>"
        result += "</tr>\n"

        result += "<tr class='headingsrow'>\n"
        result += "<td valign=top><b>Attribute</b> (inherited from)</td>\n"
        result += "<td valign=top><b>Description / Issues</b></td>\n"
        result += "<td valign=top><b>Cardinality</b></td>\n"
        result += "<td valign=top><b>Type</b></td>\n"
        result += "<td valign=top><b>Initial&nbsp;Value</b></td>\n"
        result += "<td valign=top><b>Required?</b></td>\n"
        result += "</tr>\n"
        count = 0
        displayedAttrs = { }
        for name, attr, kind in item.iterAttributes():
            if name is None: name = "Anonymous"
            displayedAttrs[name] = (attr, kind)
        keys = displayedAttrs.keys()
        keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
        for key in keys:
            attribute, kind = displayedAttrs[key]
            result += oddEvenRow(count)
            other = getattr(attribute, 'otherName', "")
            if other: other = " (inverse: '%s')" % other
            else: other = ""
            if kind is not item:
                inherited = " (from <a href=%s>%s</a>)" % (toLink(urlRoot, kind.itsPath), kind.itsName)
            else:
                inherited = ""
            result += "<td valign=top><a href=%s>%s</a>%s%s</td>\n" % \
             (toLink(urlRoot, attribute.itsPath), key, inherited, other)
            result += "<td valign=top>%s" % \
             (getattr(attribute, 'description', "&nbsp;"))
            try:
                issues = attribute.issues
                result += "<p>Issues:<ul>"
                for issue in issues:
                    result += "<li>%s\n" % issue
                result += "</ul></p>"
            except: pass
            result += "</td>\n"
            cardinality = getattr(attribute, 'cardinality', 'single')
            result += "<td valign=top>%s</td>\n" % ( cardinality )
            attrType = getattr(attribute, 'type', None)
            if attrType:
                result += "<td valign=top><a href=%s>%s</a></td>\n" % \
                 (toLink(urlRoot, attrType.itsPath), attrType.itsName)
            else:
                result += "<td valign=top>N/A</td>\n"
            if attribute.hasLocalAttributeValue('initialValue'):
                result += "<td valign=top>%s</td>\n" % (attribute.initialValue,)
            else:
                result += "<td valign=top>N/A</td>\n"
            if attribute.required: result += "<td valign=top>Yes</td>\n"
            else: result += "<td valign=top>No</td>\n"

            result += "</tr>\n"
            count += 1
        result += "</table>\n"
        result += "<br />\n"

    result += "<table width=100% border=0 cellpadding=4 cellspacing=0>\n"
    result += "<tr class='toprow'>\n"
    result += "<td colspan=2><b>Attribute values for this item:</b></td>\n"
    result += "</tr>\n"
    result += "<tr class='headingsrow'>\n"
    result += "<td valign=top><b>Attribute</b></td>\n"
    result += "<td valign=top><b>Value</b></td>\n"
    result += "</tr>\n"
    count = 0

    displayedAttrs = { }
    for (name, value) in item.iterAttributeValues():
        if name is None: name = "Anonymous"
        displayedAttrs[name] = value

    keys = displayedAttrs.keys()
    keys.sort(lambda x, y: cmp(string.lower(x), string.lower(y)))
    for name in keys:
        value = displayedAttrs[name]

        if name == "attributes" or \
           name == "notFoundAttributes" or \
           name == "inheritedAttributes":
            pass

        elif name == "originalValues":
            pass

        elif isinstance(value, RefList):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            output = []
            for j in value:
                output.append("<a href=%s>%s</a>" % \
                 (toLink(urlRoot, j.itsPath), j.itsName))
            result += (", ".join(output))

            result += "</td></tr>\n"
            count += 1

        elif isinstance(value, list):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            result += "<ul>"
            for j in value:
                try:
                    result += "<li>%s <a href=%s>%s</a><br>\n" % (j.itsName,
                     toLink(urlRoot, j.itsPath), j.itsPath)
                except:
                    result += "<li>%s (%s)<br>\n" % (clean(j), clean(type(j)))
            result += "</ul>"
            result += "</td></tr>\n"
            count += 1

        elif isinstance(value, dict):

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            for key in value.keys():
                try:
                    result += "%s: %s <a href=%s>%s</a><br>" % \
                     (key, value[key].itsName, toLink(urlRoot,
                     value[key].itsPath), value[key].itsPath)
                except:
                    result += "%s: %s (%s)<br>" % (key, clean(value[key]),
                     clean(type(value[key])))

            result += "</td></tr>\n"
            count += 1

        elif isitemref(value):
            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            target = getattr(item, name, None)
            if target is not None:
                result += "<a href=%s>%s</a><br>" % (toLink(urlRoot,
                 target.itsPath), target.itsName)
            else:
                result += " None"
            result += "</td></tr>\n"
            count += 1

        else:

            result += oddEvenRow(count)
            result += "<td valign=top>"
            result += "%s" % name
            result += "</td><td valign=top>"
            try:
                result += "<a href=%s>%s</a><br>" % (toLink(urlRoot,
                 value.itsPath), value.itsName)
            except:
                result += "%s (%s)<br>" % (clean(value), clean(type(value)))

            result += "</td></tr>\n"
            count += 1
    result += "</table>\n"

    if isKind:

        # Cloud info
        result += "<br />\n"
        result += RenderClouds(item, urlRoot)

    return result