[Erp5-report] r30160 - in /erp5/trunk/products/ERP5Type: ./ Core/

nobody at svn.erp5.org nobody at svn.erp5.org
Fri Oct 30 16:03:31 CET 2009


Author: jm
Date: Fri Oct 30 16:03:30 2009
New Revision: 30160

URL: http://svn.erp5.org?rev=30160&view=rev
Log:
Rewrite ERP5TypeInformation.getInstance* to reduce code duplication

* Move creation of temporary instances from Folder.newContent to
  ERP5TypeInformation.constructInstance.
* Use temporary object and PropertyHolder (if possible) to get list of
  categories and properties.
* Also rewrite
  TranslationProviderBase.updateInitialPropertyTranslationDomainDict

Modified:
    erp5/trunk/products/ERP5Type/Core/Folder.py
    erp5/trunk/products/ERP5Type/ERP5Type.py
    erp5/trunk/products/ERP5Type/TranslationProviderBase.py

Modified: erp5/trunk/products/ERP5Type/Core/Folder.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/Folder.py?rev=30160&r1=30159&r2=30160&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Core/Folder.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/Folder.py [utf8] Fri Oct 30 16:03:30 2009
@@ -148,24 +148,15 @@
           'portal_trash' not in container.getPhysicalPath():
         raise ValueError('Disallowed subobject type: %s' % portal_type)
 
-    # Use the factory even if the parent is already a temp object,
-    # like this we do not call the classic way, indeed, we do not
-    # need to call init script, security settings on temp objects.
-    if temp_object or temp_container:
-      type_info = pt.getTypeInfo(portal_type)
-      if not type_info.factory or not type_info.factory.startswith('add'):
-        raise ValueError('Product factory for %s is invalid: %s' %
-                         (portal_type, type_info.factory))
-      p = container.manage_addProduct[type_info.product]
-      m = getattr(p, 'newTemp' + type_info.factory[3:])
-      new_instance = m(new_id, container)
-      if hasattr(new_instance, '_setPortalTypeName'):
-        new_instance._setPortalTypeName(portal_type)
-    else:
-      pt.constructContent( type_name=portal_type,
+    type_info = pt.getTypeInfo(portal_type)
+    if type_info is None:
+      raise ValueError('No such content type: %s' % portal_type)
+
+    new_instance = type_info.constructInstance(
                            container=container,
                            id=new_id,
                            created_by_builder=created_by_builder,
+                           temp_object=temp_object or temp_container,
                            activate_kw=activate_kw,
                            reindex_kw=reindex_kw,
                            is_indexable=is_indexable
@@ -173,7 +164,6 @@
       # TODO :the **kw makes it impossible to create content not based on
       # ERP5TypeInformation, because factory method often do not support
       # keywords arguments.
-      new_instance = container[new_id]
 
     if kw != {} : new_instance._edit(force_update=1, **kw)
     if immediate_reindex: new_instance.immediateReindexObject()

Modified: erp5/trunk/products/ERP5Type/ERP5Type.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/ERP5Type.py?rev=30160&r1=30159&r2=30160&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/ERP5Type.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/ERP5Type.py [utf8] Fri Oct 30 16:03:30 2009
@@ -30,6 +30,7 @@
 from Products.CMFCore.exceptions import AccessControl_Unauthorized
 from Products.CMFCore.utils import _checkPermission
 from Products.ERP5Type import interfaces, Constraint, Permissions, PropertySheet
+from Products.ERP5Type.Base import getClassPropertyList
 from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
 from Products.ERP5Type.Utils import deprecated, createExpressionContext
 from Products.ERP5Type.XMLObject import XMLObject
@@ -376,14 +377,24 @@
         return default
 
     security.declarePublic('constructInstance')
-    def constructInstance( self, container, id,
-                           created_by_builder=0, *args, **kw ):
-        """
-        Build a "bare" instance of the appropriate type in
-        'container', using 'id' as its id.
-        Call the init_script for the portal_type.
-        Returns the object.
-        """
+    def constructInstance(self, container, id, created_by_builder=0,
+                          temp_object=0, *args, **kw ):
+      """
+      Build a "bare" instance of the appropriate type in
+      'container', using 'id' as its id.
+      Call the init_script for the portal_type.
+      Returns the object.
+      """
+      if temp_object:
+        if not self.factory or not self.factory.startswith('add'):
+          raise ValueError('Product factory for %s is invalid: %s'
+                            % (self.getId(), self.factory))
+        p = container.manage_addProduct[self.product]
+        m = getattr(p, 'newTemp' + self.factory[3:])
+        ob = m(id, container)
+        if hasattr(ob, '_setPortalTypeName'):
+          ob.portal_type = self.getId()
+      else:
         # This is part is copied from CMFCore/TypesTool/constructInstance
         # In case of temp object, we don't want to check security
         if (not (hasattr(container, 'isTempObject')
@@ -418,7 +429,12 @@
           kw['created_by_builder'] = created_by_builder
           getattr(ob, init_script)(*args, **kw)
 
-        return ob
+      return ob
+
+    def _getPropertyHolder(self):
+      ob = self.constructInstance(self, '', temp_object=1)
+      ob._aq_dynamic('id')
+      return ob.aq_portal_type[ob._aq_key()]
 
     security.declarePrivate('updatePropertySheetDefinitionDict')
     def updatePropertySheetDefinitionDict(self, definition_dict):
@@ -451,61 +467,27 @@
                               'getInstanceBaseCategoryList')
     def getInstanceBaseCategoryList(self):
       """ Return all base categories of the portal type """
-      # try to get categories from a temporary object if possible
-      module = self.getPortalObject().getDefaultModule(self.getId())
-      if module is not None:
-        return module.newContent(portal_type=self.getId(), temp_object=1).getBaseCategoryList()
-
-      # XXX The following does not return the list of all categories currently
-      #     (as implementation does not follow exactly the accessor generation,
-      #     like for Expression evaluation). Should be probably better to get
-      #     the list from property holder and not from property sheet
-      # get categories from portal type
-      base_category_set = set(self.getTypeBaseCategoryList())
-
-      # get categories from property sheet
-      ps_list = [getattr(PropertySheet, p, None)
-                 for p in self.getTypePropertySheetList()]
-      # from the property sheets defined on the class
-      m = Products.ERP5Type._m
-      if m.has_key(self.factory):
-        klass = m[self.factory].klass
-        if klass is not None:
-          from Products.ERP5Type.Base import getClassPropertyList
-          ps_list += getClassPropertyList(klass)
-
-      # XXX Can't return set to restricted code in Zope 2.8.
-      return list(base_category_set.union(category
-        for base in ps_list
-        for category in getattr(base, '_categories', ())))
+      return list(self._getPropertyHolder()._categories)
 
     security.declareProtected(Permissions.AccessContentsInformation,
                               'getInstancePropertyAndBaseCategoryList')
     def getInstancePropertyAndBaseCategoryList(self):
       """Return all the properties and base categories of the portal type. """
+      # PropertHolder._properties doesn't contain 'content' properties.
+      ob = self.constructInstance(self, '', temp_object=1)
+      property_list = list(getattr(ob.__class__, '_properties', []))
+      self.updatePropertySheetDefinitionDict({'_properties': property_list})
+      for property_sheet in getClassPropertyList(ob.__class__):
+        property_list += property_sheet._properties
+
       return_set = set()
-
-      # get the property sheet list for the portal type
-      ps_list = [getattr(PropertySheet, p, None)
-                 for p in self.getTypePropertySheetList()]
-      m = Products.ERP5Type._m
-      if m.has_key(self.factory):
-        klass = m[self.factory].klass
-        if klass is not None:
-          from Products.ERP5Type.Base import getClassPropertyList
-          ps_list += getClassPropertyList(klass)
-      # get all properties from the property sheet list
-      for base in ps_list:
-        property_list = getattr(base, '_properties', None)
-        if property_list:
-          for property in property_list:
-            if property['type'] == 'content':
-              for suffix in property['acquired_property_id']:
-                return_set.add(property['id'] + '_' + suffix)
-            else:
-              return_set.add(property['id'])
-      # get base categories
-      for category in self.getInstanceBaseCategoryList():
+      for property in property_list:
+        if property['type'] == 'content':
+          for suffix in property['acquired_property_id']:
+            return_set.add(property['id'] + '_' + suffix)
+        else:
+          return_set.add(property['id'])
+      for category in ob.getBaseCategoryList():
         return_set.add(category)
         return_set.add(category + '_free_text')
 
@@ -517,22 +499,8 @@
     def getInstancePropertyMap(self):
       """
       Returns the list of properties which are specific to the portal type.
-
-      We do this by creating a temp object at the root of the portal
-      and invoking propertyMap
-      """
-      # Access the factory method for temp object by guessing it
-      # according to ERP5 naming conventions (not very nice)
-      factory_method_id = self.factory.replace('add', 'newTemp', 1)
-      if not factory_method_id.startswith('newTemp'):
-        raise
-      factory_method = getattr(Products.ERP5Type.Document, factory_method_id)
-      id = "some_very_unlikely_temp_object_id_which_should_not_exist"
-      portal = self.getPortalObject()
-      portal_ids = portal.objectIds()
-      while id in portal_ids:
-        id = id + "d"
-      return factory_method(portal, id).propertyMap()
+      """
+      return self.constructInstance(self, '', temp_object=1).propertyMap()
 
     def _edit(self, *args, **kw):
       """

Modified: erp5/trunk/products/ERP5Type/TranslationProviderBase.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/TranslationProviderBase.py?rev=30160&r1=30159&r2=30160&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/TranslationProviderBase.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/TranslationProviderBase.py [utf8] Fri Oct 30 16:03:30 2009
@@ -58,34 +58,18 @@
     """
     property_domain_dict = {}
 
-    # get the property sheet list for the portal type
-    ps_list = [getattr(PropertySheet, p, None)
-                for p in self.getTypePropertySheetList()]
-    m = Products.ERP5Type._m
-    if m.has_key(self.factory):
-      klass = m[self.factory].klass
-      if klass is not None:
-        from Products.ERP5Type.Base import getClassPropertyList
-        ps_list += getClassPropertyList(klass)
-    # create TranslationInformation object for each property
-    for base in ps_list:
-      for prop in getattr(base, '_properties', ()):
-        prop_id = prop['id']
-        if prop.get('translatable') and prop_id not in property_domain_dict:
-          domain_name = prop.get('translation_domain')
-          property_domain_dict[prop_id] = TranslationInformation(prop_id,
-                                                                 domain_name)
+    for prop in self._getPropertyHolder()._properties:
+      prop_id = prop['id']
+      if prop.get('translatable') and prop_id not in property_domain_dict:
+        domain_name = prop.get('translation_domain')
+        property_domain_dict[prop_id] = TranslationInformation(prop_id,
+                                                               domain_name)
 
     original_property_domain_dict = getattr(aq_base(self),
                                             '_property_domain_dict', _MARKER)
-    original_property_domain_keys = original_property_domain_dict.keys()
-    property_domain_keys = property_domain_dict.keys()
-    property_domain_keys.sort()
-    original_property_domain_keys.sort()
-
     # Only update if required in order to prevent ZODB from growing
     if original_property_domain_dict is _MARKER or\
-          property_domain_keys != original_property_domain_keys:
+       sorted(property_domain_dict) != sorted(original_property_domain_dict):
       # Update existing dict
       property_domain_dict.update(original_property_domain_dict)
       # And store




More information about the Erp5-report mailing list