[Checkins] SVN: Products.CMFCore/trunk/Products/CMFCore/ - actions tool export/import: The actions tool export/import mechanism
Jens Vagelpohl
jens at dataflake.org
Sat Oct 4 09:12:40 EDT 2008
Log message for revision 91742:
- actions tool export/import: The actions tool export/import mechanism
is no longer attempting to handle actions stored on tools other than
itself. Other tools are themselves responsible for their actions.
The importer has been fixed to add all action providers to the actions
tool, not just a select list of providers we know about.
(https://bugs.launchpad.net/zope-cmf/+bug/177675)
Changed:
U Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
U Products.CMFCore/trunk/Products/CMFCore/exportimport/actions.py
U Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_actions.py
-=-
Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2008-10-04 11:00:03 UTC (rev 91741)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt 2008-10-04 13:12:38 UTC (rev 91742)
@@ -4,6 +4,13 @@
2.2.0 (unreleased)
------------------
+- actions tool export/import: The actions tool export/import mechanism
+ is no longer attempting to handle actions stored on tools other than
+ itself. Other tools are themselves responsible for their actions.
+ The importer has been fixed to add all action providers to the actions
+ tool, not just a select list of providers we know about.
+ (https://bugs.launchpad.net/zope-cmf/+bug/177675)
+
- tool interfaces: Replace non-existing IMember interface with the
correct IMemberData.
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/actions.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/actions.py 2008-10-04 11:00:03 UTC (rev 91741)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/actions.py 2008-10-04 13:12:38 UTC (rev 91742)
@@ -32,9 +32,7 @@
from Products.CMFCore.interfaces import IActionsTool
from Products.CMFCore.utils import getToolByName
-_SPECIAL_PROVIDERS = ('portal_actions', 'portal_types', 'portal_workflow')
-
class ActionCategoryNodeAdapter(NodeAdapterBase, ObjectManagerHelpers,
PropertyManagerHelpers):
@@ -134,14 +132,22 @@
for provider_id in self.context.listActionProviders():
child = self._doc.createElement('action-provider')
child.setAttribute('name', provider_id)
- # BBB: for CMF 1.6 profiles
- sub = self._extractOldstyleActions(provider_id)
- child.appendChild(sub)
+ # BBB: for CMF 1.6 action settings
+ # We only do this for the portal_actions tool itself. Other
+ # providers are responsible for their own action import/export.
+ if provider_id == 'portal_actions':
+ sub = self._extractOldstyleActions(provider_id)
+ child.appendChild(sub)
+
fragment.appendChild(child)
+
return fragment
def _extractOldstyleActions(self, provider_id):
- # BBB: for CMF 1.6 profiles
+ # BBB: for CMF 1.6 action settings
+ # This method collects "old-style" action information and
+ # formats it for import as "new-style" actions
+
fragment = self._doc.createDocumentFragment()
provider = getToolByName(self.context, provider_id)
@@ -189,15 +195,23 @@
self.context.deleteActionProvider(provider_id)
continue
- if provider_id in _SPECIAL_PROVIDERS and \
- provider_id not in self.context.listActionProviders():
+ if provider_id not in self.context.listActionProviders():
self.context.addActionProvider(provider_id)
- # BBB: for CMF 1.6 profiles
- self._initOldstyleActions(child)
+ # BBB: for CMF 1.6 action setting exports
+ # We only do this for the portal_actions tool itself. Other
+ # providers are responsible for their own action import/export.
+ if provider_id == 'portal_actions':
+ self._initOldstyleActions(child)
def _initOldstyleActions(self, node):
- # BBB: for CMF 1.6 profiles
+ # BBB: for CMF 1.6 action setting exports
+ # This code transparently migrates old export data containing
+ # "old-style" action information to "new-style" actions.
+ # It does this by synthesizing "new-style" export data from the
+ # existing export and then importing that instead of the
+ # "real" export data, which also moves these actions into the
+ # actions tool.
doc = node.ownerDocument
fragment = doc.createDocumentFragment()
for child in node.childNodes:
Modified: Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_actions.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_actions.py 2008-10-04 11:00:03 UTC (rev 91741)
+++ Products.CMFCore/trunk/Products/CMFCore/exportimport/tests/test_actions.py 2008-10-04 13:12:38 UTC (rev 91742)
@@ -90,11 +90,18 @@
</object>
"""
-_NORMAL_EXPORT = """\
+_OLD_EXPORT = """\
<?xml version="1.0"?>
<object name="portal_actions" meta_type="CMF Actions Tool"
xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider name="portal_actions"/>
+ <action-provider name="portal_actions">
+ <action action_id="baz"
+ title="Baz"
+ url_expr="string:${object_url}/baz"
+ condition_expr="python:1"
+ category="dummy"
+ visible="True"/>
+ </action-provider>
<action-provider name="portal_foo">
<action action_id="foo"
title="Foo"
@@ -116,33 +123,41 @@
</object>
"""
+_NORMAL_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_actions" meta_type="CMF Actions Tool"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions">
+ <action action_id="baz"
+ title="Baz"
+ url_expr="string:${object_url}/baz"
+ condition_expr="python:1"
+ category="dummy"
+ visible="True"/>
+ </action-provider>
+ <action-provider name="portal_foo"/>
+ <action-provider name="portal_bar"/>
+</object>
+"""
+
_NEWSYTLE_EXPORT = """\
<?xml version="1.0"?>
<object name="portal_actions" meta_type="CMF Actions Tool"
xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<action-provider name="portal_actions"/>
+ <action-provider name="portal_foo"/>
+ <action-provider name="portal_bar"/>
<object name="dummy" meta_type="CMF Action Category">
<property name="title"></property>
- <object name="foo" meta_type="CMF Action">
- <property name="title">Foo</property>
+ <object name="baz" meta_type="CMF Action">
+ <property name="title">Baz</property>
<property name="description"></property>
- <property name="url_expr">string:${object_url}/foo</property>
+ <property name="url_expr">string:${object_url}/baz</property>
<property name="icon_expr"></property>
<property name="available_expr">python:1</property>
<property name="permissions"></property>
<property name="visible">True</property>
</object>
- <object name="bar" meta_type="CMF Action">
- <property name="title">Bar</property>
- <property name="description"></property>
- <property name="url_expr">string:${object_url}/bar</property>
- <property name="icon_expr"></property>
- <property name="available_expr">python:0</property>
- <property name="permissions">
- <element value="Manage portal"/>
- </property>
- <property name="visible">False</property>
- </object>
</object>
</object>
"""
@@ -181,8 +196,8 @@
<element value="View" /></property>
<property name="visible">True</property>
</object>
- <object name="foo" insert-after="*">
- <property name="icon_expr">string:foo_icon.png</property>
+ <object name="baz" insert-after="*">
+ <property name="icon_expr">string:baz_icon.png</property>
</object>
</object>
</object>
@@ -396,6 +411,15 @@
import exportActionProviders
site = self._initSite()
+ # Set up an old action for added difficulty
+ site.portal_actions.addAction(id='baz',
+ name='Baz',
+ action='baz',
+ condition='python:1',
+ permission=(),
+ category='dummy',
+ visible=1)
+
context = DummyExportContext(site)
exportActionProviders(context)
@@ -488,18 +512,21 @@
self.failUnless('portal_actions' in atool.listActionProviders())
context = DummyImportContext(site)
- context._files['actions.xml'] = _NORMAL_EXPORT
+ context._files['actions.xml'] = _OLD_EXPORT
importActionProviders(context)
- self.assertEqual(len(atool.listActionProviders()), 1)
- self.failIf('portal_foo' in atool.listActionProviders())
+ self.assertEqual(len(atool.listActionProviders()), 3)
+ self.failUnless('portal_bar' in atool.listActionProviders())
+ self.failUnless('portal_foo' in atool.listActionProviders())
self.failUnless('portal_actions' in atool.listActionProviders())
self.assertEqual(len(atool.objectIds()), 1)
self.failUnless('dummy' in atool.objectIds())
- self.assertEqual(len(atool.dummy.objectIds()) , 2)
- self.failUnless('foo' in atool.dummy.objectIds())
- self.failUnless('bar' in atool.dummy.objectIds())
+ # Only one action appears. The importer only deals with actions
+ # defined by the actions tool. Other tools are responsible for
+ # exporting/importing actions themselves.
+ self.assertEqual(len(atool.dummy.objectIds()) , 1)
+ self.failUnless('baz' in atool.dummy.objectIds())
self.failIf(foo.listActions())
self.failIf(bar.listActions())
@@ -552,19 +579,19 @@
context._files['actions.xml'] = _NEWSYTLE_EXPORT
importActionProviders(context)
- self.assertEqual(len(atool.listActionProviders()), 1)
+ self.assertEqual(len(atool.listActionProviders()), 3)
self.assertEqual(atool.objectIds(), ['dummy'])
- self.assertEqual(atool.dummy.objectIds(), ['foo', 'bar'])
- self.assertEqual(atool.dummy.foo.icon_expr, '')
+ self.assertEqual(atool.dummy.objectIds(), ['baz'])
+ self.assertEqual(atool.dummy.baz.icon_expr, '')
context = DummyImportContext(site, False)
context._files['actions.xml'] = _INSERT_IMPORT
importActionProviders(context)
- self.assertEqual(len(atool.listActionProviders()), 1)
+ self.assertEqual(len(atool.listActionProviders()), 3)
self.assertEqual(atool.objectIds(), ['dummy'])
- self.assertEqual(atool.dummy.objectIds(), ['spam', 'bar', 'foo'])
- self.assertEqual(atool.dummy.foo.icon_expr, 'string:foo_icon.png')
+ self.assertEqual(atool.dummy.objectIds(), ['spam', 'baz'])
+ self.assertEqual(atool.dummy.baz.icon_expr, 'string:baz_icon.png')
def test_remove_skip_purge(self):
from Products.CMFCore.exportimport.actions \
More information about the Checkins
mailing list