Commit d8961c51 authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: Allow migration of {Interface,Mixin,Module,Tool} from...

ZODB Components: Allow migration of {Interface,Mixin,Module,Tool} from Business Template UI and on all Products (not only Products.ERP5).

This introduces the following new ZODB Components:
  + Module Component: Non-Documents/non-persistent classes of modules usually
    found at the top-level of Products (eg Products.ERP5.XXX) on FS. Considering
    that all other Components types are actually Modules, make it the base class.
  + Tool Component: Tool directory of Products on FS (eg Products.ERP5.Tool.XXX).
    => DiffTool and CallableTool are now 'Tool Component' instead of plain
       'Document Component' and properly registered as Tools like FS Products Tool.

Skip CMFActivity and HBTreeFolder2 Products for now in migration View for now as
almost many Portal Type classes have ActiveObject or HBTreeFolder2 in their MRO
and these Products will be done at the end anyway...
parent a4e63da9
This diff is collapsed.
...@@ -69,9 +69,11 @@ item_name_list = ( ...@@ -69,9 +69,11 @@ item_name_list = (
'registered_version_priority_selection', 'registered_version_priority_selection',
'workflow', 'workflow',
'product', 'product',
'module_component',
'document', 'document',
'interface', 'interface',
'mixin', 'mixin',
'tool_component',
'property_sheet', 'property_sheet',
'constraint', 'constraint',
'extension', 'extension',
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ComponentMixin_view</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: object is not None and not object.isWebMode()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ComponentMixin_view</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: object is not None and not object.isWebMode()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -53,7 +53,9 @@ ...@@ -53,7 +53,9 @@
<item>Extension Component</item> <item>Extension Component</item>
<item>Interface Component</item> <item>Interface Component</item>
<item>Mixin Component</item> <item>Mixin Component</item>
<item>Module Component</item>
<item>Test Component</item> <item>Test Component</item>
<item>Tool Component</item>
</portal_type> </portal_type>
<portal_type id="Contribution Registry Tool"> <portal_type id="Contribution Registry Tool">
<item>Contribution Predicate</item> <item>Contribution Predicate</item>
......
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
<portal_type id="Mixin Component"> <portal_type id="Mixin Component">
<item>SortIndex</item> <item>SortIndex</item>
</portal_type> </portal_type>
<portal_type id="Module Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Property Existence Constraint"> <portal_type id="Property Existence Constraint">
<item>ConstraintType</item> <item>ConstraintType</item>
</portal_type> </portal_type>
...@@ -79,6 +82,9 @@ ...@@ -79,6 +82,9 @@
<portal_type id="Test Component"> <portal_type id="Test Component">
<item>SortIndex</item> <item>SortIndex</item>
</portal_type> </portal_type>
<portal_type id="Tool Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Trash Bin"> <portal_type id="Trash Bin">
<item>Base</item> <item>Base</item>
<item>SimpleItem</item> <item>SimpleItem</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_property_domain_dict</string> </key>
<value>
<dictionary>
<item>
<key> <string>short_title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>web_page.png</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Text Document</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A Module Component is any non-persistent Module containing classes definitions (used to be found at the root of Products).</string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addDocumentComponent</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Module Component</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>ModuleComponent</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value> <string>erp5_content</string> </value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>short_title</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value> <string>erp5_content</string> </value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>title</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_property_domain_dict</string> </key>
<value>
<dictionary>
<item>
<key> <string>short_title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>web_page.png</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Text Document</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A Tool Component as used to be found in Products.XXX.Tool</string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addDocumentComponent</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Tool Component</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>ToolComponent</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value> <string>erp5_content</string> </value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>short_title</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value> <string>erp5_content</string> </value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>title</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -123,6 +123,10 @@ ...@@ -123,6 +123,10 @@
<type>Mixin Component</type> <type>Mixin Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow> <workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain> </chain>
<chain>
<type>Module Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
<chain> <chain>
<type>Predicate</type> <type>Predicate</type>
<workflow>edit_workflow</workflow> <workflow>edit_workflow</workflow>
...@@ -175,4 +179,8 @@ ...@@ -175,4 +179,8 @@
<type>Test Component</type> <type>Test Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow> <workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain> </chain>
<chain>
<type>Tool Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
...@@ -64,11 +64,13 @@ ...@@ -64,11 +64,13 @@
<list> <list>
<string>my_template_role_list</string> <string>my_template_role_list</string>
<string>my_template_site_property_id_list</string> <string>my_template_site_property_id_list</string>
<string>my_template_module_component_id_list</string>
<string>my_template_interface_id_list</string> <string>my_template_interface_id_list</string>
<string>my_template_mixin_id_list</string> <string>my_template_mixin_id_list</string>
<string>my_template_document_id_list</string> <string>my_template_document_id_list</string>
<string>my_template_property_sheet_id_list</string> <string>my_template_property_sheet_id_list</string>
<string>my_template_extension_id_list</string> <string>my_template_extension_id_list</string>
<string>my_template_tool_component_id_list</string>
<string>my_template_tool_id_list</string> <string>my_template_tool_id_list</string>
<string>my_template_preference_list</string> <string>my_template_preference_list</string>
<string>my_template_update_tool</string> <string>my_template_update_tool</string>
......
...@@ -2,31 +2,27 @@ ...@@ -2,31 +2,27 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Document Component" module="erp5.portal_type"/> <global name="Tool Component" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>CallableTool</string> </value> <value> <string>CallableTool</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>A tool that can be used to add scripts and other callable methods (including ZSQL templates and HTML templates) to ERP5. It replaces portal_skins</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>document.erp5.CallableTool</string> </value> <value> <string>tool.erp5.CallableTool</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value> <value> <string>Tool Component</string> </value>
</item> </item>
<item> <item>
<key> <string>sid</string> </key> <key> <string>sid</string> </key>
...@@ -53,28 +49,13 @@ ...@@ -53,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -87,7 +68,7 @@ ...@@ -87,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -96,7 +77,7 @@ ...@@ -96,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
...@@ -2,31 +2,27 @@ ...@@ -2,31 +2,27 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Document Component" module="erp5.portal_type"/> <global name="Tool Component" module="erp5.portal_type"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>DiffTool</string> </value> <value> <string>DiffTool</string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>description</string> </key>
<value> <string>A tool than can be used to Diff any 2 objects of same module.</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>document.erp5.DiffTool</string> </value> <value> <string>tool.erp5.DiffTool</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value> <value> <string>Tool Component</string> </value>
</item> </item>
<item> <item>
<key> <string>sid</string> </key> <key> <string>sid</string> </key>
...@@ -53,28 +49,13 @@ ...@@ -53,28 +49,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -87,7 +68,7 @@ ...@@ -87,7 +68,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -96,7 +77,7 @@ ...@@ -96,7 +77,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
...@@ -74,7 +74,9 @@ ...@@ -74,7 +74,9 @@
<string>Extension Component</string> <string>Extension Component</string>
<string>Interface Component</string> <string>Interface Component</string>
<string>Mixin Component</string> <string>Mixin Component</string>
<string>Module Component</string>
<string>Test Component</string> <string>Test Component</string>
<string>Tool Component</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -73,7 +73,9 @@ ...@@ -73,7 +73,9 @@
<string>Extension Component</string> <string>Extension Component</string>
<string>Interface Component</string> <string>Interface Component</string>
<string>Mixin Component</string> <string>Mixin Component</string>
<string>Module Component</string>
<string>Test Component</string> <string>Test Component</string>
<string>Tool Component</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -89,6 +89,7 @@ Interface Component | view ...@@ -89,6 +89,7 @@ Interface Component | view
Memcached Plugin | view Memcached Plugin | view
Memcached Tool | view Memcached Tool | view
Mixin Component | view Mixin Component | view
Module Component | view
Predicate | view Predicate | view
Preference Tool Type | jump_property_sheets Preference Tool Type | jump_property_sheets
Preference Tool Type | view Preference Tool Type | view
...@@ -147,6 +148,7 @@ Template Tool | upgrade_from_repository ...@@ -147,6 +148,7 @@ Template Tool | upgrade_from_repository
Template Tool | view Template Tool | view
Test Component | run_live_test Test Component | run_live_test
Test Component | view Test Component | view
Tool Component | view
Trash Bin | jump_bt5 Trash Bin | jump_bt5
Trash Bin | view Trash Bin | view
Trash Folder | view Trash Folder | view
......
document.erp5.DiffTool
document.erp5.ScriptConstraint document.erp5.ScriptConstraint
document.erp5.TransformOdtToDocx document.erp5.TransformOdtToDocx
document.erp5.TransformOdtToHtml document.erp5.TransformOdtToHtml
...@@ -28,4 +27,3 @@ document.erp5.TransformPptxToPpty ...@@ -28,4 +27,3 @@ document.erp5.TransformPptxToPpty
document.erp5.TransformPptyToPptx document.erp5.TransformPptyToPptx
document.erp5.TransformImageToPcx document.erp5.TransformImageToPcx
document.erp5.TransformImageToBmp document.erp5.TransformImageToBmp
\ No newline at end of file
document.erp5.CallableTool
\ No newline at end of file
...@@ -23,7 +23,9 @@ Component Tool | Document Component ...@@ -23,7 +23,9 @@ Component Tool | Document Component
Component Tool | Extension Component Component Tool | Extension Component
Component Tool | Interface Component Component Tool | Interface Component
Component Tool | Mixin Component Component Tool | Mixin Component
Component Tool | Module Component
Component Tool | Test Component Component Tool | Test Component
Component Tool | Tool Component
Contribution Registry Tool | Contribution Predicate Contribution Registry Tool | Contribution Predicate
Domain Tool | Base Domain Domain Tool | Base Domain
Domain | Domain Domain | Domain
......
...@@ -53,6 +53,7 @@ Mapped Value ...@@ -53,6 +53,7 @@ Mapped Value
Memcached Plugin Memcached Plugin
Memcached Tool Memcached Tool
Mixin Component Mixin Component
Module Component
Movement Movement
Notification Tool Notification Tool
Order Tool Order Tool
...@@ -85,6 +86,7 @@ TALES Constraint ...@@ -85,6 +86,7 @@ TALES Constraint
Template Tool Template Tool
Test Component Test Component
Test Tool Test Tool
Tool Component
Trash Bin Trash Bin
Trash Folder Trash Folder
Trash Tool Trash Tool
......
...@@ -14,6 +14,7 @@ Document Component | SortIndex ...@@ -14,6 +14,7 @@ Document Component | SortIndex
Extension Component | SortIndex Extension Component | SortIndex
Interface Component | SortIndex Interface Component | SortIndex
Mixin Component | SortIndex Mixin Component | SortIndex
Module Component | SortIndex
Property Existence Constraint | ConstraintType Property Existence Constraint | ConstraintType
Property Type Validity Constraint | ConstraintType Property Type Validity Constraint | ConstraintType
Python Script | CatalogFilter Python Script | CatalogFilter
...@@ -29,6 +30,7 @@ Simulation Movement | SortIndex ...@@ -29,6 +30,7 @@ Simulation Movement | SortIndex
String Attribute Match Constraint | ConstraintType String Attribute Match Constraint | ConstraintType
TALES Constraint | ConstraintType TALES Constraint | ConstraintType
Test Component | SortIndex Test Component | SortIndex
Tool Component | SortIndex
Trash Bin | Base Trash Bin | Base
Trash Bin | SimpleItem Trash Bin | SimpleItem
Trash Bin | Task Trash Bin | Task
\ No newline at end of file
...@@ -40,6 +40,9 @@ Memcached Plugin | memcached_plugin_interaction_workflow ...@@ -40,6 +40,9 @@ Memcached Plugin | memcached_plugin_interaction_workflow
Mixin Component | component_validation_workflow Mixin Component | component_validation_workflow
Mixin Component | dynamic_class_generation_interaction_workflow Mixin Component | dynamic_class_generation_interaction_workflow
Mixin Component | edit_workflow Mixin Component | edit_workflow
Module Component | component_validation_workflow
Module Component | dynamic_class_generation_interaction_workflow
Module Component | edit_workflow
Predicate | edit_workflow Predicate | edit_workflow
Preference | edit_workflow Preference | edit_workflow
Preference | preference_workflow Preference | preference_workflow
...@@ -57,3 +60,6 @@ TALES Constraint | dynamic_class_generation_interaction_workflow ...@@ -57,3 +60,6 @@ TALES Constraint | dynamic_class_generation_interaction_workflow
Test Component | component_validation_workflow Test Component | component_validation_workflow
Test Component | dynamic_class_generation_interaction_workflow Test Component | dynamic_class_generation_interaction_workflow
Test Component | edit_workflow Test Component | edit_workflow
Tool Component | component_validation_workflow
Tool Component | dynamic_class_generation_interaction_workflow
Tool Component | edit_workflow
\ No newline at end of file
tool.erp5.CallableTool
tool.erp5.DiffTool
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/lines</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A list of IDs of Module (not a Tool, Document, Interface or Mixin) ZODB Components</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_module_component_id_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: ()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/lines</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A list of IDs of Tool ZODB Components</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_tool_component_id_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: ()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -7840,6 +7840,7 @@ class _ProductMigrationTemplateItemMixin: ...@@ -7840,6 +7840,7 @@ class _ProductMigrationTemplateItemMixin:
""" """
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = """ sequence_string = """
SetPreferredWorkingCopyList
CreateProductDocumentAndPortalType CreateProductDocumentAndPortalType
CreateNewBusinessTemplate CreateNewBusinessTemplate
UseExportBusinessTemplate UseExportBusinessTemplate
...@@ -8189,6 +8190,30 @@ class _LocalTemplateItemMixin: ...@@ -8189,6 +8190,30 @@ class _LocalTemplateItemMixin:
sequence_list.addSequenceString(sequence_string) sequence_list.addSequenceString(sequence_string)
sequence_list.play(self) sequence_list.play(self)
def stepSetPreferredWorkingCopyList(self, sequence=None, **kw):
"""
TODO: Merge with Zuite_setPreference (ERP5TypeFunctionalTestCase)?
"""
pref = getattr(self.portal.portal_preferences,
"testBusinessTemplate_test_preference",
None)
if pref is None:
pref = self.portal.portal_preferences.newContent(
id="testBusinessTemplate_test_preference",
portal_type="Preference",
priority=1)
import inspect
import Products.ERP5
erp5_product_directory = os.path.realpath(
inspect.getsourcefile(Products.ERP5)).rsplit('/', 1)[0]
pref.setPreferredWorkingCopyList(
[erp5_product_directory.rsplit('/', 2)[0] + '/bt5',
erp5_product_directory + '/bootstrap'])
if pref.getPreferenceState() == 'disabled':
pref.enable()
def stepCopyAndMigrateDocumentBusinessTemplate(self, sequence=None, **kw): def stepCopyAndMigrateDocumentBusinessTemplate(self, sequence=None, **kw):
""" """
Simulate migration from filesystem to ZODB Simulate migration from filesystem to ZODB
...@@ -8243,6 +8268,7 @@ class _LocalTemplateItemMixin: ...@@ -8243,6 +8268,7 @@ class _LocalTemplateItemMixin:
""" """
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = '\ sequence_string = '\
SetPreferredWorkingCopyList \
CreateDocument \ CreateDocument \
CreateNewBusinessTemplate \ CreateNewBusinessTemplate \
UseExportBusinessTemplate \ UseExportBusinessTemplate \
...@@ -8313,6 +8339,7 @@ class _LocalTemplateItemMixin: ...@@ -8313,6 +8339,7 @@ class _LocalTemplateItemMixin:
def test_BusinessTemplateUpgradeDocumentFromFilesystemToZodb(self): def test_BusinessTemplateUpgradeDocumentFromFilesystemToZodb(self):
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = """ sequence_string = """
SetPreferredWorkingCopyList
CreateDocument CreateDocument
CreateNewBusinessTemplate CreateNewBusinessTemplate
UseExportBusinessTemplate UseExportBusinessTemplate
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage
...@@ -37,7 +37,7 @@ import zope.interface ...@@ -37,7 +37,7 @@ import zope.interface
import re import re
from Products.ERP5Type.interfaces.component import IComponent from Products.ERP5Type.interfaces.component import IComponent
class DocumentComponent(ComponentMixin, TextContentHistoryMixin): class DocumentComponent(ModuleComponent):
""" """
ZODB Component for Documents in bt5 only for now (which used to be installed ZODB Component for Documents in bt5 only for now (which used to be installed
in INSTANCE_HOME/Document) but this will also be used later on for Documents in INSTANCE_HOME/Document) but this will also be used later on for Documents
......
...@@ -27,15 +27,15 @@ ...@@ -27,15 +27,15 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
import zope.interface import zope.interface
from Products.ERP5Type.interfaces.component import IComponent from Products.ERP5Type.interfaces.component import IComponent
class ExtensionComponent(ComponentMixin, TextContentHistoryMixin): class ExtensionComponent(ModuleComponent):
""" """
ZODB Component for Extensions previously defined in the bt5 and installed in ZODB Component for Extensions previously defined in the bt5 and installed in
INSTANCE_HOME/Extensions INSTANCE_HOME/Extensions
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2019 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.mixin.component import ComponentMixin
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
import zope.interface
from Products.ERP5Type.interfaces.component import IComponent
class ModuleComponent(ComponentMixin, TextContentHistoryMixin):
"""
ZODB Component for Modules, eg non-Documents from Products, and the base
class for all other Components
"""
meta_type = 'ERP5 Module Component'
portal_type = 'Module Component'
zope.interface.implements(IComponent)
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
@staticmethod
def _getFilesystemPath():
# TODO-arnau: useful?
raise NotImplementedError
@staticmethod
def _getDynamicModuleNamespace():
return 'erp5.component.module'
@staticmethod
def getIdPrefix():
return 'module'
...@@ -27,15 +27,15 @@ ...@@ -27,15 +27,15 @@
# #
############################################################################## ##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
import zope.interface import zope.interface
from Products.ERP5Type.interfaces.component import IComponent from Products.ERP5Type.interfaces.component import IComponent
class TestComponent(ComponentMixin, TextContentHistoryMixin): class TestComponent(ModuleComponent):
""" """
ZODB Component for Live Tests only (previously defined in the bt5 and ZODB Component for Live Tests only (previously defined in the bt5 and
installed in INSTANCE_HOME/tests) as other kind of Tests should be installed in INSTANCE_HOME/tests) as other kind of Tests should be
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2019 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.DocumentComponent import DocumentComponent
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
import zope.interface
from Products.ERP5Type.interfaces.component import IComponent
from Products.CMFCore import utils
class ToolComponent(DocumentComponent):
"""
ZODB Component for Tools, used to be found on Products.XXX.Tool on FS
"""
meta_type = 'ERP5 Tool Component'
portal_type = 'Tool Component'
zope.interface.implements(IComponent)
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _hookAfterLoad(self, module_obj):
"""
Register Tool so that it can be added in ZMI through manage_addToolForm.
For FS Tools, this is done during Product initialize() by
Products.CMFCore.utils.ToolInit.
"""
tool_class = getattr(module_obj, self.getReference())
# Should we really use ERP5 Product and not ERP5Type considering that ERP5
# may be gone at some point? Or the other way around? For now, all tools
# have meta_type='ERP5 ...' so just use ERP5 Product.
import Products.ERP5
toolinit = Products.ERP5.__FactoryDispatcher__.toolinit
# Products.CMFCore.utils.ToolInit.initialize()
tool_class.__factory_meta_type__ = toolinit.meta_type
tool_class.icon = 'misc_/%s/%s' % ('ERP5', toolinit.icon)
toolinit.tools.add(tool_class)
@staticmethod
def _getFilesystemPath():
# TODO-arnau: useful?
raise NotImplementedError
@staticmethod
def _getDynamicModuleNamespace():
return 'erp5.component.tool'
@staticmethod
def getIdPrefix():
return 'tool'
...@@ -61,7 +61,9 @@ class PropertySheetTool(BaseTool): ...@@ -61,7 +61,9 @@ class PropertySheetTool(BaseTool):
_bootstrap_business_template_property_tuple = ( _bootstrap_business_template_property_tuple = (
'template_catalog_security_uid_column_property', 'template_catalog_security_uid_column_property',
'template_interface_id_property', 'template_interface_id_property',
'template_mixin_id_property') 'template_mixin_id_property',
'template_module_component_id_property',
'template_tool_component_id_property')
def _isBootstrapRequired(self): def _isBootstrapRequired(self):
if not self.has_key('BaseType'): if not self.has_key('BaseType'):
......
...@@ -257,7 +257,8 @@ class TypesTool(TypeProvider): ...@@ -257,7 +257,8 @@ class TypesTool(TypeProvider):
Documents) that can be used as Base classes Documents) that can be used as Base classes
""" """
from Products.ERP5Type import document_class_registry from Products.ERP5Type import document_class_registry
return self._getTypeList('Document Component', document_class_registry) return self._getTypeList(('Document Component', 'Tool Component'),
document_class_registry)
security.declareProtected(Permissions.AccessContentsInformation, 'getMixinTypeList') security.declareProtected(Permissions.AccessContentsInformation, 'getMixinTypeList')
def getMixinTypeList(self): def getMixinTypeList(self):
......
...@@ -1168,13 +1168,13 @@ def initializeProduct( context, ...@@ -1168,13 +1168,13 @@ def initializeProduct( context,
registerDocumentClass(tool.__module__, tool.__name__) registerDocumentClass(tool.__module__, tool.__name__)
try: try:
utils.ToolInit('%s Tool' % product_name, utils.ToolInit('%s Tool' % product_name,
tools=tools, tools=set(tools),
icon='tool.png', icon='tool.png',
).initialize( context ) ).initialize( context )
except TypeError: except TypeError:
# product_name parameter is deprecated in CMF # product_name parameter is deprecated in CMF
utils.ToolInit('%s Tool' % product_name, utils.ToolInit('%s Tool' % product_name,
tools=tools, tools=set(tools),
product_name=product_name, product_name=product_name,
icon='tool.png', icon='tool.png',
).initialize( context ) ).initialize( context )
......
...@@ -318,10 +318,12 @@ class ComponentDynamicPackage(ModuleType): ...@@ -318,10 +318,12 @@ class ComponentDynamicPackage(ModuleType):
import erp5.component import erp5.component
erp5.component.ref_manager.add_module(module) erp5.component.ref_manager.add_module(module)
return module
finally: finally:
imp.release_lock() imp.release_lock()
component._hookAfterLoad(module)
return module
def load_module(self, fullname): def load_module(self, fullname):
""" """
Make sure that loading module is thread-safe using aq_method_lock to make Make sure that loading module is thread-safe using aq_method_lock to make
...@@ -411,3 +413,18 @@ class ComponentDynamicPackage(ModuleType): ...@@ -411,3 +413,18 @@ class ComponentDynamicPackage(ModuleType):
del sys.modules[module_name] del sys.modules[module_name]
delattr(package, name) delattr(package, name)
class ToolComponentDynamicPackage(ComponentDynamicPackage):
def reset(self, *args, **kw):
"""
Reset CMFCore list of Tools (manage_addToolForm)
"""
import Products.ERP5
toolinit = Products.ERP5.__FactoryDispatcher__.toolinit
reset_tool_set = set()
for tool in toolinit.tools:
if not tool.__module__.startswith(self._namespace_prefix):
reset_tool_set.add(tool)
toolinit.tools = reset_tool_set
super(ToolComponentDynamicPackage, self).reset(*args, **kw)
...@@ -180,12 +180,16 @@ def initializeDynamicModules(): ...@@ -180,12 +180,16 @@ def initializeDynamicModules():
holds accessors holders of Portal Types holds accessors holders of Portal Types
erp5.component: erp5.component:
holds ZODB Component packages holds ZODB Component packages
erp5.component.module:
holds Module (eg any module not being one of the following and used to be found in Products.NAME on FS)
erp5.component.document: erp5.component.document:
holds Document modules previously found in bt5 in $INSTANCE_HOME/Document holds Document modules previously found in bt5 in $INSTANCE_HOME/Document
erp5.component.interface: erp5.component.interface:
holds Interface modules previously found in Products.NAME.interfaces holds Interface modules previously found in Products.NAME.interfaces
erp5.component.mixin: erp5.component.mixin:
holds Mixin modules previously found in Products.NAME.mixin holds Mixin modules previously found in Products.NAME.mixin
erp5.component.Tool:
holds Tool modules previously found in Products.NAME.Tool
erp5.component.extension: erp5.component.extension:
holds Extension modules previously found in bt5 in holds Extension modules previously found in bt5 in
$INSTANCE_HOME/Extensions $INSTANCE_HOME/Extensions
...@@ -221,7 +225,8 @@ def initializeDynamicModules(): ...@@ -221,7 +225,8 @@ def initializeDynamicModules():
# ZODB Components # ZODB Components
erp5.component = ComponentPackageType("erp5.component") erp5.component = ComponentPackageType("erp5.component")
from component_package import ComponentDynamicPackage from component_package import (ComponentDynamicPackage,
ToolComponentDynamicPackage)
# Prevent other threads to create erp5.* packages and modules or seeing them # Prevent other threads to create erp5.* packages and modules or seeing them
# incompletely # incompletely
...@@ -234,12 +239,18 @@ def initializeDynamicModules(): ...@@ -234,12 +239,18 @@ def initializeDynamicModules():
erp5.accessor_holder.property_sheet erp5.accessor_holder.property_sheet
sys.modules["erp5.component"] = erp5.component sys.modules["erp5.component"] = erp5.component
erp5.component.module = ComponentDynamicPackage('erp5.component.module',
'Module Component')
erp5.component.extension = ComponentDynamicPackage('erp5.component.extension', erp5.component.extension = ComponentDynamicPackage('erp5.component.extension',
'Extension Component') 'Extension Component')
erp5.component.document = ComponentDynamicPackage('erp5.component.document', erp5.component.document = ComponentDynamicPackage('erp5.component.document',
'Document Component') 'Document Component')
erp5.component.tool = ToolComponentDynamicPackage('erp5.component.tool',
'Tool Component')
erp5.component.interface = ComponentDynamicPackage('erp5.component.interface', erp5.component.interface = ComponentDynamicPackage('erp5.component.interface',
'Interface Component') 'Interface Component')
......
...@@ -212,6 +212,14 @@ def generatePortalTypeClass(site, portal_type_name): ...@@ -212,6 +212,14 @@ def generatePortalTypeClass(site, portal_type_name):
type_class_namespace = document_class_registry.get(type_class, '') type_class_namespace = document_class_registry.get(type_class, '')
if not (type_class_namespace.startswith('Products.ERP5Type') or if not (type_class_namespace.startswith('Products.ERP5Type') or
portal_type_name in core_portal_type_class_dict): portal_type_name in core_portal_type_class_dict):
module = None
if portal_type_name.endswith('Tool'):
import erp5.component.tool
module = erp5.component.tool.find_load_module(type_class)
# Tool Component was introduced recently and some Tool have already been
# migrated as Document Component
if module is None:
import erp5.component.document import erp5.component.document
module = erp5.component.document.find_load_module(type_class) module = erp5.component.document.find_load_module(type_class)
if module is not None: if module is not None:
...@@ -230,7 +238,14 @@ def generatePortalTypeClass(site, portal_type_name): ...@@ -230,7 +238,14 @@ def generatePortalTypeClass(site, portal_type_name):
% (type_class, portal_type_name)) % (type_class, portal_type_name))
if klass is None: if klass is None:
try:
klass = _importClass(type_class_path) klass = _importClass(type_class_path)
except ImportError:
error_msg = 'Could not import %s of Portal Type %s' % (type_class,
portal_type_name)
LOG("ERP5Type.Dynamic", WARNING, error_msg, error=True)
raise AttributeError(error_msg)
global property_sheet_generating_portal_type_set global property_sheet_generating_portal_type_set
......
...@@ -36,6 +36,12 @@ class IComponent(Interface): ...@@ -36,6 +36,12 @@ class IComponent(Interface):
Extensions or Documents, or any interfaces, mixin and Documents from Extensions or Documents, or any interfaces, mixin and Documents from
Products. Any Component class must implement this interface Products. Any Component class must implement this interface
""" """
def _hookAfterLoad(self, module_obj):
"""
Idempotent hook called after loading the module
"""
pass
def checkConsistency(obj, *args, **kwargs): def checkConsistency(obj, *args, **kwargs):
""" """
Check the consistency of a ZODB Component when validating from draft state Check the consistency of a ZODB Component when validating from draft state
...@@ -68,7 +74,12 @@ class IComponent(Interface): ...@@ -68,7 +74,12 @@ class IComponent(Interface):
Return the ID prefix for Component objects Return the ID prefix for Component objects
""" """
def importFromFilesystem(cls, context, reference, version, source_reference=None): def importFromFilesystem(cls,
context,
reference,
version,
source_reference=None,
filesystem_zodb_module_mapping_set=None):
""" """
Import a Component from the filesystem into ZODB after checking that the Import a Component from the filesystem into ZODB after checking that the
source code is valid source code is valid
......
...@@ -193,6 +193,9 @@ class ComponentMixin(PropertyRecordableMixin, Base): ...@@ -193,6 +193,9 @@ class ComponentMixin(PropertyRecordableMixin, Base):
_message_text_content_not_set = "No source code" _message_text_content_not_set = "No source code"
_message_text_content_error = "Error in Source Code: ${error_message}" _message_text_content_error = "Error in Source Code: ${error_message}"
def _hookAfterLoad(self, module_obj):
pass
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getValidationState') 'getValidationState')
def getValidationState(self): def getValidationState(self):
...@@ -352,7 +355,12 @@ class ComponentMixin(PropertyRecordableMixin, Base): ...@@ -352,7 +355,12 @@ class ComponentMixin(PropertyRecordableMixin, Base):
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
'importFromFilesystem') 'importFromFilesystem')
@classmethod @classmethod
def importFromFilesystem(cls, context, reference, version, source_reference=None): def importFromFilesystem(cls,
context,
reference,
version,
source_reference=None,
filesystem_zodb_module_mapping_set=None):
""" """
Import a Component from the filesystem into ZODB and validate it so it can Import a Component from the filesystem into ZODB and validate it so it can
be loaded straightaway provided validate() does not raise any error of be loaded straightaway provided validate() does not raise any error of
...@@ -368,7 +376,20 @@ class ComponentMixin(PropertyRecordableMixin, Base): ...@@ -368,7 +376,20 @@ class ComponentMixin(PropertyRecordableMixin, Base):
path = inspect.getsourcefile(module_obj) path = inspect.getsourcefile(module_obj)
with open(path) as f: with open(path) as f:
if filesystem_zodb_module_mapping_set is None:
source_code = f.read() source_code = f.read()
else:
source_code_line_list = []
for line in f:
for (filesystem_module,
zodb_module) in filesystem_zodb_module_mapping_set:
if line.startswith("from " + filesystem_module):
line = line.replace(filesystem_module, zodb_module, 1)
break
source_code_line_list.append(line)
source_code = ''.join(source_code_line_list)
# Checking that the source code is syntactically correct is not # Checking that the source code is syntactically correct is not
# needed when importing from filesystem, moreover errors may occur # needed when importing from filesystem, moreover errors may occur
......
...@@ -65,3 +65,37 @@ def _setCacheHeaders(obj, extra_context): ...@@ -65,3 +65,37 @@ def _setCacheHeaders(obj, extra_context):
import Products.CMFCore.utils import Products.CMFCore.utils
Products.CMFCore.utils._setCacheHeaders = _setCacheHeaders Products.CMFCore.utils._setCacheHeaders = _setCacheHeaders
# To load all erp5.component.tool.* so that they can be added through 'ERP5
# Site' => Add 'ERP5 Tool'.
from Products.CMFCore.utils import addInstanceForm
def manage_addToolForm(self, REQUEST):
""" Show the add tool form.
"""
from Products.ERP5.ERP5Site import getSite
import erp5.component.tool
seen_tool_component_set = set()
for tool_component in getSite().portal_components.objectValues(portal_type='Tool Component'):
if tool_component.getValidationState() == 'validated':
module_name = tool_component.getReference()
# In case there are several versions, only load the 'default' one
if module_name not in seen_tool_component_set:
erp5.component.tool.find_load_module(module_name)
seen_tool_component_set.add(module_name)
# self is a FactoryDispatcher.
toolinit = self.toolinit
tl = []
for tool in toolinit.tools:
tl.append(tool.meta_type)
return addInstanceForm(addInstanceForm, self, REQUEST,
factory_action='manage_addTool',
factory_meta_type=toolinit.meta_type,
factory_product_name=toolinit.product_name,
factory_icon=toolinit.icon,
factory_types_list=tl,
factory_need_id=0)
Products.CMFCore.utils.manage_addToolForm = manage_addToolForm
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