Commit 86c84618 authored by Arnaud Fontaine's avatar Arnaud Fontaine

Implement Document Component.

Also, move code from Extension Component to Component and make it more generic
in order to be used for Document Component.
parent da5d4bdc
<property_sheet_list>
<portal_type id="Document Component">
<item>DocumentConstraint</item>
<item>Reference</item>
<item>SortIndex</item>
<item>Version</item>
</portal_type>
<portal_type id="Trash Bin">
<item>Base</item>
......
......@@ -82,7 +82,7 @@
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Component</string> </value>
<value> <string>DocumentComponent</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
......
......@@ -85,7 +85,7 @@
</chain>
<chain>
<type>Document Component</type>
<workflow>edit_workflow, validation_workflow</workflow>
<workflow>component_interaction_workflow, edit_workflow, validation_workflow</workflow>
</chain>
<chain>
<type>Dynamic Category Property</type>
......
......@@ -70,6 +70,7 @@
<key> <string>portal_type_filter</string> </key>
<value>
<list>
<string>Document Component</string>
<string>Extension Component</string>
</list>
</value>
......
2012-01-24 arnaud.fontaine
* Use DocumentComponent document class for Document Component Portal Type.
2012-01-23 arnaud.fontaine
* Rename DocumentComponent to Component.
......
40992
\ No newline at end of file
40993
\ No newline at end of file
Document Component | DocumentConstraint
Document Component | Reference
Document Component | SortIndex
Document Component | Version
Trash Bin | Base
Trash Bin | SimpleItem
Trash Bin | Task
\ No newline at end of file
......@@ -22,6 +22,7 @@ Category | edit_workflow
Content Existence Constraint | dynamic_class_generation_interaction_workflow
Distributed Ram Cache | distributed_ram_cache_interaction_workflow
Document | edit_workflow
Document Component | component_interaction_workflow
Document Component | edit_workflow
Document Component | validation_workflow
Dynamic Category Property | dynamic_class_generation_interaction_workflow
......
......@@ -34,6 +34,8 @@ from Products.ERP5Type.Base import Base
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage
from zLOG import LOG, INFO
class Component(Base):
# CMF Type Definition
meta_type = 'ERP5 Component'
......@@ -86,3 +88,67 @@ class Component(Base):
source code before validate.
"""
exec self.getTextContent() in namespace_dict
@staticmethod
def _getFilesystemPath():
raise NotImplementedError
security.declareProtected(Permissions.ModifyPortalContent,
'importAllFromFilesystem')
@classmethod
def importAllFromFilesystem(cls, context, erase_existing=False):
"""
Try to import all Components and returns error as a dict if any
"""
import os.path
path_pattern = "%s%s*.py" % (cls._getFilesystemPath(), os.path.sep)
LOG("ERP5Type.Core.Component", INFO, "Importing from %s" % path_pattern)
import glob
failed_import_dict = {}
for path in glob.iglob(path_pattern):
try:
cls.importFromFilesystem(context, path, erase_existing)
except Exception, e:
failed_import_dict[path] = str(e)
else:
LOG("ERP5Type.Core.Component", INFO, "Imported %s" % path)
return failed_import_dict
@staticmethod
def _getDynamicModuleNamespace():
raise NotImplementedError
security.declareProtected(Permissions.ModifyPortalContent,
'importFromFilesystem')
@classmethod
def importFromFilesystem(cls, context, path, erase_existing=False):
"""
Import a Component from the given path into ZODB after checking that the
source code is valid
"""
import os.path
class_name = os.path.basename(path).replace('.py', '')
id = '%s.%s' % (cls._getDynamicModuleNamespace(), class_name)
# XXX-arnau: not efficient at all
if id in context:
if not erase_existing:
return
context.deleteContent(id)
with open(path) as f:
source_code = f.read()
# Try to load it first
namespace_dict = {}
exec source_code in namespace_dict
return context.newContent(id=id,
# XXX-arnau: useless field?
reference=class_name,
text_content=source_code,
portal_type=cls.portal_type)
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
# Arnaud Fontaine <arnaud.fontaine@nexedi.com>
#
# 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 Products.ERP5Type.Core.Component import Component
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
class DocumentComponent(Component):
# CMF Type Definition
meta_type = 'ERP5 Document Component'
portal_type = 'Component Component'
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
@staticmethod
def _getFilesystemPath():
import os.path
from App.config import getConfiguration
return os.path.join(getConfiguration().instancehome, 'Document')
@staticmethod
def _getDynamicModuleNamespace():
return 'erp5.component.document'
......@@ -27,14 +27,10 @@
#
##############################################################################
import os.path
from Products.ERP5Type.Core.Component import Component
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from zLOG import LOG, INFO
class ExtensionComponent(Component):
# CMF Type Definition
meta_type = 'ERP5 Extension Component'
......@@ -44,62 +40,12 @@ class ExtensionComponent(Component):
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.ModifyPortalContent,
'importAllFromFilesystem')
@classmethod
def importAllFromFilesystem(cls, context, erase_existing=False):
"""
Try to import all Extensions as found in INSTANCEHOME/Extensions and
returns error as a dict if any
"""
@staticmethod
def _getFilesystemPath():
import os.path
from App.config import getConfiguration
extension_path_pattern = "%s%s%s/*" % (getConfiguration().instancehome,
os.path.sep,
'Extensions')
LOG("ERP5Type.Core.ExtensionComponent", INFO,
"Importing from %s" % extension_path_pattern)
import glob
failed_import_dict = {}
for extension_path in glob.iglob(extension_path_pattern):
try:
cls.importFromFilesystem(context, extension_path, erase_existing)
except Exception, e:
failed_import_dict[extension_path] = str(e)
else:
LOG("ERP5Type.Core.ExtensionComponent", INFO,
"Imported %s" % extension_path)
return failed_import_dict
security.declareProtected(Permissions.ModifyPortalContent,
'importFromFilesystem')
@classmethod
def importFromFilesystem(cls, context, path, erase_existing=False):
"""
Import an Extension from the given path into ZODB after checking that the
source code is valid
"""
class_name = os.path.basename(path).replace('.py', '')
id = 'erp5.component.extension.%s' % class_name
# XXX-arnau: not efficient at all
if id in context:
if not erase_existing:
return
context.deleteContent(id)
with open(path) as extension_file:
source_code = extension_file.read()
# Try to load it first
namespace_dict = {}
exec source_code in namespace_dict
return os.path.join(getConfiguration().instancehome, 'Extensions')
return context.newContent(id=id,
# XXX-arnau: useless field?
reference=class_name,
text_content=source_code,
portal_type=cls.portal_type)
@staticmethod
def _getDynamicModuleNamespace():
return 'erp5.component.extension'
......@@ -130,3 +130,7 @@ def initializeDynamicModules():
erp5.component.extension = registerDynamicModule(
'erp5.component.extension',
generateComponentClassWrapper('erp5.component.extension'))
erp5.component.document = registerDynamicModule(
'erp5.component.document',
generateComponentClassWrapper('erp5.component.document'))
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