Exemplo n.º 1
0
    def itemStart(self, attrs):

        self.itemUUID = UUID(attrs['uuid'])
        self.itemVersion = int(attrs['version'])

        version = self.store.getItemVersion(self.itemVersion, self.itemUUID)
        if not self.force and version == self.itemVersion:
            self._isSkipping = True
            self._isOn = False

        else:
            self._buffer.truncate(0)
            self._buffer.seek(0)
            self.generator = XMLGenerator(self._buffer)
            self.generator.startDocument()
            self._isOn = True
Exemplo n.º 2
0
    def itemStart(self, attrs):

        self.itemUUID = UUID(attrs['uuid'])
        self.itemVersion = int(attrs['version'])

        version = self.store.getItemVersion(self.itemVersion, self.itemUUID)
        if not self.force and version == self.itemVersion:
            self._isSkipping = True
            self._isOn = False

        else:
            self._buffer.truncate(0)
            self._buffer.seek(0)
            self.generator = XMLGenerator(self._buffer)
            self.generator.startDocument()
            self._isOn = True
Exemplo n.º 3
0
class RemoteFilter(XMLFilter):

    def __init__(self, store, versionId, force=False):

        XMLFilter.__init__(self, None)

        self.store = store
        self.versionId = versionId
        self.force = force
        
        self._attrs = []
        self._isOn = False
        self._isSkipping = False
        
        self._txnStatus = 0
        self._lock = None
        self._buffer = cStringIO.StringIO()
        self._refBuffer = cStringIO.StringIO()
        self._keyBuffer = None
        self._document = None
        self._indexWriter = None
        self._count = 0
        
    def output(self):

        return self._isOn

    def getDocument(self):

        class doc(object):
            def __init__(self, xml):
                self._xml = xml
            def getContent(self):
                return self._xml
            
        return doc(self._document)

    def startElement(self, tag, attrs):

        if not self.errorOccurred():
            self.data = ''
            method = getattr(self, tag + 'Start', None)
            if method is not None:
                try:
                    method(attrs)
                except Exception:
                    self.saveException()
            self._attrs.append(attrs)

        XMLFilter.startElement(self, tag, attrs)

    def characters(self, data):

        self.data += data
        XMLFilter.characters(self, data)

    def cdataBlock(self, data):

        self.data += data
        XMLFilter.cdataBlock(self, data)

    def endElement(self, tag):

        if not self.errorOccurred():
            attrs = self._attrs.pop()
            method = getattr(self, tag + 'End', None)
            if method is not None:
                try:
                    method(attrs)
                except Exception:
                    self.saveException()
        else:
            if self._indexWriter is not None:
                self._indexWriter.close()
                self._indexWriter = None
            self.store.abortTransaction(self._txnStatus)
            self._txnStatus = 0
            if self._lock:
                self._lock = self.store.releaseLock(self._lock)

        XMLFilter.endElement(self, tag)

    def itemsStart(self, attrs):

        if attrs is not None and 'versionId' in attrs:
            versionId = UUID(attrs['versionId'])
            if versionId != self.versionId:
                raise ValueError, "remote version ids don't match"

        self._txnStatus = self.store.startTransaction()
        self._lock = self.store.acquireLock()

    def itemsEnd(self, attrs):

        if self._indexWriter is not None:
            self.store._index.optimizeIndex(self._indexWriter)
            self._indexWriter.close()
            self._indexWriter = None
            
        self.store.commitTransaction(self._txnStatus)
        self._txnStatus = 0
        if self._lock:
            self._lock = self.store.releaseLock(self._lock)

    def containerEnd(self, attrs):

        if not self._isSkipping:
            self.itemParent = UUID(self.data)

    def nameEnd(self, attrs):

        self.itemName = self.data

    def itemStart(self, attrs):

        self.itemUUID = UUID(attrs['uuid'])
        self.itemVersion = int(attrs['version'])

        version = self.store.getItemVersion(self.itemVersion, self.itemUUID)
        if not self.force and version == self.itemVersion:
            self._isSkipping = True
            self._isOn = False

        else:
            self._buffer.truncate(0)
            self._buffer.seek(0)
            self.generator = XMLGenerator(self._buffer)
            self.generator.startDocument()
            self._isOn = True

    def itemEnd(self, attrs):

        if not self._isSkipping:
            self.generator.endElement('item')
            self.generator.endDocument()
            self.generator = None
            self._isOn = False

            xml = self._buffer.getvalue()
            if self._document is None:
                self._document = xml

            self._count += 1
            self.store.saveItem(xml, self.itemUUID, self.itemVersion,
                                (self.itemParent, self.itemName), None, 0)

        else:
            self._isSkipping = False

    def attributeStart(self, attrs):

        if not self._isSkipping:
            self.attributeName = attrs['name']

    def refStart(self, attrs):

        if self._isSkipping:
            return 

        if attrs and 'first' in attrs:
            self._isOn = False

            self._refsUUID = UUID(attrs['uuid'])
            self._keyBuffer = self.store._refs.prepareKey(self.itemUUID,
                                                          self._refsUUID)
            self._ref = None
            self._previous = None
            self._alias = None

    def refEnd(self, attrs):

        if self._isSkipping:
            return
        
        if attrs and 'first' in attrs:
            generator = self.generator

            if self._ref is not None:
                self.store._refs.saveRef(self._keyBuffer, self._refBuffer,
                                         self.itemVersion, self._ref,
                                         self._ref, self._previous,
                                         None, self._alias)
                if self._alias is not None:
                    self.store.writeName(self.itemVersion, self._refsUUID,
                                         self._alias, self._ref)
                    
            uuid = attrs['uuid']
            del attrs['uuid']

            generator.startElement('ref', attrs)
            generator.startElement('db', None)
            generator.characters(uuid)
            generator.endElement('db')
            self._isOn = True

            self._keyBuffer.close()
            self._keyBuffer = None

        elif not self._isOn:
            uuid = UUID(self.data)

            if self._ref is not None:
                self.store._refs.saveRef(self._keyBuffer, self._refBuffer,
                                         self.itemVersion, self._ref,
                                         self._ref, self._previous,
                                         uuid, self._alias)
                if self._alias is not None:
                    self.store.writeName(self.itemVersion, self._refsUUID,
                                         self._alias, self._ref)

            self._previous = self._ref
            self._ref = uuid

            if attrs:
                self._alias = attrs.get('alias', None)
            else:
                self._alias = None

    def textStart(self, attrs):

        if not self._isSkipping:
            self._isOn = False

    def textEnd(self, attrs):

        if self._isSkipping:
            return
        
        uuid = UUID(attrs['uuid'])
        version = int(attrs['version'])
        encoding = attrs['encoding']
        compression = attrs.get('compression', None)
        store = self.store

        if encoding != 'utf-8':
            unicodeText = self.data.decode('utf-8')
            text = unicodeText.encode(encoding)
        else:
            unicodeText = None
            text = self.data

        out = store._lobs.createFile(store.lobName(uuid, version))
        if compression == 'bz2':
            out = BZ2OutputStream(out)
        elif compression == 'zlib':
            out = ZlibOutputStream(out)
        out.write(text)
        out.close()

        if attrs['indexed'] == 'True':
            if self._indexWriter is None:
                self._indexWriter = store._index.getIndexWriter()
            if unicodeText is None:
                unicodeText = text.decode(encoding)
            store._index.indexDocument(self._indexWriter,
                                       StringReader(unicodeText),
                                       uuid, self.itemUUID, self.attributeName,
                                       version)

        uuid = attrs['uuid']
        del attrs['uuid']
        attrs['type'] = 'uuid'

        self.generator.startElement('text', attrs)
        self.generator.characters(uuid)
        self._isOn = True
Exemplo n.º 4
0
class RemoteFilter(XMLFilter):
    def __init__(self, store, versionId, force=False):

        XMLFilter.__init__(self, None)

        self.store = store
        self.versionId = versionId
        self.force = force

        self._attrs = []
        self._isOn = False
        self._isSkipping = False

        self._txnStatus = 0
        self._lock = None
        self._buffer = cStringIO.StringIO()
        self._refBuffer = cStringIO.StringIO()
        self._keyBuffer = None
        self._document = None
        self._indexWriter = None
        self._count = 0

    def output(self):

        return self._isOn

    def getDocument(self):
        class doc(object):
            def __init__(self, xml):
                self._xml = xml

            def getContent(self):
                return self._xml

        return doc(self._document)

    def startElement(self, tag, attrs):

        if not self.errorOccurred():
            self.data = ''
            method = getattr(self, tag + 'Start', None)
            if method is not None:
                try:
                    method(attrs)
                except Exception:
                    self.saveException()
            self._attrs.append(attrs)

        XMLFilter.startElement(self, tag, attrs)

    def characters(self, data):

        self.data += data
        XMLFilter.characters(self, data)

    def cdataBlock(self, data):

        self.data += data
        XMLFilter.cdataBlock(self, data)

    def endElement(self, tag):

        if not self.errorOccurred():
            attrs = self._attrs.pop()
            method = getattr(self, tag + 'End', None)
            if method is not None:
                try:
                    method(attrs)
                except Exception:
                    self.saveException()
        else:
            if self._indexWriter is not None:
                self._indexWriter.close()
                self._indexWriter = None
            self.store.abortTransaction(self._txnStatus)
            self._txnStatus = 0
            if self._lock:
                self._lock = self.store.releaseLock(self._lock)

        XMLFilter.endElement(self, tag)

    def itemsStart(self, attrs):

        if attrs is not None and 'versionId' in attrs:
            versionId = UUID(attrs['versionId'])
            if versionId != self.versionId:
                raise ValueError, "remote version ids don't match"

        self._txnStatus = self.store.startTransaction()
        self._lock = self.store.acquireLock()

    def itemsEnd(self, attrs):

        if self._indexWriter is not None:
            self.store._index.optimizeIndex(self._indexWriter)
            self._indexWriter.close()
            self._indexWriter = None

        self.store.commitTransaction(self._txnStatus)
        self._txnStatus = 0
        if self._lock:
            self._lock = self.store.releaseLock(self._lock)

    def containerEnd(self, attrs):

        if not self._isSkipping:
            self.itemParent = UUID(self.data)

    def nameEnd(self, attrs):

        self.itemName = self.data

    def itemStart(self, attrs):

        self.itemUUID = UUID(attrs['uuid'])
        self.itemVersion = int(attrs['version'])

        version = self.store.getItemVersion(self.itemVersion, self.itemUUID)
        if not self.force and version == self.itemVersion:
            self._isSkipping = True
            self._isOn = False

        else:
            self._buffer.truncate(0)
            self._buffer.seek(0)
            self.generator = XMLGenerator(self._buffer)
            self.generator.startDocument()
            self._isOn = True

    def itemEnd(self, attrs):

        if not self._isSkipping:
            self.generator.endElement('item')
            self.generator.endDocument()
            self.generator = None
            self._isOn = False

            xml = self._buffer.getvalue()
            if self._document is None:
                self._document = xml

            self._count += 1
            self.store.saveItem(xml, self.itemUUID, self.itemVersion,
                                (self.itemParent, self.itemName), None, 0)

        else:
            self._isSkipping = False

    def attributeStart(self, attrs):

        if not self._isSkipping:
            self.attributeName = attrs['name']

    def refStart(self, attrs):

        if self._isSkipping:
            return

        if attrs and 'first' in attrs:
            self._isOn = False

            self._refsUUID = UUID(attrs['uuid'])
            self._keyBuffer = self.store._refs.prepareKey(
                self.itemUUID, self._refsUUID)
            self._ref = None
            self._previous = None
            self._alias = None

    def refEnd(self, attrs):

        if self._isSkipping:
            return

        if attrs and 'first' in attrs:
            generator = self.generator

            if self._ref is not None:
                self.store._refs.saveRef(self._keyBuffer, self._refBuffer,
                                         self.itemVersion, self._ref,
                                         self._ref, self._previous, None,
                                         self._alias)
                if self._alias is not None:
                    self.store.writeName(self.itemVersion, self._refsUUID,
                                         self._alias, self._ref)

            uuid = attrs['uuid']
            del attrs['uuid']

            generator.startElement('ref', attrs)
            generator.startElement('db', None)
            generator.characters(uuid)
            generator.endElement('db')
            self._isOn = True

            self._keyBuffer.close()
            self._keyBuffer = None

        elif not self._isOn:
            uuid = UUID(self.data)

            if self._ref is not None:
                self.store._refs.saveRef(self._keyBuffer, self._refBuffer,
                                         self.itemVersion, self._ref,
                                         self._ref, self._previous, uuid,
                                         self._alias)
                if self._alias is not None:
                    self.store.writeName(self.itemVersion, self._refsUUID,
                                         self._alias, self._ref)

            self._previous = self._ref
            self._ref = uuid

            if attrs:
                self._alias = attrs.get('alias', None)
            else:
                self._alias = None

    def textStart(self, attrs):

        if not self._isSkipping:
            self._isOn = False

    def textEnd(self, attrs):

        if self._isSkipping:
            return

        uuid = UUID(attrs['uuid'])
        version = int(attrs['version'])
        encoding = attrs['encoding']
        compression = attrs.get('compression', None)
        store = self.store

        if encoding != 'utf-8':
            unicodeText = self.data.decode('utf-8')
            text = unicodeText.encode(encoding)
        else:
            unicodeText = None
            text = self.data

        out = store._lobs.createFile(store.lobName(uuid, version))
        if compression == 'bz2':
            out = BZ2OutputStream(out)
        elif compression == 'zlib':
            out = ZlibOutputStream(out)
        out.write(text)
        out.close()

        if attrs['indexed'] == 'True':
            if self._indexWriter is None:
                self._indexWriter = store._index.getIndexWriter()
            if unicodeText is None:
                unicodeText = text.decode(encoding)
            store._index.indexDocument(self._indexWriter,
                                       StringReader(unicodeText), uuid,
                                       self.itemUUID, self.attributeName,
                                       version)

        uuid = attrs['uuid']
        del attrs['uuid']
        attrs['type'] = 'uuid'

        self.generator.startElement('text', attrs)
        self.generator.characters(uuid)
        self._isOn = True
Exemplo n.º 5
0
    def testItemParentChild(self):
        """Test basic attribute functionality, focusing on parent-child relationships"""
        # Test find()
        kind = self._find('//Schema/Core/Item')
        self.assert_(kind is not None)

        # Test getItemDisplayName
        self.assertEquals(kind.getItemDisplayName(), 'Item')

        # Test itsPath
        self.assertEquals(str(kind.itsPath), '//Schema/Core/Item')

        # Test simple item construction
        item = Item('test', self.rep, kind)
        self.assert_(item is not None)
        self.assert_(item.isItemOf(kind))
        self.failIf(item.isRemote())
        self.failIf(item.hasChildren())
        self.assertEquals(item.getItemDisplayName(), 'test')
        self.assertItemPathEqual(item, '//test')
        self.assertEquals(item.refCount(), 0)
        self.assert_(item.isNew())
        self.assert_(item.isDirty())
        self.failIf(item.isDeleted())
        self.failIf(item.isStale())
        self.assertEquals(self.rep.view, item.itsView)

        #TODO test toXML
        out = StringIO()
        generator = XMLPrettyGenerator(XMLGenerator(out))
        itemWriter = XMLItemWriter(generator)
        generator.startDocument()
        itemWriter.writeItem(item, item.getVersion())
        generator.endDocument()
        xml = out.getvalue()
        out.close()

        self.failIf(xml is None)

        # Test to see that item became a respository root
        self.rep.commit()
        roots = list(self.rep.iterRoots())
        self.assert_(item in roots)
        self.failIf(item.isDirty())

        # Test placing children
        child1 = Item('child1', item, kind)
        self.assertEquals(child1.getItemDisplayName(), 'child1')
        self.assertItemPathEqual(child1, '//test/child1')
        self.assert_(item.hasChildren())
        self.assert_(item.hasChild('child1'))
        item.placeChild(child1, None)
        self.assert_(item.hasChild('child1'))
        self.failIf(item.isNew())
        self.assert_(item.isDirty())

        child2 = Item('child2', item, kind)
        self.assertEquals(child2.getItemDisplayName(), 'child2')
        self.assertItemPathEqual(child2, '//test/child2')
        self.assert_(item.hasChildren())
        self.assert_(item.hasChild('child1'))
        self.assert_(item.hasChild('child2'))

        item.placeChild(child2, child1)
        self.assert_(item.hasChild('child2'))
        self.failIf(item.isNew())
        self.assert_(item.isDirty())

        self.assertEqual(item.getItemChild('child1'), child1)
        self.assertEqual(item.getItemChild('child2'), child2)
        self.assertEqual(child1.itsParent, item)
        self.assertEqual(child2.itsParent, item)

        # Test iterating over child items
        iter = item.iterChildren()
        self.assertEqual(item.getItemChild('child1'), iter.next())
        self.assertEqual(item.getItemChild('child2'), iter.next())

        #        self.failUnlessRaises(StopIteration, lambda: iter.next())

        # now write what we've done and read it back
        self._reopenRepository()
        item = self._find('//test')
        child1 = item['child1']
        child2 = item['child2']
        self.assertIsRoot(item)
        self.assert_(item.hasChildren())
        self.assert_(item.hasChild('child1'))
        self.assert_(item.hasChild('child2'))

        # Test item renaming, itsName
        kind = self._find('//Schema/Core/Item')
        child3 = Item('busted', item, kind)
        self.assertEqual(child3.itsName, 'busted')
        child3.itsName = 'busted'
        self.assertEqual(child3.itsName, 'busted')
        child3.itsName = 'child3'
        self.assertEqual(child3.itsName, 'child3')

        # Test that placing affects iteration order
        item.placeChild(child3, child1)
        iter = item.iterChildren()
        iter.next()
        self.assertEqual(child3, iter.next())
        self.assertItemPathEqual(child3, '//test/child3')
        self.assertIsRoot(child3.itsRoot)

        # Test item movement to same parent
        oldParent = child3.itsParent
        child3.itsParent = child3.itsParent
        self.assertEqual(oldParent, child3.itsParent)
        self.assertItemPathEqual(child3, '//test/child3')
        self.assertIsRoot(child3.itsRoot)

        # Test item movement to leaf item
        child3.itsParent = child2
        self.assertEqual(child2, child3.itsParent)
        self.assertItemPathEqual(child3, '//test/child2/child3')
        self.assertIsRoot(child3.itsRoot)

        # now write what we've done and read it back
        self._reopenRepository()
        item = self._find('//test')
        child1 = item['child1']
        child2 = item['child2']
        child3 = child2['child3']

        self.assertEqual(child2, child3.itsParent)
        self.assertItemPathEqual(child3, '//test/child2/child3')
        self.assertIsRoot(child3.itsRoot)

        # Test item movement to root
        child3.itsParent = self.rep
        self.assertIsRoot(child3)
        self.assertItemPathEqual(child3, '//child3')
        self.assertIsRoot(child3.itsRoot)

        # now write what we've done and read it back
        self._reopenRepository()
        item = self._find('//test')
        child1 = item['child1']
        child2 = item['child2']
        child3 = self.rep['child3']

        self.assert_(child3 in list(self.rep.iterRoots()))
        self.assertItemPathEqual(child3, '//child3')
        self.assertIsRoot(child3.itsRoot)