From 3c43fe1fc800fa8b70cc92ed95dc1bdb8326009a Mon Sep 17 00:00:00 2001
From: Yoshinori Okuji <yo@nexedi.com>
Date: Wed, 20 Oct 2010 11:20:39 +0000
Subject: [PATCH] No need to hardcode so much for the bootstrap.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@39386 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/Dynamic/portaltypeclass.py | 72 ++++++++++-----------
 1 file changed, 35 insertions(+), 37 deletions(-)

diff --git a/product/ERP5Type/Dynamic/portaltypeclass.py b/product/ERP5Type/Dynamic/portaltypeclass.py
index 932957a76c..b270eed05d 100644
--- a/product/ERP5Type/Dynamic/portaltypeclass.py
+++ b/product/ERP5Type/Dynamic/portaltypeclass.py
@@ -115,42 +115,22 @@ def portal_type_factory(portal_type_name):
   mixin_list = []
   interface_list = []
   accessor_holder_list = []
-  # two exceptions that cant be loaded from types tool:
-  if portal_type_name == "Base Type":
-    # avoid chicken and egg issue:
-    # you can access portal_types/Foo if you havent
-    # loaded Base Type class, but you cant load
-    # Base Type class without accessing portal_types/Base Type
-    type_class = "ERP5TypeInformation"
-  elif portal_type_name == "Solver Type":
-    type_class = "SolverTypeInformation"
-  elif portal_type_name == "Business Template":
-    # When installing a BT, Business Templates are loaded
-    # before creating any Base Type object
-    type_class = "BusinessTemplate"
-  elif portal_type_name == "Base Category":
-    # 'elementary_type' is a Base Category needed for Standard
-    # Property and Acquired Property
-    type_class = "BaseCategory"
-  elif portal_type_name == "Category":
-    # 'elementary_type' sub-categories are needed for Standard
-    # Property and Acquired Property
-    type_class = "Category"
-  else:
-    from Products.ERP5.ERP5Site import getSite
-    site = getSite()
 
-    type_tool = site.portal_types
-    try:
-      portal_type = getattr(type_tool, portal_type_name)
-    except:
-      import traceback; traceback.print_stack()
-      raise AttributeError('portal type %s not found in Types Tool' \
-                              % portal_type_name)
-
-    # type_class has a compatibility getter that should return
-    # something even if the field is not set (i.e. Base Type object
-    # was not migrated yet)
+  from Products.ERP5.ERP5Site import getSite
+  site = getSite()
+
+  type_tool = site.portal_types
+  try:
+    portal_type = getattr(type_tool, portal_type_name)
+  except:
+    import traceback; traceback.print_stack()
+    raise AttributeError('portal type %s not found in Types Tool' \
+                            % portal_type_name)
+
+  # type_class has a compatibility getter that should return
+  # something even if the field is not set (i.e. Base Type object
+  # was not migrated yet)
+  try:
     type_class = portal_type.getTypeClass()
 
     # But no such getter exists for Mixins and Interfaces:
@@ -158,13 +138,31 @@ def portal_type_factory(portal_type_name):
     try:
       mixin_list = portal_type.getTypeMixinList()
       interface_list = portal_type.getTypeInterfaceList()
-    except:
+    except StandardError:
       # log loudly the error, but it's not _critical_
       LOG("ERP5Type.Dynamic", ERROR,
           "Could not load interfaces or Mixins for portal type %s" \
               % portal_type_name)
+  except AttributeError:
+    # Try to figure out a coresponding document class from the document side.
+    # This is required for the bootstrap (e.g. Base Type).
+    for name, path in document_class_registry.iteritems():
+      # XXX heuristic: bootstrap issues should happen only inside ERP5Type.
+      if not path.startswith('Products.ERP5Type.'):
+        continue
+      klass = _import_class(path)
+      try:
+        try:
+          document_portal_type = getattr(klass, 'portal_type')
+          if document_portal_type == portal_type_name:
+            type_class = name
+            break
+        except AttributeError:
+          pass
+      finally:
+        del klass
 
-    import erp5
+  import erp5
 
 #broken#    # Initialize filesystem Property Sheets accessor holders
 #broken#    _fill_accessor_holder_list(
-- 
2.30.9