[Erp5-report] r16438 - /erp5/trunk/products/ERP5Type/Interactor.py

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Sep 18 13:42:21 CEST 2007


Author: jp
Date: Tue Sep 18 13:42:21 2007
New Revision: 16438

URL: http://svn.erp5.org?rev=16438&view=rev
Log:
Initial upload. This class is not used (yet) by ERP5Type but we are working on it. 

Added:
    erp5/trunk/products/ERP5Type/Interactor.py

Added: erp5/trunk/products/ERP5Type/Interactor.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Interactor.py?rev=16438&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/Interactor.py (added)
+++ erp5/trunk/products/ERP5Type/Interactor.py Tue Sep 18 13:42:21 2007
@@ -1,0 +1,148 @@
+from Products.ERP5Type.Accessor.Accessor import Accessor as Method
+from Products.ERP5Type.Base import _aq_reset
+
+"""
+  Current implementation uses callable objects.
+  Using decorator would be more modern and consistent with
+  recent evolution of python. But we have 2.3 ERP5 users
+  so we should, at least, provide both implementations.
+  
+  Code structure should be changed so that Interactors
+  because a new "type" of ERP5 class such Document
+  with a modular plugin structure.
+  
+  TODO: multiple instances of interactors could
+  use different parameters. This way, interactions
+  can be defined on "instances" or can be
+  made generic.
+"""
+
+
+class InteractorMethodCall:
+  
+  def __init__(self, method, instance, *args, **kw):
+    self.instance = instance
+    self.args = args
+    self.kw = kw
+    self.method = method
+    
+  def __call__(self):
+    return self.method(self.instance, *self.args, **self.kw)
+
+class InteractorMethod(Method):
+
+  def __init__(self, method):
+    self.after_action_list = []
+    self.before_action_list = []
+    self.method = method
+    self.func_code = method.func_code
+    self.func_defaults = method.func_defaults
+
+  def registerBeforeAction(self, action, args, kw):
+    self.after_action_list.append((action, args, kw))
+  
+  def registerAfterAction(self, action, args, kw):
+    self.after_action_list.append((action, args, kw))
+
+  def __call__(self, instance, *args, **kw):
+    method_call_object = InteractorMethodCall(self.method, instance, *args, **kw)
+    for action, args, kw in self.before_action_list:
+      action(method_call_object, *args, **kw)
+    result = method_call_object()
+    for action, args, kw in self.after_action_list:
+      action(method_call_object, *args, **kw)
+    return result
+
+class InteractorSource:
+
+  def __init__(self, method):
+    """
+      Register method
+    """
+    self.method = method
+
+  def doAfter(self, action, *args, **kw):
+    """
+    """
+    im_class = self.method.im_class
+    if not isinstance(self.method, InteractorMethod):
+      # Turn this into an InteractorMethod
+      interactor_method = InteractorMethod(self.method)
+      setattr(im_class, self.method.__name__, interactor_method)
+      self.method = interactor_method
+    # Register the action
+    self.method.registerAfterAction(action, args, kw)
+
+class Interactor:
+  def install(self):
+    raise NotImplementedError
+  
+  def uninstall(self):
+    raise NotImplementedError
+  
+  # Interaction implementation
+  def on(self, method):
+    """
+      Parameters may hold predicates ?
+      no need - use InteractorMethodCall and decide on action
+    """
+    return InteractorSource(method)
+
+class AqDynamicInteractor(Interactor):
+
+  def install(self):
+    """
+      Installs interactions
+    """
+    from Products.ERP5.Interaction import InteractionDefinition
+    self.on(InteractionDefinition.setProperties).doAfter(self.resetAqDynamic, 1, 2, toto="foo")
+    self.on(InteractionDefinition.addVariable).doAfter(self.resetAqDynamic, 1, 2, toto="foo")
+
+  def uninstall(self):
+    """
+      Uninstall interactions
+    """
+
+  # Interaction example
+  def resetAqDynamic(self, method_call_object, a, b, toto=None):
+    """
+      Reset _aq_dynamic
+    """
+    _aq_reset()
+
+class FieldValueInteractor(Interactor):
+  
+  def install(self):
+    """
+      Installs interactions
+    """
+    from Products.Formulator.Field import ZMIField
+    self.on(ZMIField.manage_edit).doAfter(self.purgeFieldValueCache)
+
+  def uninstall(self):
+    """
+      Uninstall interactions
+    """
+
+  def purgeFieldValueCache(self, method_call_object):
+    """
+    """
+    # here call something
+
+
+class TypeInteractorExample(Interactor):
+  def __init__(self, portal_type):
+    self.portal_type = portal_type
+
+  def install(self):
+    from Products.CMFCore.TypesTool import TypesTool
+    self.on(TypesTool.manage_edit).doAfter(self.doSomething)
+
+  def doSomething(self, method_call_object):
+    if self.portal_type == method_call_object.instance.portal_type:
+      pass
+      # do whatever
+
+
+test = AqDynamicInteractor()
+test.install()




More information about the Erp5-report mailing list