From dbc4a6aa36e6abd0de932dd7405e020f272bbcac Mon Sep 17 00:00:00 2001
From: Jean-Paul Smets <jp@nexedi.com>
Date: Mon, 18 Sep 2006 18:54:12 +0000
Subject: [PATCH] First working implementation of temporary sub content

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@10125 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/Base.py               |  5 ++++-
 product/ERP5Type/ERP5Type.py           | 17 ++++++++---------
 product/ERP5Type/Utils.py              | 12 +++++++++---
 product/ERP5Type/tests/testERP5Type.py |  7 +++++++
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py
index 48061ae235..1e8ea1bb41 100644
--- a/product/ERP5Type/Base.py
+++ b/product/ERP5Type/Base.py
@@ -1852,8 +1852,11 @@ class Base( CopyContainer, PortalContent, ActiveObject, Historical, ERP5Property
   def isTempObject(self):
     """
       Tells if an object is temporary or not
+
+      Implementation is based on the fact that reindexObject method is overloaded
+      for all TempObjects with the same dummy method
     """
-    return self.reindexObject is self._temp_reindexObject
+    return self.reindexObject.im_func is self._temp_reindexObject.im_func
 
   # Workflow Related Method
   security.declarePublic('getWorkflowStateItemList')
diff --git a/product/ERP5Type/ERP5Type.py b/product/ERP5Type/ERP5Type.py
index ced8b13248..435a7707bc 100644
--- a/product/ERP5Type/ERP5Type.py
+++ b/product/ERP5Type/ERP5Type.py
@@ -21,10 +21,10 @@
 ##############################################################################
 
 from Globals import InitializeClass, DTMLFile
-from exceptions import AccessControl_Unauthorized
 from AccessControl import ClassSecurityInfo, getSecurityManager
 from Acquisition import aq_base, aq_inner, aq_parent
 
+import Products
 import Products.CMFCore.TypesTool
 from Products.CMFCore.TypesTool import TypeInformation
 from Products.CMFCore.TypesTool import FactoryTypeInformation
@@ -34,6 +34,7 @@ from Products.CMFCore.interfaces.portal_types import ContentTypeInformation\
 from Products.CMFCore.ActionProviderBase import ActionProviderBase
 from Products.CMFCore.utils import SimpleItemWithProperties
 from Products.CMFCore.Expression import createExprContext
+from Products.CMFCore.exceptions import AccessControl_Unauthorized
 from Products.ERP5Type import PropertySheet
 from Products.ERP5Type import _dtmldir
 from Products.ERP5Type import Permissions
@@ -183,8 +184,9 @@ class ERP5TypeInformation( FactoryTypeInformation,
                                self.getId())
         p = container.manage_addProduct[self.product]
         if hasattr(container, 'isTempObject') and container.isTempObject():
-          factory_name = self.factory
-          factory_name.replace('add', 'newTemp')
+          factory_name = self.factory.replace('add', 'newTemp') # We suppose here
+                         # that methods are names addClass or newTempClass
+                         # Prefix should be moved to a central place.
           m = getattr(p, factory_name, None)
         else:
           m = getattr(p, self.factory, None)
@@ -233,8 +235,7 @@ class ERP5TypeInformation( FactoryTypeInformation,
             Return list of content types.
             XXX I (seb) think the name is bad
         """
-        from Products.ERP5Type import PropertySheet
-        result = PropertySheet.__dict__.keys()
+        result = Products.ERP5Type.PropertySheet.__dict__.keys()
         result = filter(lambda k: not k.startswith('__'),  result)
         result.sort()
         return result
@@ -265,8 +266,7 @@ class ERP5TypeInformation( FactoryTypeInformation,
     security.declareProtected(Permissions.AccessContentsInformation,
                               'getConstraintList')
     def getConstraintList( self ):
-        from Products.ERP5Type import Constraint
-        result = Constraint.__dict__.keys()
+        result = Products.ERP5Type.Constraint.__dict__.keys()
         result = filter(lambda k: k != 'Constraint' and not k.startswith('__'),
                         result)
         result.sort()
@@ -368,13 +368,12 @@ class ERP5TypeInformation( FactoryTypeInformation,
       We do this by creating a temp object at the root of the portal
       and invoking propertyMap
       """
-      from Products.ERP5Type import Document
       # 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(Document, factory_method_id)
+      factory_method = getattr(Products.ERP5Type.Document, factory_method_id)
       id = "some_very_unlikely_temp_object_id_which_should_not_exist"
       portal = self.portal_url.getPortalObject()
       portal_ids = portal.objectIds()
diff --git a/product/ERP5Type/Utils.py b/product/ERP5Type/Utils.py
index b32936247e..8ca5aa44eb 100644
--- a/product/ERP5Type/Utils.py
+++ b/product/ERP5Type/Utils.py
@@ -351,9 +351,13 @@ class TempDocumentConstructor(DocumentConstructor):
       for k in ('isIndexable', 'reindexObject', 'recursiveReindexObject',
                 'activate', 'setUid', 'setTitle', 'getTitle'):
         setattr(o, k, getattr(o,"_temp_%s" % k))
-      o = o.__of__(folder)
       if kw:
         o.__of__(folder)._edit(force_update=1, **kw)
+      if folder.isTempObject(): # Temp Object in Temp Object should use containment
+        folder._setObject(id, o)
+        return id               # return id to be compatible with CMF constructInstance
+      else:                     # Temp Object in Persistent Object should use acquisition
+        o = o.__of__(folder)
       return o
 
 
@@ -685,7 +689,7 @@ def importLocalDocument(class_id, document_path = None):
           temp_document_constructor_name,
           temp_document_constructor)
   ModuleSecurityInfo('Products.ERP5Type.Document').declarePublic(
-                      temp_document_constructor_name,)
+                      temp_document_constructor_name,) # XXX Probably bad security
 
   # Update Meta Types
   new_meta_types = []
@@ -713,12 +717,14 @@ def importLocalDocument(class_id, document_path = None):
     constructors = ( manage_addContentForm
                    , manage_addContent
                    , document_constructor
+                   , temp_document_constructor
                    , ('factory_type_information',
                         document_class.factory_type_information) )
   else:
     constructors = ( manage_addContentForm
                    , manage_addContent
-                   , document_constructor )
+                   , document_constructor
+                   , temp_document_constructor )
   initial = constructors[0]
   m[initial.__name__]=manage_addContentForm
   default_permission = ('Manager',)
diff --git a/product/ERP5Type/tests/testERP5Type.py b/product/ERP5Type/tests/testERP5Type.py
index df365ed7c8..dabd93ee94 100644
--- a/product/ERP5Type/tests/testERP5Type.py
+++ b/product/ERP5Type/tests/testERP5Type.py
@@ -150,6 +150,13 @@ class TestERP5Type(ERP5TypeTestCase, LogInterceptor):
       o.edit(tata=123)
       self.assertEquals(o.getProperty('tata'), 123)
 
+      # Make sure this is a Temp Object
+      self.assertEquals(o.isTempObject(), 1)
+
+      # Create a subobject and make sure it is a Temp Object
+      a = o.newContent(portal_type = 'Telephone')
+      self.assertEquals(a.isTempObject(), 1)
+
     def test_04_CategoryAccessors(self, quiet=quiet, run=run_all_test):
       """
         This test provides basic testing of category
-- 
2.30.9