From 3ed753c673cab71aae83bb469bc2bac002c60d75 Mon Sep 17 00:00:00 2001
From: Julien Muchembled <jm@nexedi.com>
Date: Mon, 21 Feb 2011 11:05:13 +0000
Subject: [PATCH] Fix several bootstrap issues

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@43514 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/Tool/BaseTool.py             |  2 +-
 product/ERP5Type/Tool/TypesTool.py            |  2 +
 product/ERP5Type/dynamic/portal_type_class.py | 89 +++++++++----------
 3 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/product/ERP5Type/Tool/BaseTool.py b/product/ERP5Type/Tool/BaseTool.py
index 1da4a8a8dd..8285f2b9d7 100644
--- a/product/ERP5Type/Tool/BaseTool.py
+++ b/product/ERP5Type/Tool/BaseTool.py
@@ -77,7 +77,7 @@ class BaseTool (UniqueObject, Folder):
           id_set = set(x[:-4] for x in files if x[-4:] == '.xml')
         else:
           id_set = set(quote(x) for x in content_id_list)
-          id_set.difference_update(self.objectIds())
+          id_set.difference_update(quote(x) for x in self.objectIds())
         dirs[:] = id_set.intersection(dirs)
         for file in id_set:
           load(os.path.join(root, file + '.xml'),
diff --git a/product/ERP5Type/Tool/TypesTool.py b/product/ERP5Type/Tool/TypesTool.py
index 1b75140c31..d2ed4299d2 100644
--- a/product/ERP5Type/Tool/TypesTool.py
+++ b/product/ERP5Type/Tool/TypesTool.py
@@ -128,6 +128,8 @@ class TypesTool(TypeProvider):
       'Standard Property',
       'Acquired Property',
       'Dummy Class Tool',
+      # the following ones are required to upgrade an existing site
+      'Category Property',
     ))
 
   def listContentTypes(self, container=None):
diff --git a/product/ERP5Type/dynamic/portal_type_class.py b/product/ERP5Type/dynamic/portal_type_class.py
index 83ca9d4c02..908a6275c1 100644
--- a/product/ERP5Type/dynamic/portal_type_class.py
+++ b/product/ERP5Type/dynamic/portal_type_class.py
@@ -399,51 +399,8 @@ def initializeDynamicModules():
   erp5.temp_portal_type = registerDynamicModule('erp5.temp_portal_type',
                                                 loadTempPortalTypeClass)
 
-def _maybe_bootstrap(portal):
-  global _maybe_bootstrap
-  bootstrap = None
-  from Products.ERP5Type.Tool.PropertySheetTool import PropertySheetTool
-  from Products.ERP5Type.Tool.TypesTool import TypesTool
-  for tool_class in TypesTool, PropertySheetTool:
-    # if the instance has no property sheet tool, or incomplete
-    # property sheets, we need to import some data to bootstrap
-    # (only likely to happen on the first run ever)
-    tool_id = tool_class.id
-    tool = getattr(portal, tool_id, None)
-    if tool is None:
-      tool = tool_class()
-      try:
-        portal._setObject(tool_id, tool, set_owner=False, suppress_events=True)
-      except TypeError:
-        portal._setObject(tool_id, tool, set_owner=False)
-      tool = getattr(portal, tool_id)
-    elif not tool._isBootstrapRequired():
-      continue
-
-    if not bootstrap:
-      LOG('ERP5Site', INFO, 'bootstrap %s...' % tool_id)
-      from Products.ERP5.ERP5Site import getBootstrapDirectory
-      bootstrap = getBootstrapDirectory()
-      cwd = os.getcwd()
-    try:
-      os.chdir(bootstrap)
-      tool._bootstrap()
-    finally:
-      os.chdir(cwd)
-
-  if bootstrap:
-    if not getattr(portal, '_v_bootstrapping', False):
-      LOG('ERP5Site', INFO, 'Transition successful, please update your'
-          ' business templates')
-    # XXX: if some portal types are missing, for instance
-    # if some Tools have no portal types, this is likely to fail with an
-    # error. On the other hand, we can't proceed without this change,
-    # and if we dont import the xml, the instance wont start.
-    portal.migrateToPortalTypeClass()
-
-  _maybe_bootstrap = lambda portal: None
-
 last_sync = -1
+_bootstrapped = set()
 def synchronizeDynamicModules(context, force=False):
   """
   Allow resetting all classes to ghost state, most likely done after
@@ -473,7 +430,49 @@ def synchronizeDynamicModules(context, force=False):
 
   Base.aq_method_lock.acquire()
   try:
-    _maybe_bootstrap(portal)
+    if portal.id not in _bootstrapped:
+      bootstrap = None
+      from Products.ERP5Type.Tool.PropertySheetTool import PropertySheetTool
+      from Products.ERP5Type.Tool.TypesTool import TypesTool
+      for tool_class in TypesTool, PropertySheetTool:
+        # if the instance has no property sheet tool, or incomplete
+        # property sheets, we need to import some data to bootstrap
+        # (only likely to happen on the first run ever)
+        tool_id = tool_class.id
+        tool = getattr(portal, tool_id, None)
+        if tool is None:
+          tool = tool_class()
+          try:
+            portal._setObject(tool_id, tool, set_owner=False, suppress_events=True)
+          except TypeError:
+            portal._setObject(tool_id, tool, set_owner=False)
+          tool = getattr(portal, tool_id)
+        elif not tool._isBootstrapRequired():
+          continue
+
+        if not bootstrap:
+          LOG('ERP5Site', INFO, 'bootstrap %s...' % tool_id)
+          from Products.ERP5.ERP5Site import getBootstrapDirectory
+          bootstrap = getBootstrapDirectory()
+          cwd = os.getcwd()
+        try:
+          os.chdir(bootstrap)
+          tool._bootstrap()
+        finally:
+          os.chdir(cwd)
+
+      if bootstrap:
+        if not getattr(portal, '_v_bootstrapping', False):
+          LOG('ERP5Site', INFO, 'Transition successful, please update your'
+              ' business templates')
+        # XXX: if some portal types are missing, for instance
+        # if some Tools have no portal types, this is likely to fail with an
+        # error. On the other hand, we can't proceed without this change,
+        # and if we dont import the xml, the instance wont start.
+        portal.migrateToPortalTypeClass()
+
+      _bootstrapped.add(portal.id)
+
     LOG("ERP5Type.dynamic", 0, "Resetting dynamic classes")
     for class_name, klass in inspect.getmembers(erp5.portal_type,
                                                 inspect.isclass):
-- 
2.30.9