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

Use a transactional variable instead of a transaction object for acquisition...

Use a transactional variable instead of a transaction object for acquisition stacks. Remove unneeded imports.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@13755 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 1b3b7b62
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
from struct import unpack from struct import unpack
import warnings import warnings
import ExtensionClass
from Globals import InitializeClass, DTMLFile, PersistentMapping from Globals import InitializeClass, DTMLFile
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from AccessControl.Permission import pname, Permission from AccessControl.Permission import pname, Permission
from AccessControl.PermissionRole import rolesForPermissionOn from AccessControl.PermissionRole import rolesForPermissionOn
...@@ -56,7 +55,7 @@ from Products.ERP5Type.Cache import CachingMethod, clearCache, getReadOnlyTransa ...@@ -56,7 +55,7 @@ from Products.ERP5Type.Cache import CachingMethod, clearCache, getReadOnlyTransa
from Products.CMFCore.WorkflowCore import ObjectDeleted from Products.CMFCore.WorkflowCore import ObjectDeleted
from Accessor import WorkflowState from Accessor import WorkflowState
from Products.ERP5Type.Log import log as unrestrictedLog from Products.ERP5Type.Log import log as unrestrictedLog
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from ZopePatch import ERP5PropertyManager from ZopePatch import ERP5PropertyManager
from CopySupport import CopyContainer, CopyError,\ from CopySupport import CopyContainer, CopyError,\
...@@ -69,22 +68,14 @@ from Products.ERP5Type.Accessor.TypeDefinition import asDate ...@@ -69,22 +68,14 @@ from Products.ERP5Type.Accessor.TypeDefinition import asDate
from string import join from string import join
import sys import sys
import psyco import psyco
import traceback
from cStringIO import StringIO from cStringIO import StringIO
from socket import gethostname, gethostbyaddr from socket import gethostname, gethostbyaddr
import random import random
from DateTime import DateTime
import inspect import inspect
from pprint import pformat from pprint import pformat
try:
from transaction import get as get_transaction
except ImportError:
pass
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
from zLOG import LOG, INFO, ERROR, WARNING from zLOG import LOG, INFO, ERROR, WARNING
...@@ -682,120 +673,112 @@ class Base( CopyContainer, ...@@ -682,120 +673,112 @@ class Base( CopyContainer,
Other case : we want to change the phone number of a related object without Other case : we want to change the phone number of a related object without
going to edit the related object going to edit the related object
""" """
# Push context to prevent loop # Push context to prevent loop
# We use TRANSACTION but should use REQUEST tv = getTransactionalVariable()
from Globals import get_request
TRANSACTION = get_transaction()
if not hasattr(TRANSACTION, '_erp5_acquisition_stack'): TRANSACTION._erp5_acquisition_stack = {}
if isinstance(portal_type, list): if isinstance(portal_type, list):
portal_type = tuple(portal_type) portal_type = tuple(portal_type)
acquisition_key = ('_getDefaultAcquiredProperty', self.getPath(), key, base_category, acquisition_key = ('_getDefaultAcquiredProperty', self.getPath(), key, base_category,
portal_type, copy_value, mask_value, sync_value, portal_type, copy_value, mask_value, sync_value,
accessor_id, depends, storage_id, alt_accessor_id, is_list_type, is_tales_type) accessor_id, depends, storage_id, alt_accessor_id, is_list_type, is_tales_type)
if TRANSACTION._erp5_acquisition_stack.has_key(acquisition_key): return null_value if acquisition_key in tv:
TRANSACTION._erp5_acquisition_stack[acquisition_key] = 1 return null_value
if storage_id is None: storage_id=key tv[acquisition_key] = 1
#LOG("Get Acquired Property storage_id",0,str(storage_id))
# Test presence of attribute without acquisition try:
# if present, get it in its context, thus we keep acquisition if if storage_id is None: storage_id=key
# returned value is an object #LOG("Get Acquired Property storage_id",0,str(storage_id))
d = getattr(aq_base(self), storage_id, _MARKER) # Test presence of attribute without acquisition
if d is not _MARKER: # if present, get it in its context, thus we keep acquisition if
value = getattr(self, storage_id, None) # returned value is an object
else: d = getattr(aq_base(self), storage_id, _MARKER)
value = None if d is not _MARKER:
# If we hold an attribute and mask_value is set, return the attribute value = getattr(self, storage_id, None)
if mask_value and value is not None:
# Pop context
del TRANSACTION._erp5_acquisition_stack[acquisition_key]
if is_tales_type:
expression = Expression(value)
econtext = createExpressionContext(self)
return expression(econtext)
else:
return value
# Retrieve the list of related objects
#LOG("Get Acquired Property self",0,str(self))
#LOG("Get Acquired Property portal_type",0,str(portal_type))
#LOG("Get Acquired Property base_category",0,str(base_category))
#super_list = self._getValueList(base_category, portal_type=portal_type) # We only do a single jump
super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # Full acquisition
super_list = filter(lambda o: o.getPhysicalPath() != self.getPhysicalPath(), super_list) # Make sure we do not create stupid loop here
#LOG("Get Acquired Property super_list",0,str(super_list))
#LOG("Get Acquired Property accessor_id",0,str(accessor_id))
if len(super_list) > 0:
super = super_list[0]
# Retrieve the value
if accessor_id is None:
value = super.getProperty(key)
else: else:
method = getattr(super, accessor_id) value = None
value = method() # We should add depends here XXXXXX # If we hold an attribute and mask_value is set, return the attribute
# There is also a strong risk here of infinite loop if mask_value and value is not None:
if copy_value: # Pop context
if getattr(self, storage_id, None) is None: if is_tales_type:
# Copy the value if it does not already exist as an attribute of self expression = Expression(value)
# Like in the case of orders / invoices econtext = createExpressionContext(self)
setattr(self, storage_id, value) return expression(econtext)
if is_list_type:
# We must provide the first element of the acquired list
if value is None:
result = None
else: else:
if isinstance(value, (list, tuple)): return value
if len(value) is 0: # Retrieve the list of related objects
result = None #LOG("Get Acquired Property self",0,str(self))
else: #LOG("Get Acquired Property portal_type",0,str(portal_type))
result = value[0] #LOG("Get Acquired Property base_category",0,str(base_category))
#super_list = self._getValueList(base_category, portal_type=portal_type) # We only do a single jump
super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # Full acquisition
super_list = filter(lambda o: o.getPhysicalPath() != self.getPhysicalPath(), super_list) # Make sure we do not create stupid loop here
#LOG("Get Acquired Property super_list",0,str(super_list))
#LOG("Get Acquired Property accessor_id",0,str(accessor_id))
if len(super_list) > 0:
super = super_list[0]
# Retrieve the value
if accessor_id is None:
value = super.getProperty(key)
else:
method = getattr(super, accessor_id)
value = method() # We should add depends here XXXXXX
# There is also a strong risk here of infinite loop
if copy_value:
if getattr(self, storage_id, None) is None:
# Copy the value if it does not already exist as an attribute of self
# Like in the case of orders / invoices
setattr(self, storage_id, value)
if is_list_type:
# We must provide the first element of the acquired list
if value is None:
result = None
else: else:
result = value if isinstance(value, (list, tuple)):
if len(value) is 0:
result = None
else:
result = value[0]
else:
result = value
else:
# Value is a simple type
result = value
else: else:
# Value is a simple type result = None
result = value if result is not None:
else: return result
result = None else:
if result is not None: #LOG("alt_accessor_id",0,str(alt_accessor_id))
# Pop context if alt_accessor_id is not None:
del TRANSACTION._erp5_acquisition_stack[acquisition_key] for id in alt_accessor_id:
return result #LOG("method",0,str(id))
else: method = getattr(self, id, None)
#LOG("alt_accessor_id",0,str(alt_accessor_id)) if callable(method):
if alt_accessor_id is not None: result = method()
for id in alt_accessor_id: if result is not None:
#LOG("method",0,str(id)) if is_list_type:
method = getattr(self, id, None) if isinstance(result, (list, tuple)):
if callable(method): # We must provide the first element of the alternate result
result = method() if len(result) > 0:
if result is not None: return result[0]
if is_list_type: else:
if isinstance(result, (list, tuple)): return result
# We must provide the first element of the alternate result
if len(result) > 0:
# Pop context
del TRANSACTION._erp5_acquisition_stack[acquisition_key]
return result[0]
else: else:
# Pop context # Result is a simple type
del TRANSACTION._erp5_acquisition_stack[acquisition_key]
return result return result
else:
# Pop context
del TRANSACTION._erp5_acquisition_stack[acquisition_key]
# Result is a simple type
return result
if copy_value: if copy_value:
# Pop context return getattr(self,storage_id, default_value)
del TRANSACTION._erp5_acquisition_stack[acquisition_key] else:
return getattr(self,storage_id, default_value) # Return the default value defined at the class level XXXXXXXXXXXXXXX
else: return default_value
# Pop context finally:
del TRANSACTION._erp5_acquisition_stack[acquisition_key] # Pop the acquisition context.
# Return the default value defined at the class level XXXXXXXXXXXXXXX try:
return default_value del tv[acquisition_key]
except KeyError:
pass
def _getAcquiredPropertyList(self, key, default_value, null_value, def _getAcquiredPropertyList(self, key, default_value, null_value,
base_category, portal_type=None, copy_value=0, mask_value=0, sync_value=0, append_value=0, base_category, portal_type=None, copy_value=0, mask_value=0, sync_value=0, append_value=0,
...@@ -811,66 +794,67 @@ class Base( CopyContainer, ...@@ -811,66 +794,67 @@ class Base( CopyContainer,
""" """
# Push context to prevent loop # Push context to prevent loop
from Globals import get_request tv = getTransactionalVariable()
TRANSACTION = get_transaction() if isinstance(portal_type, list):
if not hasattr(TRANSACTION, '_erp5_acquisition_stack'): TRANSACTION._erp5_acquisition_stack = {} portal_type = tuple(portal_type)
acquisition_key = ('_getAcquiredPropertyList', self.getPath(), key, base_category, acquisition_key = ('_getAcquiredPropertyList', self.getPath(), key, base_category,
portal_type, copy_value, mask_value, sync_value, portal_type, copy_value, mask_value, sync_value,
accessor_id, depends, storage_id, alt_accessor_id, is_list_type, is_tales_type) accessor_id, depends, storage_id, alt_accessor_id, is_list_type, is_tales_type)
if TRANSACTION._erp5_acquisition_stack.has_key(acquisition_key): return null_value if acquisition_key in tv:
TRANSACTION._erp5_acquisition_stack[acquisition_key] = 1 return null_value
if storage_id is None: storage_id=key tv[acquisition_key] = 1
value = getattr(self, storage_id, None)
if mask_value and value is not None: try:
# Pop context if storage_id is None: storage_id=key
del TRANSACTION._erp5_acquisition_stack[acquisition_key] value = getattr(self, storage_id, None)
if is_tales_type: if mask_value and value is not None:
expression = Expression(value) if is_tales_type:
econtext = createExpressionContext(self) expression = Expression(value)
return expression(econtext) econtext = createExpressionContext(self)
else: return expression(econtext)
return value
super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # Full acquisition
super_list = filter(lambda o: o.getPhysicalPath() != self.getPhysicalPath(), super_list) # Make sure we do not create stupid loop here
if len(super_list) > 0:
value = []
for super in super_list:
if accessor_id is None:
if is_list_type:
result = super.getPropertyList(key)
if isinstance(result, (list, tuple)):
value += result
else:
value += [result]
else:
value += [super.getProperty(key)]
else: else:
method = getattr(super, accessor_id) return value
if is_list_type: super_list = self._getAcquiredValueList(base_category, portal_type=portal_type) # Full acquisition
result = method() # We should add depends here super_list = filter(lambda o: o.getPhysicalPath() != self.getPhysicalPath(), super_list) # Make sure we do not create stupid loop here
if isinstance(result, (list, tuple)): if len(super_list) > 0:
value += result value = []
for super in super_list:
if accessor_id is None:
if is_list_type:
result = super.getPropertyList(key)
if isinstance(result, (list, tuple)):
value += result
else:
value += [result]
else: else:
value += [result] value += [super.getProperty(key)]
else: else:
value += [method()] # We should add depends here method = getattr(super, accessor_id)
if copy_value: if is_list_type:
if not hasattr(self, storage_id): result = method() # We should add depends here
setattr(self, storage_id, value) if isinstance(result, (list, tuple)):
# Pop context value += result
del TRANSACTION._erp5_acquisition_stack[acquisition_key] else:
return value value += [result]
else: else:
# ????? value += [method()] # We should add depends here
if copy_value: if copy_value:
# Pop context if not hasattr(self, storage_id):
del TRANSACTION._erp5_acquisition_stack[acquisition_key] setattr(self, storage_id, value)
return getattr(self,storage_id, default_value) return value
else: else:
# Pop context # ?????
del TRANSACTION._erp5_acquisition_stack[acquisition_key] if copy_value:
return default_value return getattr(self,storage_id, default_value)
else:
return default_value
finally:
# Pop the acquisition context.
try:
del tv[acquisition_key]
except KeyError:
pass
security.declareProtected( Permissions.AccessContentsInformation, 'getProperty' ) security.declareProtected( Permissions.AccessContentsInformation, 'getProperty' )
def getProperty(self, key, d=_MARKER, **kw): def getProperty(self, key, d=_MARKER, **kw):
......
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