[Products.Silva][Sylvain Viollon] Preserve references while upda...

[email protected] Fri, 08 Nov 2013 17:27:10 +0100
Newsgroups gmane.comp.web.zope.silva.cvs
Message-ID <[email protected]>
author:    Sylvain Viollon
date:      Fri Nov 08 17:27:05 2013 +0100
revision:  11876:8b2a0402b221 in Products.Silva
branch:    2.4
details:   https://hg.infrae.com/Products.Silva?cmd=changeset;node=8b2a0402b221
modified:  Products/Silva/Ghost/base.py Products/Silva/Ghost/content.py Products/Silva/GhostAsset/content.py Products/Silva/GhostFolder/content.py Products/Silva/tests/test_ghost_folder.py
added:     
removed:   
log:       Preserve references while updating a content to a ghost.


diffstat:

 Products/Silva/Ghost/base.py              |  27 +++++++++++++++++++++++++++
 Products/Silva/Ghost/content.py           |   7 +++----
 Products/Silva/GhostAsset/content.py      |   7 +++----
 Products/Silva/GhostFolder/content.py     |   6 ++----
 Products/Silva/tests/test_ghost_folder.py |  15 ++++++++++++++-
 5 files changed, 49 insertions(+), 13 deletions(-)

diffs (133 lines):

diff -r 13f06e1c78b7 -r 8b2a0402b221 Products/Silva/Ghost/base.py
--- a/Products/Silva/Ghost/base.py	Fri Nov 08 16:36:46 2013 +0100
+++ b/Products/Silva/Ghost/base.py	Fri Nov 08 17:27:05 2013 +0100
@@ -31,6 +31,19 @@
         self.manager = manager
         self.target = target
         self.identifier = identifier
+        self.__references = []
+
+    def save_references_of(self, content):
+        service = getUtility(IReferenceService)
+        self.__references = []
+        for reference in service.get_references_to(content):
+            # Break the reference so we can replace it.
+            reference.set_target_id(0)
+            self.__references.append(reference)
+
+    def restore_references_to(self, content):
+        for reference in self.__references:
+            reference.set_target(content)
 
     def create(self):
         raise NotImplementedError
@@ -41,6 +54,20 @@
     def need_update(self):
         raise NotImplementedError
 
+    def delete(self):
+        assert self.manager.ghost is not None
+        self.manager.container.manage_delObjects([self.identifier])
+        self.manager.ghost = None
+        return None
+
+    def recreate(self):
+        # Recreate the ghost, conserving the references.
+        assert self.manager.ghost is not None
+        self.save_references_of(self.manager.ghost)
+        self.delete()
+        self.create()
+        self.restore_references_to(self.manager.ghost)
+
     def verify(self):
         if self.manager.ghost is None:
             if self.target is not None:
diff -r 13f06e1c78b7 -r 8b2a0402b221 Products/Silva/Ghost/content.py
--- a/Products/Silva/Ghost/content.py	Fri Nov 08 16:36:46 2013 +0100
+++ b/Products/Silva/Ghost/content.py	Fri Nov 08 17:27:05 2013 +0100
@@ -124,10 +124,9 @@
                 self.target, auto_delete=self.manager.auto_delete)
             if self.manager.auto_publish:
                 publication.publish()
-            return self.manager.ghost
-        self.manager.container.manage_delObjects([self.identifier])
-        self.manager.ghost = None
-        return self.create()
+        else:
+            self.recreate()
+        return self.manager.ghost
 
     def need_update(self):
         if IGhost.providedBy(self.manager.ghost):
diff -r 13f06e1c78b7 -r 8b2a0402b221 Products/Silva/GhostAsset/content.py
--- a/Products/Silva/GhostAsset/content.py	Fri Nov 08 16:36:46 2013 +0100
+++ b/Products/Silva/GhostAsset/content.py	Fri Nov 08 17:27:05 2013 +0100
@@ -81,10 +81,9 @@
         if IGhostAsset.providedBy(self.manager.ghost):
             self.manager.ghost.set_haunted(
                 self.target, auto_delete=self.manager.auto_delete)
-            return self.manager.ghost
-        self.manager.container.manage_delObjects([self.identifier])
-        self.manager.ghost = None
-        return self.create()
+        else:
+            self.recreate()
+        return self.manager.ghost
 
     def need_update(self):
         if IGhostAsset.providedBy(self.manager.ghost):
diff -r 13f06e1c78b7 -r 8b2a0402b221 Products/Silva/GhostFolder/content.py
--- a/Products/Silva/GhostFolder/content.py	Fri Nov 08 16:36:46 2013 +0100
+++ b/Products/Silva/GhostFolder/content.py	Fri Nov 08 17:27:05 2013 +0100
@@ -227,10 +227,8 @@
         if IGhostFolder.providedBy(self.manager.ghost):
             self.manager.ghost.set_haunted(
                 self.target, auto_delete=self.manager.auto_delete)
-            return None
-        self.manager.container.manage_delObjects([self.identifier])
-        self.manager.ghost = None
-        return self.create()
+        else:
+            self.recreate()
 
     def need_update(self):
         if IGhostFolder.providedBy(self.manager.ghost):
diff -r 13f06e1c78b7 -r 8b2a0402b221 Products/Silva/tests/test_ghost_folder.py
--- a/Products/Silva/tests/test_ghost_folder.py	Fri Nov 08 16:36:46 2013 +0100
+++ b/Products/Silva/tests/test_ghost_folder.py	Fri Nov 08 17:27:05 2013 +0100
@@ -9,7 +9,7 @@
 
 from Acquisition import aq_chain
 from Products.Silva.testing import FunctionalLayer
-from Products.Silva.tests.mockers import IMockupNonPublishable
+from Products.Silva.tests.mockers import IMockupAsset, IMockupNonPublishable
 from Products.SilvaMetadata.interfaces import IMetadataService, ReadOnlyError
 
 from silva.core.interfaces import IContainerManager, IPublicationWorkflow
@@ -526,6 +526,12 @@
         factory.manage_addMockupAsset('results', 'Results set 1')
         factory.manage_addMockupNonPublishable('analyze', 'Analyze set 1')
 
+        # We add a reference. It should be kept.
+        service = getUtility(IReferenceService)
+        reference = service.new_reference(self.root.folder, name=u"test")
+        reference.set_target(ghost.data)
+        self.assertTrue(verifyObject(IMockupAsset, ghost.data))
+
         # Now if we rehaunt the folder, they should be replaced by ghost assets.
         self.assertTrue(ghost.haunt())
         self.assertIn('data', ghost.objectIds())
@@ -536,6 +542,13 @@
         self.assertEqual(
             aq_chain(ghost.data.get_haunted()),
             aq_chain(self.root.folder.data))
+        # The reference should have been moved as well.
+        references = list(service.get_references_to(ghost.data, name=u"test"))
+        self.assertEqual(len(references), 1)
+        self.assertEqual(references[0].source, self.root.folder)
+        self.assertEqual(references[0].target, ghost.data)
+
+        # Other content were changed properly as well.
         self.assertIn('publication', ghost.objectIds())
         self.assertTrue(verifyObject(IGhostFolder, ghost.publication))
         self.assertIn('results', ghost.publication.objectIds())