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
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
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
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)