Commit 2f54ba04 authored by Yoshinori Okuji's avatar Yoshinori Okuji

Fix some dynamic patches. They should not create new classes.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@3565 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent cccbd8cd
......@@ -49,19 +49,7 @@ from Products.Formulator.Field import Field
from zLOG import LOG
class ERP5Field(Field):
"""
The ERP5Field provides here, request,
container etc. names to TALES expressions. It is used to dynamically
patch the standard Formulator
"""
security = ClassSecurityInfo()
# this is a field
is_field = 1
security.declareProtected('Access contents information', 'get_value')
def get_value(self, id, **kw):
def get_value(self, id, **kw):
"""Get value for id."""
# FIXME: backwards compat hack to make sure tales dict exists
if not hasattr(self, 'tales'):
......@@ -138,15 +126,16 @@ class ERP5Field(Field):
return value
def om_icons(self):
psyco.bind(get_value)
def om_icons(self):
"""Return a list of icon URLs to be displayed by an ObjectManager"""
icons = ({'path': self.icon,
'alt': self.meta_type, 'title': self.meta_type},)
return icons
psyco.bind(get_value)
def _get_default(self, key, value, REQUEST):
def _get_default(self, key, value, REQUEST):
if value is not None:
return value
try:
......@@ -167,9 +156,9 @@ class ERP5Field(Field):
# Dynamic Patch
Field.get_value = ERP5Field.get_value
Field._get_default = ERP5Field._get_default
Field.om_icons = ERP5Field.om_icons
Field.get_value = get_value
Field._get_default = _get_default
Field.om_icons = om_icons
# Constructors
......
......@@ -26,12 +26,7 @@ from Products.Formulator.Widget import Widget
from AccessControl import ClassSecurityInfo
from zLOG import LOG
class PatchedField(Field):
security = ClassSecurityInfo()
security.declareProtected('Access contents information',
'generate_field_key')
def generate_field_key(self, validation=0, key=None):
def Field_generate_field_key(self, validation=0, key=None):
"""Generate the key Silva uses to render the field in the form.
"""
# Patched by JPS for ERP5 in order to
......@@ -47,8 +42,7 @@ class PatchedField(Field):
else:
return '%s.%s:record' % (self.field_record, self.id)
security.declareProtected('View', 'render')
def render(self, value=None, REQUEST=None, key=None):
def Field_render(self, value=None, REQUEST=None, key=None):
"""Render the field widget.
value -- the value the field should have (for instance
from validation).
......@@ -60,8 +54,7 @@ class PatchedField(Field):
"""
return self._render_helper(self.generate_field_key(key=key), value, REQUEST)
security.declareProtected('View', 'render_sub_field')
def render_sub_field(self, id, value=None, REQUEST=None, key=None):
def Field_render_sub_field(self, id, value=None, REQUEST=None, key=None):
"""Render a sub field, as part of complete rendering of widget in
a form. Works like render() but for sub field.
Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
......@@ -69,7 +62,7 @@ class PatchedField(Field):
return self.sub_form.get_field(id)._render_helper(
self.generate_subfield_key(id, key=key), value, REQUEST)
def generate_subfield_key(self, id, validation=0, key=None):
def Field_generate_subfield_key(self, id, validation=0, key=None):
"""Generate the key Silva uses to render a sub field.
Added key parameter for ERP5
Added key parameter for ERP5 in order to be compatible with listbox/matrixbox
......@@ -79,17 +72,17 @@ class PatchedField(Field):
return 'subfield_%s_%s'%(key, id)
return '%s.subfield_%s_%s:record' % (self.field_record, key, id)
def validate_sub_field(self, id, REQUEST, key=None):
def Field_validate_sub_field(self, id, REQUEST, key=None):
"""Validates a subfield (as part of field validation).
"""
return self.sub_form.get_field(id)._validate_helper(
self.generate_subfield_key(id, validation=1, key=key), REQUEST)
Field.generate_field_key = PatchedField.generate_field_key
Field.render = PatchedField.render
Field.render_sub_field = PatchedField.render_sub_field
Field.generate_subfield_key = PatchedField.generate_subfield_key
Field.validate_sub_field = PatchedField.validate_sub_field
Field.generate_field_key = Field_generate_field_key
Field.render = Field_render
Field.render_sub_field = Field_render_sub_field
Field.generate_subfield_key = Field_generate_subfield_key
Field.validate_sub_field = Field_validate_sub_field
from Products.Formulator.Validator import SelectionValidator
from Products.Formulator.Validator import StringBaseValidator
......@@ -564,14 +557,7 @@ MultiItemsWidget.render_items = MultiItemsWidget_render_items
# JPS - Subfield handling with listbox requires extension
from Products.Formulator.StandardFields import DateTimeField
class PatchedDateTimeField(DateTimeField):
"""
Make sur we test if this REQUEST parameter has a form
attribute. In ERP5, we sometimes use the REQUEST to pass
subobjects to forms.
"""
def _get_default(self, key, value, REQUEST):
def DateTimeField_get_default(self, key, value, REQUEST):
if value is not None:
return value
# if there is something in the request then return None
......@@ -582,7 +568,7 @@ class PatchedDateTimeField(DateTimeField):
else:
return self.get_value('default')
DateTimeField._get_default = PatchedDateTimeField._get_default
DateTimeField._get_default = DateTimeField_get_default
from Products.Formulator.Widget import DateTimeWidget
......
......@@ -61,7 +61,7 @@ import FormulatorPatch
import psyco
psyco.bind(ListBox.ListBoxWidget.render)
psyco.bind(ListBox.ListBoxValidator.validate)
psyco.bind(Form.ERP5Field.get_value)
#psyco.bind(Form.ERP5Field.get_value)
#psyco.bind(Form.ERP5Form.__call__)
#psyco.bind(Form.ERP5Form._exec)
......
......@@ -24,9 +24,7 @@ from Products.CMFCore.FSZSQLMethod import FSZSQLMethod
from Products.CMFCore.DirectoryView import expandpath
from Products.ZSQLMethods.SQL import SQL
class PatchedFSZSQLMethod(FSZSQLMethod):
def _readFile(self, reparse):
def FSZSQLMethod_readFile(self, reparse):
fp = expandpath(self._filepath)
file = open(fp, 'r') # not 'rb', as this is a text file!
try:
......@@ -39,7 +37,7 @@ class PatchedFSZSQLMethod(FSZSQLMethod):
self.PUT(RESPONSE,None)
def _createZODBClone(self):
def FSZSQLMethod_createZODBClone(self):
"""Create a ZODB (editable) equivalent of this object."""
# I guess it's bad to 'reach inside' ourselves like this,
# but Z SQL Methods don't have accessor methdods ;-)
......@@ -55,8 +53,8 @@ class PatchedFSZSQLMethod(FSZSQLMethod):
self.class_file_)
return s
FSZSQLMethod._readFile = PatchedFSZSQLMethod._readFile
FSZSQLMethod._createZODBClone = PatchedFSZSQLMethod._createZODBClone
FSZSQLMethod._readFile = FSZSQLMethod_readFile
FSZSQLMethod._createZODBClone = FSZSQLMethod_createZODBClone
from Products.CMFCore import ActionInformation
from AccessControl import ClassSecurityInfo
......@@ -188,9 +186,7 @@ ActionInformation.ActionInformation = PatchedActionInformation
from Products.CMFCore.ActionProviderBase import ActionProviderBase
from Products.CMFCore.ActionInformation import ActionInformation
class PatchedActionProviderBase(ActionProviderBase):
def manage_editActionsForm( self, REQUEST, manage_tabs_message=None ):
def ActionProviderBase_manage_editActionsForm( self, REQUEST, manage_tabs_message=None ):
""" Show the 'Actions' management tab.
"""
......@@ -227,7 +223,7 @@ class PatchedActionProviderBase(ActionProviderBase):
)
def addAction( self
def ActionProviderBase_addAction( self
, id
, name
, action
......@@ -272,7 +268,7 @@ class PatchedActionProviderBase(ActionProviderBase):
REQUEST, manage_tabs_message='Added.')
def _extractAction( self, properties, index ):
def ActionProviderBase_extractAction( self, properties, index ):
""" Extract an ActionInformation from the funky form properties.
"""
......@@ -327,7 +323,7 @@ class PatchedActionProviderBase(ActionProviderBase):
, optional=optional
)
ActionProviderBase.manage_editActionsForm = PatchedActionProviderBase.manage_editActionsForm
ActionProviderBase.addAction = PatchedActionProviderBase.addAction
ActionProviderBase._extractAction = PatchedActionProviderBase._extractAction
ActionProviderBase.manage_editActionsForm = ActionProviderBase_manage_editActionsForm
ActionProviderBase.addAction = ActionProviderBase_addAction
ActionProviderBase._extractAction = ActionProviderBase_extractAction
......@@ -36,8 +36,8 @@ MembershipTool.membersfolder_id = 'member'
##############################################################################
# Import: add rename feature
from OFS.ObjectManager import ObjectManager, customImporters
class PatchedObjectManager(ObjectManager):
def _importObjectFromFile(self, filepath, verify=1, set_owner=1, id=None):
def ObjectManager_importObjectFromFile(self, filepath, verify=1, set_owner=1, id=None):
#LOG('_importObjectFromFile, filepath',0,filepath)
# locate a valid connection
connection=self._p_jar
......@@ -59,7 +59,7 @@ class PatchedObjectManager(ObjectManager):
ob=self._getOb(id)
ob.manage_changeOwnershipType(explicit=0)
ObjectManager._importObjectFromFile=PatchedObjectManager._importObjectFromFile
ObjectManager._importObjectFromFile=ObjectManager_importObjectFromFile
##############################################################################
# Properties
......@@ -71,12 +71,16 @@ from Products.ERP5Type.ERP5Type import ERP5TypeInformation
from Products.CMFCore.Expression import Expression
class ERP5PropertyManager(PropertyManager):
"""
This class is only for backward compatibility.
"""
pass
manage_propertiesForm=DTMLFile('dtml/properties', globals(),
PropertyManager_manage_propertiesForm=DTMLFile('dtml/properties', globals(),
property_extensible_schema__=1)
def _updateProperty(self, id, value):
def PropertyManager_updateProperty(self, id, value):
# Update the value of an existing property. If value
# is a string, an attempt will be made to convert
# the value to the type of the existing property.
......@@ -91,14 +95,14 @@ class ERP5PropertyManager(PropertyManager):
#LOG('_updateProperty', 0, 'self = %r, id = %r, value = %r' % (self, id, value))
self._setPropValue(id, value)
def hasProperty(self, id):
def PropertyManager_hasProperty(self, id):
"""Return true if object has a property 'id'"""
for p in self.propertyIds():
if id==p:
return 1
return 0
def getProperty(self, id, d=None, evaluate=1):
def PropertyManager_getProperty(self, id, d=None, evaluate=1):
"""Get the property 'id', returning the optional second
argument or None if no such property is found."""
type = self.getPropertyType(id)
......@@ -111,7 +115,7 @@ class ERP5PropertyManager(PropertyManager):
return getattr(self, id)
return d
def getPropertyType(self, id):
def PropertyManager_getPropertyType(self, id):
"""Get the type of property 'id', returning None if no
such property exists"""
for md in self._propertyMap():
......@@ -119,7 +123,7 @@ class ERP5PropertyManager(PropertyManager):
return md.get('type', 'string')
return None
def _setProperty(self, id, value, type=None):
def PropertyManager_setProperty(self, id, value, type=None):
# for selection and multiple selection properties
# the value argument indicates the select variable
# of the property
......@@ -160,36 +164,36 @@ class ERP5PropertyManager(PropertyManager):
self._local_properties=getattr(self, '_local_properties', ())+({'id':id,'type':type},)
self._setPropValue(id, value)
def _delProperty(self, id):
def PropertyManager_delProperty(self, id):
if not self.hasProperty(id):
raise ValueError, 'The property %s does not exist' % escape(id)
self._delPropValue(id)
self._local_properties=tuple(filter(lambda i, n=id: i['id'] != n,
getattr(self, '_local_properties', ())))
def propertyIds(self):
def PropertyManager_propertyIds(self):
"""Return a list of property ids """
return map(lambda i: i['id'], self._propertyMap())
def propertyValues(self):
def PropertyManager_propertyValues(self):
"""Return a list of actual property objects """
return map(lambda i,s=self: getattr(s,i['id']), self._propertyMap())
def propertyItems(self):
def PropertyManager_propertyItems(self):
"""Return a list of (id,property) tuples """
return map(lambda i,s=self: (i['id'],getattr(s,i['id'])), self._propertyMap())
def _propertyMap(self):
def PropertyManager_propertyMap(self):
"""Return a tuple of mappings, giving meta-data for properties """
return tuple(list(self._properties) + list(getattr(self, '_local_properties', ())))
def propdict(self):
def PropertyManager_propdict(self):
dict={}
for p in self._propertyMap():
dict[p['id']]=p
return dict
def manage_addProperty(self, id, value, type, REQUEST=None):
def PropertyManager_manage_addProperty(self, id, value, type, REQUEST=None):
"""Add a new property via the web. Sets a new property with
the given id, type, and value."""
if type_converters.has_key(type):
......@@ -199,20 +203,20 @@ class ERP5PropertyManager(PropertyManager):
if REQUEST is not None:
return self.manage_propertiesForm(self, REQUEST)
PropertyManager.manage_addProperty = ERP5PropertyManager.manage_addProperty
PropertyManager.manage_propertiesForm = ERP5PropertyManager.manage_propertiesForm
PropertyManager._updateProperty = ERP5PropertyManager._updateProperty
PropertyManager.getPropertyType = ERP5PropertyManager.getPropertyType
PropertyManager._setProperty = ERP5PropertyManager._setProperty
PropertyManager._delProperty = ERP5PropertyManager._delProperty
PropertyManager.propertyIds = ERP5PropertyManager.propertyIds
PropertyManager.propertyValues = ERP5PropertyManager.propertyValues
PropertyManager.propertyItems = ERP5PropertyManager.propertyItems
PropertyManager._propertyMap = ERP5PropertyManager._propertyMap
PropertyManager.propdict = ERP5PropertyManager.propdict
PropertyManager.hasProperty = ERP5PropertyManager.hasProperty
PropertyManager.getProperty = ERP5PropertyManager.getProperty
ERP5TypeInformation.manage_propertiesForm = ERP5PropertyManager.manage_propertiesForm
PropertyManager.manage_addProperty = PropertyManager_manage_addProperty
PropertyManager.manage_propertiesForm = PropertyManager_manage_propertiesForm
PropertyManager._updateProperty = PropertyManager_updateProperty
PropertyManager.getPropertyType = PropertyManager_getPropertyType
PropertyManager._setProperty = PropertyManager_setProperty
PropertyManager._delProperty = PropertyManager_delProperty
PropertyManager.propertyIds = PropertyManager_propertyIds
PropertyManager.propertyValues = PropertyManager_propertyValues
PropertyManager.propertyItems = PropertyManager_propertyItems
PropertyManager._propertyMap = PropertyManager_propertyMap
PropertyManager.propdict = PropertyManager_propdict
PropertyManager.hasProperty = PropertyManager_hasProperty
PropertyManager.getProperty = PropertyManager_getProperty
ERP5TypeInformation.manage_propertiesForm = PropertyManager_manage_propertiesForm
from ZPublisher.Converters import type_converters, field2string
......@@ -226,10 +230,7 @@ except: Bucket=lambda:{}
from Shared.DC.ZRDB.Aqueduct import decodestring, parse
from Shared.DC.ZRDB.DA import DA
class PatchedDA(DA):
def fromFile(self, filename):
def DA_fromFile(self, filename):
"""
Read the file and update self
"""
......@@ -238,7 +239,7 @@ class PatchedDA(DA):
f.close()
self.fromText(s)
def fromText(self, text):
def DA_fromText(self, text):
"""
Read the string 'text' and updates self
"""
......@@ -270,7 +271,7 @@ class PatchedDA(DA):
arguments=arguments, template=template)
self.manage_advanced(max_rows, max_cache, cache_time, class_name, class_file)
def manage_FTPget(self):
def DA_manage_FTPget(self):
"""Get source for FTP download"""
self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
return """<dtml-comment>
......@@ -288,8 +289,8 @@ class_file:%s
self.class_name_, self.class_file_,
self.arguments_src, self.src)
# This function doesn't take care about properties by default
def PUT(self, REQUEST, RESPONSE):
# This function doesn't take care about properties by default
def DA_PUT(self, REQUEST, RESPONSE):
"""Handle put requests"""
if RESPONSE is not None: self.dav__init(REQUEST, RESPONSE)
if RESPONSE is not None: self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
......@@ -329,10 +330,10 @@ class_file:%s
return RESPONSE
DA.fromFile = PatchedDA.fromFile
DA.fromText = PatchedDA.fromText
DA.manage_FTPget = PatchedDA.manage_FTPget
DA.PUT = PatchedDA.PUT
DA.fromFile = DA_fromFile
DA.fromText = DA_fromText
DA.manage_FTPget = DA_manage_FTPget
DA.PUT = DA_PUT
##############################################################################
# Optimized rendering of global actions (cache)
......@@ -345,9 +346,7 @@ from Products.CMFCore.utils import _getAuthenticatedUser
from time import time
from Products.ERP5Type.Cache import CachingMethod
class PatchedDCWorkflowDefinition(DCWorkflowDefinition):
def listGlobalActions(self, info):
def DCWorkflowDefinition_listGlobalActions(self, info):
'''
Allows this workflow to
include actions to be displayed in the actions box.
......@@ -416,7 +415,7 @@ class PatchedDCWorkflowDefinition(DCWorkflowDefinition):
return _listGlobalActions(user=user, id=self.id, portal_path=self._getPortalRoot().getPhysicalPath())
DCWorkflowDefinition.listGlobalActions = PatchedDCWorkflowDefinition.listGlobalActions
DCWorkflowDefinition.listGlobalActions = DCWorkflowDefinition_listGlobalActions
##############################################################################
# Stribger repair of BTreeFolder2
......@@ -516,9 +515,7 @@ from AccessControl import ModuleSecurityInfo
ModuleSecurityInfo('Products.DCWorkflow.DCWorkflow').declarePublic('ValidationFailed')
class ERP5DCWorkflowDefinition (DCWorkflowDefinition):
def _executeTransition(self, ob, tdef=None, kwargs=None):
def DCWorkflowDefinition_executeTransition(self, ob, tdef=None, kwargs=None):
'''
Private method.
Puts object in a new state.
......@@ -642,7 +639,7 @@ class ERP5DCWorkflowDefinition (DCWorkflowDefinition):
return new_sdef
DCWorkflowDefinition._executeTransition = ERP5DCWorkflowDefinition._executeTransition
DCWorkflowDefinition._executeTransition = DCWorkflowDefinition_executeTransition
# This patch allows to use workflowmethod as an after_script
# However, the right way of doing would be to have a combined state of TRIGGER_USER_ACTION and TRIGGER_WORKFLOW_METHOD
......@@ -660,15 +657,14 @@ TransitionDefinition.getAvailableScriptIds = ERP5TransitionDefinition.getAvailab
##############################################################################
# Adding commit_prepare to the zodb transaction
from ZODB import Transaction
#class ERP5Transaction(Transaction):
try:
from ZODB import Transaction
hosed = Transaction.hosed
free_transaction = Transaction.free_transaction
jar_cmp = Transaction.jar_cmp
hosed = Transaction.hosed
free_transaction = Transaction.free_transaction
jar_cmp = Transaction.jar_cmp
def commit(self, subtransaction=None):
def commit(self, subtransaction=None):
"""Finalize the transaction."""
objects = self._objects
......@@ -771,7 +767,7 @@ def commit(self, subtransaction=None):
if not subtransaction and self._id is not None:
free_transaction()
def _commit_prepare(self, jars, subjars, subtransaction):
def _commit_prepare(self, jars, subjars, subtransaction):
if subtransaction:
assert not subjars
for jar in jars:
......@@ -815,9 +811,10 @@ def _commit_prepare(self, jars, subjars, subtransaction):
# not available
pass
Transaction.Transaction.commit = commit
Transaction.Transaction._commit_prepare = _commit_prepare
Transaction.Transaction.commit = commit
Transaction.Transaction._commit_prepare = _commit_prepare
except ImportError:
pass
##############################################################################
......@@ -825,9 +822,7 @@ Transaction.Transaction._commit_prepare = _commit_prepare
from Products.CMFCore.WorkflowTool import WorkflowTool
class ERP5WorkflowTool(WorkflowTool):
def wrapWorkflowMethod(self, ob, method_id, func, args, kw):
def WorkflowTool_wrapWorkflowMethod(self, ob, method_id, func, args, kw):
""" To be invoked only by WorkflowCore.
Allows a workflow definition to wrap a WorkflowMethod.
......@@ -873,13 +868,11 @@ class ERP5WorkflowTool(WorkflowTool):
for w in wfs:
w.notifySuccess(ob, method_id, result, args=args, kw=kw)
WorkflowTool.wrapWorkflowMethod = ERP5WorkflowTool.wrapWorkflowMethod
WorkflowTool.wrapWorkflowMethod = WorkflowTool_wrapWorkflowMethod
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
class ERP5DCWorkflow(DCWorkflowDefinition):
def notifyBefore(self, ob, action, args=None, kw=None):
def DCWorkflowDefinition_notifyBefore(self, ob, action, args=None, kw=None):
'''
Notifies this workflow of an action before it happens,
allowing veto by exception. Unless an exception is thrown, either
......@@ -888,14 +881,14 @@ class ERP5DCWorkflow(DCWorkflowDefinition):
'''
pass
def notifySuccess(self, ob, action, result, args=None, kw=None):
def DCWorkflowDefinition_notifySuccess(self, ob, action, result, args=None, kw=None):
'''
Notifies this workflow that an action has taken place.
'''
pass
DCWorkflowDefinition.notifyBefore = ERP5DCWorkflow.notifyBefore
DCWorkflowDefinition.notifySuccess = ERP5DCWorkflow.notifySuccess
DCWorkflowDefinition.notifyBefore = DCWorkflowDefinition_notifyBefore
DCWorkflowDefinition.notifySuccess = DCWorkflowDefinition_notifySuccess
##############################################################################
# Make sure the xml export will be ordered
......@@ -903,7 +896,10 @@ DCWorkflowDefinition.notifySuccess = ERP5DCWorkflow.notifySuccess
from Shared.DC.xml import ppml
from base64 import encodestring
from cStringIO import StringIO
from ZODB.referencesf import referencesf
try:
from ZODB.serialize import referencesf
except ImportError:
from ZODB.referencesf import referencesf
from ZODB.ExportImport import TemporaryFile
from pickle import Pickler, EMPTY_DICT, MARK, DICT
from cPickle import loads, dumps
......@@ -1911,3 +1907,21 @@ def erp5_new_traverse(request, path, response=None, validated_hook=None):
BaseRequest.traverse = erp5_new_traverse
######################################################################################
# AttrDict patch for more dict-like methods.
try:
from App.ProductContext import AttrDict
def AttrDict_getitem(self, name):
try:
return getattr(self.ob, name)
except AttributeError:
raise KeyError
def AttrDict_has_key(self, name):
return hasattr(self.ob, name)
AttrDict.__getitem__ = AttrDict_getitem
AttrDict.has_key = AttrDict_has_key
except ImportError:
pass
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