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 = (
'registered_version_priority_selection',
'workflow',
'product',
'module_component',
'document',
'interface',
'mixin',
'tool_component',
'property_sheet',
'constraint',
'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 @@
<item>Extension Component</item>
<item>Interface Component</item>
<item>Mixin Component</item>
<item>Module Component</item>
<item>Test Component</item>
<item>Tool Component</item>
</portal_type>
<portal_type id="Contribution Registry Tool">
<item>Contribution Predicate</item>
......
......@@ -47,6 +47,9 @@
<portal_type id="Mixin Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Module Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Property Existence Constraint">
<item>ConstraintType</item>
</portal_type>
......@@ -79,6 +82,9 @@
<portal_type id="Test Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Tool Component">
<item>SortIndex</item>
</portal_type>
<portal_type id="Trash Bin">
<item>Base</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 @@
<type>Mixin Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
<chain>
<type>Module Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
<chain>
<type>Predicate</type>
<workflow>edit_workflow</workflow>
......@@ -175,4 +179,8 @@
<type>Test Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
<chain>
<type>Tool Component</type>
<workflow>component_validation_workflow, dynamic_class_generation_interaction_workflow, edit_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
......@@ -64,11 +64,13 @@
<list>
<string>my_template_role_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_mixin_id_list</string>
<string>my_template_document_id_list</string>
<string>my_template_property_sheet_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_preference_list</string>
<string>my_template_update_tool</string>
......
......@@ -2,31 +2,27 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
<global name="Tool Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>CallableTool</string> </value>
</item>
<item>
<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>
<key> <string>id</string> </key>
<value> <string>document.erp5.CallableTool</string> </value>
<value> <string>tool.erp5.CallableTool</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
<value> <string>Tool Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
......@@ -53,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -87,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -96,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
......@@ -2,31 +2,27 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Document Component" module="erp5.portal_type"/>
<global name="Tool Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>DiffTool</string> </value>
</item>
<item>
<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>
<key> <string>id</string> </key>
<value> <string>document.erp5.DiffTool</string> </value>
<value> <string>tool.erp5.DiffTool</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Document Component</string> </value>
<value> <string>Tool Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
......@@ -53,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -87,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -96,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
......@@ -74,7 +74,9 @@
<string>Extension Component</string>
<string>Interface Component</string>
<string>Mixin Component</string>
<string>Module Component</string>
<string>Test Component</string>
<string>Tool Component</string>
</list>
</value>
</item>
......
......@@ -73,7 +73,9 @@
<string>Extension Component</string>
<string>Interface Component</string>
<string>Mixin Component</string>
<string>Module Component</string>
<string>Test Component</string>
<string>Tool Component</string>
</list>
</value>
</item>
......
......@@ -89,6 +89,7 @@ Interface Component | view
Memcached Plugin | view
Memcached Tool | view
Mixin Component | view
Module Component | view
Predicate | view
Preference Tool Type | jump_property_sheets
Preference Tool Type | view
......@@ -147,6 +148,7 @@ Template Tool | upgrade_from_repository
Template Tool | view
Test Component | run_live_test
Test Component | view
Tool Component | view
Trash Bin | jump_bt5
Trash Bin | view
Trash Folder | view
......
document.erp5.DiffTool
document.erp5.ScriptConstraint
document.erp5.TransformOdtToDocx
document.erp5.TransformOdtToHtml
......@@ -27,5 +26,4 @@ document.erp5.TransformPptxToOdp
document.erp5.TransformPptxToPpty
document.erp5.TransformPptyToPptx
document.erp5.TransformImageToPcx
document.erp5.TransformImageToBmp
document.erp5.CallableTool
\ No newline at end of file
document.erp5.TransformImageToBmp
\ No newline at end of file
......@@ -23,7 +23,9 @@ Component Tool | Document Component
Component Tool | Extension Component
Component Tool | Interface Component
Component Tool | Mixin Component
Component Tool | Module Component
Component Tool | Test Component
Component Tool | Tool Component
Contribution Registry Tool | Contribution Predicate
Domain Tool | Base Domain
Domain | Domain
......
......@@ -53,6 +53,7 @@ Mapped Value
Memcached Plugin
Memcached Tool
Mixin Component
Module Component
Movement
Notification Tool
Order Tool
......@@ -85,6 +86,7 @@ TALES Constraint
Template Tool
Test Component
Test Tool
Tool Component
Trash Bin
Trash Folder
Trash Tool
......
......@@ -14,6 +14,7 @@ Document Component | SortIndex
Extension Component | SortIndex
Interface Component | SortIndex
Mixin Component | SortIndex
Module Component | SortIndex
Property Existence Constraint | ConstraintType
Property Type Validity Constraint | ConstraintType
Python Script | CatalogFilter
......@@ -29,6 +30,7 @@ Simulation Movement | SortIndex
String Attribute Match Constraint | ConstraintType
TALES Constraint | ConstraintType
Test Component | SortIndex
Tool Component | SortIndex
Trash Bin | Base
Trash Bin | SimpleItem
Trash Bin | Task
\ No newline at end of file
......@@ -40,6 +40,9 @@ Memcached Plugin | memcached_plugin_interaction_workflow
Mixin Component | component_validation_workflow
Mixin Component | dynamic_class_generation_interaction_workflow
Mixin Component | edit_workflow
Module Component | component_validation_workflow
Module Component | dynamic_class_generation_interaction_workflow
Module Component | edit_workflow
Predicate | edit_workflow
Preference | edit_workflow
Preference | preference_workflow
......@@ -56,4 +59,7 @@ System Preference | preference_workflow
TALES Constraint | dynamic_class_generation_interaction_workflow
Test Component | component_validation_workflow
Test Component | dynamic_class_generation_interaction_workflow
Test Component | edit_workflow
\ No newline at end of file
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:
"""
sequence_list = SequenceList()
sequence_string = """
SetPreferredWorkingCopyList
CreateProductDocumentAndPortalType
CreateNewBusinessTemplate
UseExportBusinessTemplate
......@@ -8189,6 +8190,30 @@ class _LocalTemplateItemMixin:
sequence_list.addSequenceString(sequence_string)
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):
"""
Simulate migration from filesystem to ZODB
......@@ -8243,6 +8268,7 @@ class _LocalTemplateItemMixin:
"""
sequence_list = SequenceList()
sequence_string = '\
SetPreferredWorkingCopyList \
CreateDocument \
CreateNewBusinessTemplate \
UseExportBusinessTemplate \
......@@ -8313,6 +8339,7 @@ class _LocalTemplateItemMixin:
def test_BusinessTemplateUpgradeDocumentFromFilesystemToZodb(self):
sequence_list = SequenceList()
sequence_string = """
SetPreferredWorkingCopyList
CreateDocument
CreateNewBusinessTemplate
UseExportBusinessTemplate
......
......@@ -27,8 +27,8 @@
#
##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage
......@@ -37,7 +37,7 @@ import zope.interface
import re
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
in INSTANCE_HOME/Document) but this will also be used later on for Documents
......
......@@ -27,15 +27,15 @@
#
##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
import zope.interface
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
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 @@
#
##############################################################################
from Products.ERP5Type.mixin.component import ComponentMixin
from Products.ERP5Type.mixin.text_content_history import TextContentHistoryMixin
from Products.ERP5Type.Core.ModuleComponent import ModuleComponent
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
import zope.interface
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
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):
_bootstrap_business_template_property_tuple = (
'template_catalog_security_uid_column_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):
if not self.has_key('BaseType'):
......
......@@ -257,7 +257,8 @@ class TypesTool(TypeProvider):
Documents) that can be used as Base classes
"""
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')
def getMixinTypeList(self):
......
......@@ -1168,13 +1168,13 @@ def initializeProduct( context,
registerDocumentClass(tool.__module__, tool.__name__)
try:
utils.ToolInit('%s Tool' % product_name,
tools=tools,
tools=set(tools),
icon='tool.png',
).initialize( context )
except TypeError:
# product_name parameter is deprecated in CMF
utils.ToolInit('%s Tool' % product_name,
tools=tools,
tools=set(tools),
product_name=product_name,
icon='tool.png',
).initialize( context )
......
......@@ -318,10 +318,12 @@ class ComponentDynamicPackage(ModuleType):
import erp5.component
erp5.component.ref_manager.add_module(module)
return module
finally:
imp.release_lock()
component._hookAfterLoad(module)
return module
def load_module(self, fullname):
"""
Make sure that loading module is thread-safe using aq_method_lock to make
......@@ -411,3 +413,18 @@ class ComponentDynamicPackage(ModuleType):
del sys.modules[module_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():
holds accessors holders of Portal Types
erp5.component:
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:
holds Document modules previously found in bt5 in $INSTANCE_HOME/Document
erp5.component.interface:
holds Interface modules previously found in Products.NAME.interfaces
erp5.component.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:
holds Extension modules previously found in bt5 in
$INSTANCE_HOME/Extensions
......@@ -221,7 +225,8 @@ def initializeDynamicModules():
# ZODB Components
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
# incompletely
......@@ -234,12 +239,18 @@ def initializeDynamicModules():
erp5.accessor_holder.property_sheet
sys.modules["erp5.component"] = erp5.component
erp5.component.module = ComponentDynamicPackage('erp5.component.module',
'Module Component')
erp5.component.extension = ComponentDynamicPackage('erp5.component.extension',
'Extension Component')
erp5.component.document = ComponentDynamicPackage('erp5.component.document',
'Document Component')
erp5.component.tool = ToolComponentDynamicPackage('erp5.component.tool',
'Tool Component')
erp5.component.interface = ComponentDynamicPackage('erp5.component.interface',
'Interface Component')
......
......@@ -212,8 +212,16 @@ def generatePortalTypeClass(site, portal_type_name):
type_class_namespace = document_class_registry.get(type_class, '')
if not (type_class_namespace.startswith('Products.ERP5Type') or
portal_type_name in core_portal_type_class_dict):
import erp5.component.document
module = erp5.component.document.find_load_module(type_class)
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
module = erp5.component.document.find_load_module(type_class)
if module is not None:
try:
klass = getattr(module, type_class)
......@@ -230,7 +238,14 @@ def generatePortalTypeClass(site, portal_type_name):
% (type_class, portal_type_name))
if klass is None:
klass = _importClass(type_class_path)
try:
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
......
......@@ -36,6 +36,12 @@ class IComponent(Interface):
Extensions or Documents, or any interfaces, mixin and Documents from
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):
"""
Check the consistency of a ZODB Component when validating from draft state
......@@ -68,7 +74,12 @@ class IComponent(Interface):
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
source code is valid
......
......@@ -193,6 +193,9 @@ class ComponentMixin(PropertyRecordableMixin, Base):
_message_text_content_not_set = "No source code"
_message_text_content_error = "Error in Source Code: ${error_message}"
def _hookAfterLoad(self, module_obj):
pass
security.declareProtected(Permissions.AccessContentsInformation,
'getValidationState')
def getValidationState(self):
......@@ -352,7 +355,12 @@ class ComponentMixin(PropertyRecordableMixin, Base):
security.declareProtected(Permissions.ModifyPortalContent,
'importFromFilesystem')
@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
be loaded straightaway provided validate() does not raise any error of
......@@ -368,7 +376,20 @@ class ComponentMixin(PropertyRecordableMixin, Base):
path = inspect.getsourcefile(module_obj)
with open(path) as f:
source_code = f.read()
if filesystem_zodb_module_mapping_set is None:
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
# needed when importing from filesystem, moreover errors may occur
......
......@@ -65,3 +65,37 @@ def _setCacheHeaders(obj, extra_context):
import Products.CMFCore.utils
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