diff --git a/product/ERP5Type/Core/DocumentComponent.py b/product/ERP5Type/Core/DocumentComponent.py new file mode 100644 index 0000000000000000000000000000000000000000..822d5ca3fb182b1e316fe6ea0bec3d8a2103f9f3 --- /dev/null +++ b/product/ERP5Type/Core/DocumentComponent.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved. +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsibility of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# guarantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +# +############################################################################## + +from AccessControl import ClassSecurityInfo +from Products.CMFCore.utils import getToolByName +from Products.ERP5Type import Permissions, PropertySheet, Constraint, interfaces +from Products.ERP5Type.Base import Base + + +class DocumentComponent(Base): + # CMF Type Definition + meta_type = 'ERP5 Document Component' + portal_type = 'Document Component' + isPortalContent = 1 + isRADContent = 1 + isDelivery = 1 + + # Declarative security + security = ClassSecurityInfo() + security.declareObjectProtected(Permissions.AccessContentsInformation) + + # Declarative properties + property_sheets = ( PropertySheet.Base + , PropertySheet.XMLObject + , PropertySheet.CategoryCore + , PropertySheet.DublinCore + , PropertySheet.Version + , PropertySheet.TextDocument + ) + + def loadComponent(self): + """ + """ + from Products.ERP5Type.Utils import importLocalDocument + from App.config import getConfiguration + instance_home = getConfiguration().instancehome + path = '%s/component/document' % instance_home + component_path = '%s/%s.py' % (path, self.getReference()) # using ID would be better... with some extensions in importLocalDocument + component_file = open(component_path, 'w') + component_file.write(self.getTextContent()) + component_file.close() + importLocalDocument(self.getReference(), path=path) diff --git a/product/ERP5Type/Tool/ComponentTool.py b/product/ERP5Type/Tool/ComponentTool.py new file mode 100644 index 0000000000000000000000000000000000000000..15abdf03d8bb94615f66df750a057e78cc0d6a89 --- /dev/null +++ b/product/ERP5Type/Tool/ComponentTool.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2011 Nexedi SA and Contributors. All Rights Reserved. +# Jean-Paul Smets <jp@nexedi.com> +# +# WARNING: This program as such is intended to be used by professional +# programmers who take the whole responsability of assessing all potential +# consequences resulting from its eventual inadequacies and bugs +# End users who are looking for a ready-to-use solution with commercial +# garantees and support are strongly adviced to contract a Free Software +# Service Company +# +# This program is Free Software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################## + + +""" Component Tool module for ERP5 """ +from AccessControl import ClassSecurityInfo +from Products.ERP5Type.Tool.BaseTool import BaseTool +from Products.ERP5Type import Permissions + +class ComponentLoader: + """ + A callable class which delegates component load to ComponentTool + and which contains attributes which can either be called or + implement default component access for different types of components + """ + def __init__(self): + self.component = self + # This could be automated by introspecting + # portal_types and listing all component types + self.document = TypedComponentLoader('Document Component') + self.interface = TypedComponentLoader('Interface Component') + self.mixin = TypedComponentLoader('Mixin Component') + self.accessor = TypedComponentLoader('Accessor Component') + self.test = TypedComponentLoader('Test Component') + self.extension = TypedComponentLoader('Extension Component') + + def __call__(self, portal_type, reference, version=None): + site = getSite() + return site.portal_components.loadComponent(portal_type, reference, version=version) + +def TypedComponentLoader(ComponentLoader): + """ + A callable class which delegates component load to + ComponentLoader and provides default component access through + attributes. + """ + def __init__(self, portal_type): + self._portal_type = portal_type + + def __call__(self, reference, version=None): + return ComponentLoader.__call__(self._portal_type, reference, version=version) + + def __getattr__(self, key): + if key.startswith('_'): + return self.__dict__[key] + return self(key) + +component = ComponentLoader() + +component_revision = None +component_dict = None + +class ComponentTool(BaseTool): + """ + This tool provides methods to load the the different types + of components of the ERP5 framework: Document classes, interfaces, + mixin classes, fields, accessors, etc. + """ + + id = "portal_components" + meta_type = "ERP5 Component Tool" + portal_type = "Component Tool" + + security = ClassSecurityInfo() + manage_options = BaseTool.manage_options + + def loadComponent(self, portal_type, reference, version=None): + """ + This first version compiles all components once. A lazy + version could be more efficient. + """ + global component_dict + # Reset cache if modified + #if component_revision is None: + # component_dict = None + if component_dict is None: + component_dict = {} + for document in contentValues(): + portal_type = document.getPortalType() + version = document.getVersion() + reference = document.getReference() + component = document.loadComponent() + typed_component_dict = component_dict.setdefault(portal_type, {}) + component_version_dict = typed_component_dict.setdefault(reference, {}) + # How to handle default ? + component_version_dict[version] = component + component_version_dict[None] = component + return component_dict[portal_type][reference][version] diff --git a/product/ERP5Type/__init__.py b/product/ERP5Type/__init__.py index 2207ac4b3a4188c33c76874833c745ea49a546f8..9ac51f7793926bf602f07cd32f3a544b65a77868 100644 --- a/product/ERP5Type/__init__.py +++ b/product/ERP5Type/__init__.py @@ -96,7 +96,8 @@ def allowClassTool(): def initialize( context ): # Import Product Components from Tool import (ClassTool, CacheTool, MemcachedTool, SessionTool, - TypesTool, WebServiceTool, PropertySheetTool) + TypesTool, WebServiceTool, PropertySheetTool, + ComponentTool,) import Document from Base import Base, DocumentationHelper import XMLObject @@ -115,7 +116,8 @@ def initialize( context ): SessionTool.SessionTool, TypesTool.TypesTool, WebServiceTool.WebServiceTool, - PropertySheetTool.PropertySheetTool + PropertySheetTool.PropertySheetTool, + ComponentTool.ComponentTool, ) # Do initialization step initializeProduct(context, this_module, globals(),