Commit 4dde4bdf authored by Yoshinori Okuji's avatar Yoshinori Okuji

Define isTempDocument to specify if an object is a temporary object or...

Define isTempDocument to specify if an object is a temporary object or persistent object, rather than using a hack. Remove hasattr in TempDocumentConstructor. Write a test for _aq_dynamic with a temporary object. Remove an unused test. Make it safe to call _aq_dynamic with a temporary object.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14005 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b3a6d79c
......@@ -407,6 +407,7 @@ class Base( CopyContainer,
isPredicate = 0 #
isTemplate = 0 #
isDocument = 0 #
isTempDocument = 0 # If set to 0, instances are temporary.
# Dynamic method acquisition system (code generation)
aq_method_generated = {}
......@@ -490,6 +491,13 @@ class Base( CopyContainer,
# Proceed with property generation
klass = self.__class__
if self.isTempObject():
# If self is a temporary object, generate methods for the base
# document class rather than for the temporary document class.
# Otherwise, instances of the base document class would fail
# in calling such methods, because they are not instances of
# the temporary document class.
klass = klass.__bases__[0]
generated = 0 # Prevent infinite loops
# Generate class methods
......@@ -2114,13 +2122,9 @@ class Base( CopyContainer,
security.declarePublic('isTempObject')
def isTempObject(self):
"""Return true if self is an instance of a temporary document class.
"""
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.im_func is self._temp_reindexObject.im_func
return getattr(self.__class__, 'isTempDocument', 0)
# Workflow Related Method
security.declarePublic('getWorkflowStateItemList')
......@@ -2916,6 +2920,7 @@ class TempBase(Base):
we shoud used TempBase
"""
isIndexable = 0
isTempDocument = 1
# Declarative security
security = ClassSecurityInfo()
......
......@@ -350,6 +350,7 @@ class TempDocumentConstructor(DocumentConstructor):
def __init__(self, klass):
# Create a new class to set permissions specific to temporary objects.
class TempDocument(klass):
isTempDocument = 1
pass
# Replace some attributes.
......@@ -369,7 +370,8 @@ class TempDocumentConstructor(DocumentConstructor):
o = self.klass(id)
if kw:
o.__of__(folder)._edit(force_update=1, **kw)
if hasattr(folder, 'isTempObject') and folder.isTempObject():
isTempObject = getattr(folder, 'isTempObject', None)
if isTempObject is not None and isTempObject():
folder._setObject(id, o)# Temp Object in Temp Object should use containment
return id # return id to be compatible with CMF constructInstance
else: # Temp Object in Persistent Object should use acquisition
......
......@@ -209,19 +209,8 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
self.failUnless(business_template.getTitle()==test_string)
# Test Dynamic Code Generation
def test_01_AqDynamic(self):
portal = self.getPortal()
#module = portal.person
from Products.ERP5Type.Base import initializeClassDynamicProperties
from Products.ERP5Type.Base import initializePortalTypeDynamicProperties
from Products.ERP5Type.Base import Base
from Products.ERP5Type import Document
initializeClassDynamicProperties(portal, Base)
# Base class should now have a state method
# self.failUnless(hasattr(Base, 'getFirstName'))
# This test is now useless since methods are portal type based
def test_02_AqDynamic(self):
def test_02_AqDynamic(self, quiet=quiet, run=run_all_test):
if not run: return
portal = self.getPortal()
module = self.getPersonModule()
person = module.newContent(id='1', portal_type='Person')
......@@ -1273,6 +1262,72 @@ class TestPropertySheet:
checked_permission="View"),
[doo.getTitle(), bar.getTitle(), ])
def test_25_AqDynamicWithTempObject(self, quiet=quiet, run=run_all_test):
"""Check if _aq_dynamic works correctly, regardless of whether
it is first called for a temporary object or a persistent object.
This test is based on the fact that a portal type is shared between
a temporary document and a persistent document, and if a class for
the temporary document is used for generating new methods, calling
such methods from a persistent object may fail, because such a
persistent object is not an instance of the temporary document class.
"""
if not run: return
portal = self.getPortal()
# Clear out all generated methods.
_aq_reset()
# Create a new temporary person object.
from Products.ERP5Type.Document import newTempPerson
o = newTempPerson(portal, 'temp_person_1')
self.failUnless(o.isTempObject())
# This should generate a workflow method.
self.assertEquals(o.getValidationState(), 'draft')
o.validate()
self.assertEquals(o.getValidationState(), 'validated')
# Create a new persistent person object.
person_module = portal.person_module
person_id = 'person_1'
if person_id in person_module.objectIds():
person_module.manage_delObjects([person_id])
o = person_module.newContent(id=person_id, portal_type='Person')
self.failIf(o.isTempObject())
# This should call methods generated above for the temporary object.
self.assertEquals(o.getValidationState(), 'draft')
o.validate()
self.assertEquals(o.getValidationState(), 'validated')
# Paranoia: test the reverse snenario as well, although this
# should succeed anyway.
# Create a new persistent person object.
person_id = 'person_2'
if person_id in person_module.objectIds():
person_module.manage_delObjects([person_id])
o = person_module.newContent(id=person_id, portal_type='Person')
self.failIf(o.isTempObject())
# Clear out all generated methods.
_aq_reset()
# This should generate workflow methods.
self.assertEquals(o.getValidationState(), 'draft')
o.validate()
self.assertEquals(o.getValidationState(), 'validated')
# Create a new temporary person object.
o = newTempPerson(portal, 'temp_person_2')
self.failUnless(o.isTempObject())
# This should call methods generated for the persistent object.
self.assertEquals(o.getValidationState(), 'draft')
o.validate()
self.assertEquals(o.getValidationState(), 'validated')
if __name__ == '__main__':
framework()
else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment