Commit 5d48a7a6 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Avoid creating a temporary file when loading the source code of a Component.

parent 569c3097
...@@ -28,9 +28,6 @@ ...@@ -28,9 +28,6 @@
# #
############################################################################## ##############################################################################
import imp
import os
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Base import Base from Products.ERP5Type.Base import Base
...@@ -58,36 +55,13 @@ class DocumentComponent(Base): ...@@ -58,36 +55,13 @@ class DocumentComponent(Base):
'Reference', 'Reference',
'TextDocument') 'TextDocument')
def load(self, namespace_dict={}):
# XXX-arnau: per-component reset, global for now """
# def reset(self): Load the source code into the given dict. Using exec() rather than
# import erp5 imp.load_source() as the latter would required creating an intermediary
# file. Also, for traceback readability sake, the destination module
# try: __dict__ is given rather than creating an empty dict and returning
# component_namespace_name, module_name = self.getId().split('.')[1:] it. By default namespace_dict is an empty dict to allow checking the
# component_namespace = getattr(erp5, component_namespace_name) source code before validate.
# except (ValueError, AttributeError): """
# LOG("ERP5Type.Core.DocumentComponent", DEBUG, exec self.getTextContent() in namespace_dict
# "Invalid namespace %s..." % self.getId())
# else:
# if module_name in component_namespace.__dict__:
# LOG("ERP5Type.Core.DocumentComponent", INFO, "Reset %s..." % self.getId())
# getattr(component_namespace, module_name).restoreGhostState()
def load(self):
# XXX-arnau: There should be a load_source() taking a string rather than
# creating a temporary file
from App.config import getConfiguration
instance_home = getConfiguration().instancehome
path = '%s/Component' % instance_home
if not os.path.isdir(path):
os.mkdir(path)
component_path = '%s/%s.py' % (path, self.getId())
with open(component_path, 'w') as component_file:
component_file.write(self.getTextContent())
try:
return imp.load_source(self.getReference(), component_path)
finally:
os.remove(component_path)
...@@ -26,55 +26,33 @@ ...@@ -26,55 +26,33 @@
# #
############################################################################## ##############################################################################
from types import ModuleType
from zLOG import LOG, INFO from zLOG import LOG, INFO
class ComponentProxyClass(object):
"""
XXX-arnau: should maybe use Ghost class?
"""
def __init__(self, component, module):
self._component = component
self._module = module
self.__isghost__ = False
# XXX-arnau: metaclass!
self.__class__.__name__ = component.getReference()
self.__class__.__module__ = component.getId().rsplit('.', 1)[0]
description = component.getDescription()
if description:
self.__doc__ = description
def restoreGhostState(self):
self.__isghost__ = True
def __getattr__(self, name):
if self.__isghost__:
self._module = self._component.load()
self.__isghost__ = False
LOG("ERP5Type.dynamic", INFO, "Reloaded %s" % self._component.getId())
return getattr(self._module, name)
def generateComponentClassWrapper(namespace): def generateComponentClassWrapper(namespace):
def generateComponentClass(component_name): def generateComponentClass(component_name):
from Products.ERP5.ERP5Site import getSite from Products.ERP5.ERP5Site import getSite
site = getSite() site = getSite()
component_name = '%s.%s' % (namespace, component_name) component_id = '%s.%s' % (namespace, component_name)
try: try:
component = getattr(site.portal_components, component_name) component = getattr(site.portal_components, component_id)
except AttributeError: except AttributeError:
LOG("ERP5Type.dynamic", INFO, LOG("ERP5Type.dynamic", INFO,
"Could not find %s, perhaps it has not been migrated yet?" % component_name) "Could not find %s, perhaps it has not been migrated yet?" % \
component_id)
raise raise
else: else:
if component.getValidationState() == 'validated': if component.getValidationState() == 'validated':
klass = ComponentProxyClass(component, component.load()) new_module = ModuleType(component_name,
LOG("ERP5Type.dynamic", INFO, "Loaded successfully %s" % component_name) component.getDescription())
return klass
new_module.__module__ = component_id
component.load(new_module.__dict__)
LOG("ERP5Type.dynamic", INFO, "Loaded successfully %s" % component_id)
return new_module
else: else:
raise AttributeError("Component %s not validated" % component_name) raise AttributeError("Component %s not validated" % component_id)
return generateComponentClass return generateComponentClass
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