[CMF-checkins] SVN: CMF/trunk/C - converted ActionsTool setup handlers to new style

Yvo Schubbe y.2005- at wcm-solutions.de
Sun Oct 9 15:59:31 EDT 2005


Log message for revision 39025:
  - converted ActionsTool setup handlers to new style
  - presettings for new Actions can now be loaded from Action settings in setup profiles
  - updated CMFDefault default profile

Changed:
  U   CMF/trunk/CHANGES.txt
  U   CMF/trunk/CMFCore/ActionInformation.py
  U   CMF/trunk/CMFCore/configure.zcml
  U   CMF/trunk/CMFCore/nodeadapters.py
  U   CMF/trunk/CMFCore/tests/test_nodeadapters.py
  U   CMF/trunk/CMFCore/www/addAction.zpt
  U   CMF/trunk/CMFDefault/profiles/default/actions.xml
  U   CMF/trunk/CMFSetup/actions.py
  U   CMF/trunk/CMFSetup/tests/test_actions.py
  D   CMF/trunk/CMFSetup/xml/apcExport.xml

-=-
Modified: CMF/trunk/CHANGES.txt
===================================================================
--- CMF/trunk/CHANGES.txt	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CHANGES.txt	2005-10-09 19:59:31 UTC (rev 39025)
@@ -2,6 +2,9 @@
 
   New Features
 
+    - ActionsTool: Improved add form for 'CMF Action' objects.
+      Presettings can now be loaded from Action settings in setup profiles.
+
     - CMFSetup and GenericSetup: Added catalog tool setup handlers.
       This includes node adapters for PluginIndexes, ZCTextIndex and ZCatalog.
       Support for additional indexes can be added by providing INodeExporter

Modified: CMF/trunk/CMFCore/ActionInformation.py
===================================================================
--- CMF/trunk/CMFCore/ActionInformation.py	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFCore/ActionInformation.py	2005-10-09 19:59:31 UTC (rev 39025)
@@ -16,6 +16,7 @@
 """
 
 from UserDict import UserDict
+from xml.dom.minidom import parseString
 
 from AccessControl import ClassSecurityInfo
 from Acquisition import aq_base, aq_inner, aq_parent
@@ -27,6 +28,8 @@
 from zope.i18nmessageid import MessageID
 from zope.interface import implements
 
+from Products.GenericSetup.interfaces import INodeImporter
+
 from Expression import Expression
 from interfaces import IAction
 from interfaces import IActionCategory
@@ -168,12 +171,80 @@
 
 InitializeClass(Action)
 
-manage_addActionForm = PageTemplateFile( 'addAction.zpt', _wwwdir)
 
-def manage_addAction(self, id, REQUEST=None):
+def manage_addActionForm(self):
+    """Form for adding a new CMF Action object.
+    """
+    profiles = []
+
+    stool = getToolByName(self, 'portal_setup', None)
+    if stool:
+        for info in stool.listContextInfos():
+            action_paths = []
+            context = stool._getImportContext(info['id'])
+            body = context.readDataFile('actions.xml')
+            if body is None:
+                continue
+            root = parseString(body).documentElement
+            for node in root.childNodes:
+                if node.nodeName != 'object':
+                    continue
+                action_paths += _extractChildren(node)
+            action_paths.sort()
+            profiles.append({'id': info['id'],
+                             'title': info['title'],
+                             'action_paths': tuple(action_paths)})
+
+    template = PageTemplateFile('addAction.zpt', _wwwdir).__of__(self)
+    return template(profiles=tuple(profiles))
+
+def _extractChildren(node):
+    action_paths = []
+    category_id = node.getAttribute('name')
+    for child in node.childNodes:
+        if child.nodeName != 'object':
+            continue
+        if child.getAttribute('meta_type') == Action.meta_type:
+            action_id = child.getAttribute('name')
+            action_paths.append(action_id)
+        else:
+            action_paths += _extractChildren(child)
+    return [ ('%s/%s' % (category_id, path)) for path in action_paths ]
+
+def manage_addAction(self, id, settings_id='', REQUEST=None):
     """Add a new CMF Action object with ID *id*.
     """
+    settings_node = None
+    if settings_id:
+        stool = getToolByName(self, 'portal_setup', None)
+        if stool:
+            path = settings_id.split('/')
+            context = stool._getImportContext(path.pop(0))
+            body = context.readDataFile('actions.xml')
+            if body is not None:
+                root = parseString(body).documentElement
+                for node in root.childNodes:
+                    if node.nodeName != 'object':
+                        continue
+                    for obj_id in path:
+                        for child in node.childNodes:
+                            if child.nodeName != 'object':
+                                continue
+                            if child.getAttribute('name') != obj_id:
+                                continue
+                            if child.getAttribute(
+                                             'meta_type') == Action.meta_type:
+                                settings_node = child
+                            else:
+                                node = child
+                            break
+                    if settings_node:
+                        if not id:
+                            id = obj_id
+                        break
     obj = Action(id)
+    if settings_node:
+        INodeImporter(obj).importNode(settings_node)
     self._setObject(id, obj)
 
     if REQUEST:

Modified: CMF/trunk/CMFCore/configure.zcml
===================================================================
--- CMF/trunk/CMFCore/configure.zcml	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFCore/configure.zcml	2005-10-09 19:59:31 UTC (rev 39025)
@@ -10,6 +10,42 @@
     />
 
   <adapter
+      factory=".nodeadapters.ActionCategoryNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeExporter"
+      for=".interfaces.IActionCategory"
+      />
+
+  <adapter
+      factory=".nodeadapters.ActionCategoryNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeImporter"
+      for=".interfaces.IActionCategory"
+      />
+
+  <adapter
+      factory=".nodeadapters.ActionNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeExporter"
+      for=".interfaces.IAction"
+      />
+
+  <adapter
+      factory=".nodeadapters.ActionNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeImporter"
+      for=".interfaces.IAction"
+      />
+
+  <adapter
+      factory=".nodeadapters.ActionsToolNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeExporter"
+      for=".interfaces.IActionsTool"
+      />
+
+  <adapter
+      factory=".nodeadapters.ActionsToolNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeImporter"
+      for=".interfaces.IActionsTool"
+      />
+
+  <adapter
       factory=".nodeadapters.CookieCrumblerNodeAdapter"
       provides="Products.GenericSetup.interfaces.INodeExporter"
       for=".interfaces.ICookieCrumbler"

Modified: CMF/trunk/CMFCore/nodeadapters.py
===================================================================
--- CMF/trunk/CMFCore/nodeadapters.py	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFCore/nodeadapters.py	2005-10-09 19:59:31 UTC (rev 39025)
@@ -15,13 +15,210 @@
 $Id$
 """
 
-from Products.GenericSetup.interfaces import PURGE
+from Products.GenericSetup.interfaces import PURGE, UPDATE
+from Products.GenericSetup.utils import I18NURI
 from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import ObjectManagerHelpers
 from Products.GenericSetup.utils import PropertyManagerHelpers
 
+from interfaces import IAction
+from interfaces import IActionCategory
+from interfaces import IActionsTool
 from interfaces import ICookieCrumbler
+from interfaces.portal_actions import ActionProvider as IActionProvider
+from utils import getToolByName
 
+_SPECIAL_PROVIDERS = ('portal_actions', 'portal_types', 'portal_workflow')
 
+
+class ActionCategoryNodeAdapter(NodeAdapterBase, ObjectManagerHelpers,
+                                PropertyManagerHelpers):
+
+    """Node im- and exporter for ActionCategory.
+    """
+
+    __used_for__ = IActionCategory
+
+    def exportNode(self, doc):
+        """Export the object as a DOM node.
+        """
+        self._doc = doc
+        node = self._getObjectNode('object')
+        node.appendChild(self._extractProperties())
+        node.appendChild(self._extractObjects())
+        return node
+
+    def importNode(self, node, mode=PURGE):
+        """Import the object from the DOM node.
+        """
+        if mode == PURGE:
+            self._purgeProperties()
+            self._purgeObjects()
+
+        self._initProperties(node, mode)
+        self._initObjects(node, mode)
+
+
+class ActionNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
+
+    """Node im- and exporter for Action.
+    """
+
+    __used_for__ = IAction
+
+    def exportNode(self, doc):
+        """Export the object as a DOM node.
+        """
+        self._doc = doc
+        node = self._getObjectNode('object')
+        node.appendChild(self._extractProperties())
+        return node
+
+    def importNode(self, node, mode=PURGE):
+        """Import the object from the DOM node.
+        """
+        self._initProperties(node, mode)
+
+
+class ActionsToolNodeAdapter(NodeAdapterBase, ObjectManagerHelpers):
+
+    """Node im- and exporter for ActionsTool.
+    """
+
+    __used_for__ = IActionsTool
+
+    def exportNode(self, doc):
+        """Export the object as a DOM node.
+        """
+        self._doc = doc
+        node = self._getObjectNode('object')
+        node.setAttribute('xmlns:i18n', I18NURI)
+        node.appendChild(self._extractProviders())
+        node.appendChild(self._extractObjects())
+        return node
+
+    def importNode(self, node, mode=PURGE):
+        """Import the object from the DOM node.
+        """
+        if mode == PURGE:
+            self._purgeProviders()
+            self._purgeObjects()
+
+        self._initObjects(node, mode)
+        self._initProviders(node, mode)
+
+    def _extractProviders(self):
+        fragment = self._doc.createDocumentFragment()
+        for provider_id in self.context.listActionProviders():
+            child = self._doc.createElement('action-provider')
+            child.setAttribute('name', provider_id)
+            # BBB: for CMF 1.5 profiles
+            sub = self._extractOldstyleActions(provider_id)
+            child.appendChild(sub)
+            fragment.appendChild(child)
+        return fragment
+
+    def _extractOldstyleActions(self, provider_id):
+        # BBB: for CMF 1.5 profiles
+        fragment = self._doc.createDocumentFragment()
+
+        provider = getToolByName(self.context, provider_id)
+        if not IActionProvider.isImplementedBy(provider):
+            return fragment
+
+        if provider_id == 'portal_actions':
+            actions = provider._actions
+        else:
+            actions = provider.listActions()
+
+        if actions and isinstance(actions[0], dict):
+            return fragment
+
+        for ai in actions:
+            mapping = ai.getMapping()
+            child = self._doc.createElement('action')
+            child.setAttribute('action_id', mapping['id'])
+            child.setAttribute('category', mapping['category'])
+            child.setAttribute('condition_expr', mapping['condition'])
+            child.setAttribute('title', mapping['title'])
+            child.setAttribute('url_expr', mapping['action'])
+            child.setAttribute('visible', str(mapping['visible']))
+            for permission in mapping['permissions']:
+                sub = self._doc.createElement('permission')
+                sub.appendChild(self._doc.createTextNode(permission))
+                child.appendChild(sub)
+            fragment.appendChild(child)
+        return fragment
+
+    def _purgeProviders(self):
+        for provider_id in self.context.listActionProviders():
+            self.context.deleteActionProvider(provider_id)
+
+    def _initProviders(self, node, mode):
+        for child in node.childNodes:
+            if child.nodeName != 'action-provider':
+                continue
+
+            provider_id = str(child.getAttribute('name'))
+            if not provider_id:
+                # BBB: for CMF 1.5 profiles
+                provider_id = str(child.getAttribute('id'))
+            if child.hasAttribute('remove'):
+                if provider_id in self.context.listActionProviders():
+                    self.context.deleteActionProvider(provider_id)
+                continue
+
+            if provider_id in _SPECIAL_PROVIDERS and \
+                    provider_id not in self.context.listActionProviders():
+                self.context.addActionProvider(provider_id)
+
+            # BBB: for CMF 1.5 profiles
+            self._initOldstyleActions(child, mode)
+
+    def _initOldstyleActions(self, node, mode):
+        # BBB: for CMF 1.5 profiles
+        doc = node.ownerDocument
+        fragment = doc.createDocumentFragment()
+        for child in node.childNodes:
+            if child.nodeName != 'action':
+                continue
+
+            parent = fragment
+            for category_id in child.getAttribute('category').split('/'):
+                newnode = doc.createElement('object')
+                newnode.setAttribute('name', str(category_id))
+                newnode.setAttribute('meta_type', 'CMF Action Category')
+                parent.appendChild(newnode)
+                parent = newnode
+            newnode = doc.createElement('object')
+            newnode.setAttribute('name', str(child.getAttribute('action_id')))
+            newnode.setAttribute('meta_type', 'CMF Action')
+
+            mapping = {'title': 'title',
+                       'url_expr': 'url_expr',
+                       'condition_expr': 'available_expr',
+                       'visible': 'visible'}
+            for old, new in mapping.iteritems():
+                newchild = doc.createElement('property')
+                newchild.setAttribute('name', new)
+                newsub = doc.createTextNode(child.getAttribute(old))
+                newchild.appendChild(newsub)
+                newnode.appendChild(newchild)
+
+            newchild = doc.createElement('property')
+            newchild.setAttribute('name', 'permissions')
+            for sub in child.childNodes:
+                if sub.nodeName == 'permission':
+                    newsub = doc.createElement('element')
+                    newsub.setAttribute('value', self._getNodeText(sub))
+                    newchild.appendChild(newsub)
+            newnode.appendChild(newchild)
+
+            parent.appendChild(newnode)
+
+        self._initObjects(fragment, UPDATE)
+
+
 class CookieCrumblerNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
 
     """Node im- and exporter for CookieCrumbler.

Modified: CMF/trunk/CMFCore/tests/test_nodeadapters.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_nodeadapters.py	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFCore/tests/test_nodeadapters.py	2005-10-09 19:59:31 UTC (rev 39025)
@@ -17,13 +17,63 @@
 
 import unittest
 import Testing
+import Zope2
+Zope2.startup()
 
 import Products
 from Products.Five import zcml
-from Products.GenericSetup.testing import NodeAdapterTestCase
 from zope.app.tests.placelesssetup import PlacelessSetup
 
+from Products.CMFCore.tests.base.dummy import DummySite
+from Products.GenericSetup.testing import NodeAdapterTestCase
 
+
+_ACTION_XML = """\
+<object name="foo_action" meta_type="CMF Action">
+ <property name="title">Foo</property>
+ <property name="description"></property>
+ <property name="url_expr">string:${object_url}/foo</property>
+ <property name="icon_expr"></property>
+ <property name="available_expr">python:1</property>
+ <property name="permissions"/>
+ <property name="visible">True</property>
+</object>
+"""
+
+_ACTIONCATEGORY_XML = """\
+<object name="foo_category" meta_type="CMF Action Category">
+ <property name="title"></property>
+ <object name="foo_action" meta_type="CMF Action">
+  <property name="title"></property>
+  <property name="description"></property>
+  <property name="url_expr"></property>
+  <property name="icon_expr"></property>
+  <property name="available_expr"></property>
+  <property name="permissions"/>
+  <property name="visible">True</property>
+ </object>
+</object>
+"""
+
+_ACTIONSTOOL_XML = """\
+<object name="portal_actions" meta_type="CMF Actions Tool"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+ <object name="foo_category" meta_type="CMF Action Category">
+  <property name="title"></property>
+  <object name="foo_action" meta_type="CMF Action" i18n:domain="foo_domain">
+   <property name="title" i18n:translate=""></property>
+   <property name="description" i18n:translate=""></property>
+   <property name="url_expr"></property>
+   <property name="icon_expr"></property>
+   <property name="available_expr"></property>
+   <property name="permissions"/>
+   <property name="visible">True</property>
+  </object>
+ </object>
+</object>
+"""
+
 _COOKIECRUMBLER_XML = """\
 <object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
  <property name="auth_cookie">__ac</property>
@@ -40,6 +90,81 @@
 """
 
 
+class ActionNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.CMFCore.nodeadapters import ActionNodeAdapter
+
+        return ActionNodeAdapter
+
+    def _populate(self, obj):
+        obj._setPropValue('title', 'Foo')
+        obj._setPropValue('url_expr', 'string:${object_url}/foo')
+        obj._setPropValue('available_expr', 'python:1')
+
+    def setUp(self):
+        from Products.CMFCore.ActionInformation import Action
+
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        self._obj = Action('foo_action')
+        self._XML = _ACTION_XML
+
+
+class ActionCategoryNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.CMFCore.nodeadapters import ActionCategoryNodeAdapter
+
+        return ActionCategoryNodeAdapter
+
+    def _populate(self, obj):
+        from Products.CMFCore.ActionInformation import Action
+
+        obj._setObject('foo_action', Action('foo_action'))
+
+    def setUp(self):
+        from Products.CMFCore.ActionInformation import ActionCategory
+
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        self._obj = ActionCategory('foo_category')
+        self._XML = _ACTIONCATEGORY_XML
+
+
+class ActionsToolNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.CMFCore.nodeadapters import ActionsToolNodeAdapter
+
+        return ActionsToolNodeAdapter
+
+    def _populate(self, obj):
+        from Products.CMFCore.ActionInformation import Action
+        from Products.CMFCore.ActionInformation import ActionCategory
+
+        obj._setObject('foo_category', ActionCategory('foo_category'))
+        obj.action_providers = ('portal_actions',)
+        obj.foo_category._setObject('foo_action', Action('foo_action'))
+        obj.foo_category.foo_action.i18n_domain = 'foo_domain'
+
+    def setUp(self):
+        from Products.CMFCore.ActionsTool import ActionsTool
+
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        site = DummySite('site')
+        site._setObject('portal_actions', ActionsTool('portal_actions'))
+        self._obj = site.portal_actions
+        self._XML = _ACTIONSTOOL_XML
+
+
 class CookieCrumblerNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
 
     def _getTargetClass(self):
@@ -60,6 +185,9 @@
 
 def test_suite():
     return unittest.TestSuite((
+        unittest.makeSuite(ActionNodeAdapterTests),
+        unittest.makeSuite(ActionCategoryNodeAdapterTests),
+        unittest.makeSuite(ActionsToolNodeAdapterTests),
         unittest.makeSuite(CookieCrumblerNodeAdapterTests),
         ))
 

Modified: CMF/trunk/CMFCore/www/addAction.zpt
===================================================================
--- CMF/trunk/CMFCore/www/addAction.zpt	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFCore/www/addAction.zpt	2005-10-09 19:59:31 UTC (rev 39025)
@@ -16,6 +16,23 @@
  </tr>
  <tr>
   <td>
+   <div class="form-label">Presettings</div>
+  </td>
+  <td>
+   <select name="settings_id">
+    <option value="" selected="selected">(None)</option>
+    <optgroup label="PROFILE_TITLE"
+       tal:repeat="profile options/profiles"
+       tal:attributes="label profile/title">
+     <option value="SETTINGS_ID"
+             tal:repeat="action_path profile/action_paths"
+             tal:attributes="value string:${profile/id}/${action_path}"
+             tal:content="action_path">ACTION PATH</option></optgroup>
+   </select>
+  </td>
+ </tr>
+ <tr>
+  <td>
    &nbsp;
   </td>
   <td>

Modified: CMF/trunk/CMFDefault/profiles/default/actions.xml
===================================================================
--- CMF/trunk/CMFDefault/profiles/default/actions.xml	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFDefault/profiles/default/actions.xml	2005-10-09 19:59:31 UTC (rev 39025)
@@ -1,186 +1,207 @@
 <?xml version="1.0"?>
-<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider id="portal_types">
- </action-provider>
- <action-provider id="portal_workflow">
- </action-provider>
- <action-provider id="portal_actions">
- </action-provider>
+<object name="portal_actions" meta_type="CMF Actions Tool"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_types"/>
+ <action-provider name="portal_workflow"/>
+ <action-provider name="portal_actions"/>
  <object name="user" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="login" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Login</property>
-  <property name="description" i18n:translate="">Click here to Login</property>
-  <property name="url_expr">string:${portal_url}/login_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">not: member</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
+  <object name="login" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Login</property>
+   <property name="description"
+      i18n:translate="">Click here to Login</property>
+   <property name="url_expr">string:${portal_url}/login_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">not: member</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="join" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Join</property>
+   <property name="description"
+      i18n:translate="">Click here to Join</property>
+   <property name="url_expr">string:${portal_url}/join_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">not: member</property>
+   <property name="permissions">
+    <element value="Add portal member"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="preferences" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Preferences</property>
+   <property name="description"
+      i18n:translate="">Change your user preferences</property>
+   <property name="url_expr">string:${portal_url}/personalize_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">member</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="logout" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Log out</property>
+   <property name="description"
+      i18n:translate="">Click here to logout</property>
+   <property name="url_expr">string:${portal_url}/logout</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">member</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="addFavorite" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Add to favorites</property>
+   <property name="description"
+      i18n:translate="">Add this item to your favorites</property>
+   <property name="url_expr">string:${object_url}/addtoFavorites</property>
+   <property name="icon_expr"></property>
+   <property
+      name="available_expr">portal/portal_membership/getHomeFolder</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="mystuff" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">My stuff</property>
+   <property name="description"
+      i18n:translate="">Goto your home folder</property>
+   <property
+      name="url_expr">string:${portal/portal_membership/getHomeUrl}/folder_contents</property>
+   <property name="icon_expr"></property>
+   <property
+      name="available_expr">python: member and portal.portal_membership.getHomeFolder()</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="favorites" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">My favorites</property>
+   <property name="description"
+      i18n:translate="">Browse your favorites</property>
+   <property
+      name="url_expr">string:${portal/portal_membership/getHomeUrl}/Favorites/folder_contents</property>
+   <property name="icon_expr"></property>
+   <property
+      name="available_expr">python: member and hasattr(portal.portal_membership.getHomeFolder(), "Favorites")</property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="logged_in" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Logged in</property>
+   <property name="description" i18n:translate="">Used by scripts</property>
+   <property name="url_expr">string:${portal_url}/logged_in</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr"></property>
+   <property name="permissions">
+    <element value="View"/>
+   </property>
+   <property name="visible">False</property>
+  </object>
  </object>
- <object name="join" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Join</property>
-  <property name="description" i18n:translate="">Click here to Join</property>
-  <property name="url_expr">string:${portal_url}/join_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">not: member</property>
-  <property name="permissions">
-   <element value="Add portal member" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="preferences" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Preferences</property>
-  <property name="description" i18n:translate="">Change your user preferences</property>
-  <property name="url_expr">string:${portal_url}/personalize_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">member</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="logout" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Log out</property>
-  <property name="description" i18n:translate="">Click here to logout</property>
-  <property name="url_expr">string:${portal_url}/logout</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">member</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="addFavorite" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Add to favorites</property>
-  <property name="description" i18n:translate="">Add this item to your favorites</property>
-  <property name="url_expr">string:${object_url}/addtoFavorites</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">portal/portal_membership/getHomeFolder</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="mystuff" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">My stuff</property>
-  <property name="description" i18n:translate="">Goto your home folder</property>
-  <property name="url_expr">string:${portal/portal_membership/getHomeUrl}/folder_contents</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python: member and portal.portal_membership.getHomeFolder()</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="favorites" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">My favorites</property>
-  <property name="description" i18n:translate="">Browse your favorites</property>
-  <property name="url_expr">string:${portal/portal_membership/getHomeUrl}/Favorites/folder_contents</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python: member and hasattr(portal.portal_membership.getHomeFolder(), "Favorites")</property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="logged_in" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Logged in</property>
-  <property name="description" i18n:translate="">Used by scripts</property>
-  <property name="url_expr">string:${portal_url}/logged_in</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr"></property>
-  <property name="permissions">
-   <element value="View" /></property>
-  <property name="visible">False</property>
- </object>
- </object>
  <object name="object" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="reply" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Reply</property>
-  <property name="description" i18n:translate=""></property>
-  <property name="url_expr">string:${object_url}/discussion_reply_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python: object is not None and portal.portal_discussion.isDiscussionAllowedFor(object)</property>
-  <property name="permissions">
-   <element value="Reply to item" /></property>
-  <property name="visible">True</property>
+  <object name="reply" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Reply</property>
+   <property name="description" i18n:translate=""></property>
+   <property
+      name="url_expr">string:${object_url}/discussion_reply_form</property>
+   <property name="icon_expr"></property>
+   <property
+      name="available_expr">python: object is not None and portal.portal_discussion.isDiscussionAllowedFor(object)</property>
+   <property name="permissions">
+    <element value="Reply to item"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="syndication" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Syndication</property>
+   <property name="description" i18n:translate=""></property>
+   <property name="url_expr">string:${folder_url}/synPropertiesForm</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">python: folder is object</property>
+   <property name="permissions">
+    <element value="Manage properties"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
  </object>
- <object name="syndication" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Syndication</property>
-  <property name="description" i18n:translate=""></property>
-  <property name="url_expr">string:${folder_url}/synPropertiesForm</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python: folder is object</property>
-  <property name="permissions">
-   <element value="Manage properties" /></property>
-  <property name="visible">True</property>
- </object>
- </object>
  <object name="folder" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="folderContents" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Folder contents</property>
-  <property name="description" i18n:translate=""></property>
-  <property name="url_expr">string:${folder_url}/folder_contents</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python: folder is not object</property>
-  <property name="permissions">
-   <element value="List folder contents" /></property>
-  <property name="visible">True</property>
+  <object name="folderContents" meta_type="CMF Action"
+     i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Folder contents</property>
+   <property name="description" i18n:translate=""></property>
+   <property name="url_expr">string:${folder_url}/folder_contents</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">python: folder is not object</property>
+   <property name="permissions">
+    <element value="List folder contents"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
  </object>
- </object>
  <object name="global" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="manage_members" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Manage members</property>
-  <property name="description" i18n:translate="">Manage portal members</property>
-  <property name="url_expr">string:${portal_url}/members_manage_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr"></property>
-  <property name="permissions">
-   <element value="Manage users" /></property>
-  <property name="visible">True</property>
+  <object name="manage_members" meta_type="CMF Action"
+     i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Manage members</property>
+   <property name="description"
+      i18n:translate="">Manage portal members</property>
+   <property
+      name="url_expr">string:${portal_url}/members_manage_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr"></property>
+   <property name="permissions">
+    <element value="Manage users"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="members_delete" meta_type="CMF Action"
+     i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Delete members</property>
+   <property name="description"
+      i18n:translate="">Delete portal members</property>
+   <property
+      name="url_expr">string:${portal_url}/members_delete_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr"></property>
+   <property name="permissions">
+    <element value="Manage users"/>
+   </property>
+   <property name="visible">False</property>
+  </object>
+  <object name="undo" meta_type="CMF Action" i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Undo</property>
+   <property name="description" i18n:translate=""></property>
+   <property name="url_expr">string:${portal_url}/undo_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">member</property>
+   <property name="permissions">
+    <element value="List undoable changes"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
+  <object name="configPortal" meta_type="CMF Action"
+     i18n:domain="cmf_default">
+   <property name="title" i18n:translate="">Reconfigure Portal</property>
+   <property name="description"
+      i18n:translate="">Reconfigure the portal</property>
+   <property name="url_expr">string:${portal_url}/reconfig_form</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr"></property>
+   <property name="permissions">
+    <element value="Manage portal"/>
+   </property>
+   <property name="visible">True</property>
+  </object>
  </object>
- <object name="members_delete" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Delete members</property>
-  <property name="description" i18n:translate="">Delete portal members</property>
-  <property name="url_expr">string:${portal_url}/members_delete_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr"></property>
-  <property name="permissions">
-   <element value="Manage users" /></property>
-  <property name="visible">False</property>
- </object>
- <object name="undo" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Undo</property>
-  <property name="description" i18n:translate=""></property>
-  <property name="url_expr">string:${portal_url}/undo_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">member</property>
-  <property name="permissions">
-   <element value="List undoable changes" /></property>
-  <property name="visible">True</property>
- </object>
- <object name="configPortal" meta_type="CMF Action"
-         i18n:domain="cmf_default">
-  <property name="title" i18n:translate="">Reconfigure Portal</property>
-  <property name="description" i18n:translate="">Reconfigure the portal</property>
-  <property name="url_expr">string:${portal_url}/reconfig_form</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr"></property>
-  <property name="permissions">
-   <element value="Manage portal" /></property>
-  <property name="visible">True</property>
- </object>
- </object>
-</actions-tool>
+</object>

Modified: CMF/trunk/CMFSetup/actions.py
===================================================================
--- CMF/trunk/CMFSetup/actions.py	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFSetup/actions.py	2005-10-09 19:59:31 UTC (rev 39025)
@@ -10,240 +10,54 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" Classes:  ActionsProviderConfigurator
+"""Actions tool setup handlers.
 
 $Id$
 """
 
-from AccessControl import ClassSecurityInfo
-from Globals import InitializeClass
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from xml.dom.minidom import parseString
 
-from Products.CMFCore.interfaces import IActionProvider
-from Products.CMFCore.interfaces.portal_actions \
-        import ActionProvider as z2IActionProvider
 from Products.CMFCore.utils import getToolByName
+from Products.GenericSetup.interfaces import INodeExporter
+from Products.GenericSetup.interfaces import INodeImporter
+from Products.GenericSetup.interfaces import PURGE, UPDATE
+from Products.GenericSetup.utils import PrettyDocument
 
-from permissions import ManagePortal
-from utils import _xmldir
-from utils import ConfiguratorBase
-from utils import CONVERTER, DEFAULT, KEY
-
-
-#
-#   Configurator entry points
-#
 _FILENAME = 'actions.xml'
-_SPECIAL_PROVIDERS = ('portal_actions', 'portal_types', 'portal_workflow')
 
-def importActionProviders( context ):
 
-    """ Import action providers and their actions from an XML file.
-
-    o 'context' must implement IImportContext.
-
-    o Register via Python:
-
-      registry = site.portal_setup.getImportStepRegistry()
-      registry.registerStep( 'importActionProviders'
-                           , '20040518-01'
-                           , Products.CMFSetup.actions.importActionProviders
-                           , ()
-                           , 'Action Provider import'
-                           , 'Import  action providers registered with '
-                             'the actions tool, and their actions.'
-                           )
-
-    o Register via XML:
-
-      <setup-step id="importActionProviders"
-                  version="20040524-01"
-                  handler="Products.CMFSetup.actions.importActionProviders"
-                  title="Action Provider import"
-      >Import action providers registered with the actions tool,
-       and their actions.</setup-step>
-
+def importActionProviders(context):
+    """ Import actions tool.
     """
     site = context.getSite()
-    encoding = context.getEncoding()
+    mode = context.shouldPurge() and PURGE or UPDATE
+    atool = getToolByName(site, 'portal_actions')
 
-    actions_tool = getToolByName( site, 'portal_actions' )
+    body = context.readDataFile(_FILENAME)
+    if body is None:
+        return 'Actions tool: Nothing to import.'
 
-    if context.shouldPurge():
+    importer = INodeImporter(atool, None)
+    if importer is None:
+        return 'Actions tool: Import adapter misssing.'
 
-        for provider_id in actions_tool.listActionProviders():
-            actions_tool.deleteActionProvider( provider_id )
+    importer.importNode(parseString(body).documentElement, mode=mode)
+    return 'Actions tool imported.'
 
-        for obj_id in actions_tool.objectIds():
-            actions_tool._delObject(obj_id)
-
-    xml = context.readDataFile(_FILENAME)
-    if xml is None:
-        return 'Action providers: Nothing to import.'
-
-    apc = ActionProvidersConfigurator(site, encoding)
-    tool_info = apc.parseXML(xml)
-
-    for p_info in tool_info['providers']:
-
-        if 'remove' in p_info:
-            if p_info['id'] in actions_tool.listActionProviders():
-                actions_tool.deleteActionProvider(p_info['id'])
-            continue
-
-        if p_info['id'] in _SPECIAL_PROVIDERS and \
-                p_info['id'] not in actions_tool.listActionProviders():
-            actions_tool.addActionProvider(p_info['id'])
-
-        provider = getToolByName(site, p_info['id'])
-        provider._actions = ()
-
-        for a_info in p_info['actions']:
-            parent = actions_tool
-            for category_id in a_info['category'].split('/'):
-                if category_id not in parent.objectIds():
-                    o_info = {'id': str(category_id),
-                              'meta_type': 'CMF Action Category',
-                              'properties':(),
-                              'objects': ()}
-                    apc.initObject(parent, o_info)
-                parent = parent._getOb(category_id)
-            if a_info['id'] not in parent.objectIds():
-                o_info = {'id': str(a_info['id']),
-                          'meta_type': 'CMF Action',
-                          'properties':
-                             ( {'id': 'title',
-                                'value': a_info.get('title', ''),
-                                'elements': ()}
-                             , {'id': 'description',
-                                'value': a_info.get('description', ''),
-                                'elements': ()}
-                             , {'id': 'url_expr',
-                                'value': a_info.get('action', ''),
-                                'elements': ()}
-                             , {'id': 'available_expr',
-                                'value': a_info.get('condition', ''),
-                                'elements': ()}
-                             , {'id': 'permissions',
-                                'value': '',
-                                'elements': a_info['permissions']}
-                             , {'id': 'visible',
-                                'value': a_info.get('visible', True),
-                                'elements': ()}
-                             ),
-                          'objects': ()}
-                apc.initObject(parent, o_info)
-
-    for sub_info in tool_info['objects']:
-        apc.initObject(actions_tool, sub_info)
-
-    return 'Action providers imported.'
-
-def exportActionProviders( context ):
-
-    """ Export action providers and their actions as an XML file
-
-    o 'context' must implement IExportContext.
-
-    o Register via Python:
-
-      registry = site.portal_setup.getExportStepRegistry()
-      registry.registerStep( 'exportActionProviders'
-                           , Products.CMFSetup.actions.exportActionProviders
-                           , 'Action Provider export'
-                           , 'Export action providers registered with '
-                             'the actions tool, and their actions.'
-                           )
-
-    o Register via XML:
-
-      <export-script id="exportActionProviders"
-                     version="20040518-01"
-                     handler="Products.CMFSetup.actions.exportActionProviders"
-                     title="Action Provider export"
-      >Export action providers registered with the actions tool,
-       and their actions.</export-script>
-
+def exportActionProviders(context):
+    """ Export actions tool.
     """
     site = context.getSite()
-    apc = ActionProvidersConfigurator( site ).__of__( site )
-    text = apc.generateXML()
 
-    context.writeDataFile( _FILENAME, text, 'text/xml' )
+    atool = getToolByName(site, 'portal_actions', None)
+    if atool is None:
+        return 'Actions tool: Nothing to export.'
 
-    return 'Action providers exported.'
+    exporter = INodeExporter(atool)
+    if exporter is None:
+        return 'Actions tool: Export adapter misssing.'
 
-
-class ActionProvidersConfigurator(ConfiguratorBase):
-
-    """ Synthesize XML description of site's action providers.
-    """
-
-    security = ClassSecurityInfo()
-
-    security.declareProtected( ManagePortal, 'listProviderInfo' )
-    def listProviderInfo( self ):
-
-        """ Return a sequence of mappings for each action provider.
-        """
-        actions_tool = getToolByName( self._site, 'portal_actions' )
-        result = []
-
-        for provider_id in actions_tool.listActionProviders():
-
-            provider_info = { 'id' : provider_id, 'actions' : [] }
-            result.append( provider_info )
-
-            provider = getToolByName( self._site, provider_id )
-
-            if not IActionProvider.providedBy(provider) and \
-                    not z2IActionProvider.isImplementedBy(provider):
-                continue
-
-            if provider_id == 'portal_actions':
-                actions = provider._actions
-            else:
-                actions = provider.listActions()
-
-            if actions and isinstance(actions[0], dict):
-                continue
-
-            provider_info['actions'] = [ ai.getMapping() for ai in actions ]
-
-        return result
-
-    security.declareProtected(ManagePortal, 'listSubobjectInfos')
-    def listSubobjectInfos(self):
-        """ List info mappings for the objects stored inside the tool.
-        """
-        atool = getToolByName(self._site, 'portal_actions')
-        return [ self._extractObject(obj) for obj in atool.objectValues() ]
-
-    def _getExportTemplate(self):
-
-        return PageTemplateFile('apcExport.xml', _xmldir)
-
-    def _getImportMapping(self):
-
-        return {
-          'actions-tool':
-            { 'action-provider': {KEY: 'providers', DEFAULT: ()},
-              'object':          {KEY: 'objects', DEFAULT: ()},
-              'xmlns:i18n':      {} },
-          'action-provider':
-            { 'id':              {},
-              'remove':          {},
-              'action':          {KEY: 'actions', DEFAULT: ()} },
-          'action':
-            { 'action_id':       {KEY: 'id'},
-              'title':           {},
-              'description':     {CONVERTER: self._convertToUnique},
-              'category':        {},
-              'condition_expr':  {KEY: 'condition'},
-              'permission':      {KEY: 'permissions', DEFAULT: ()},
-              'visible':         {CONVERTER: self._convertToBoolean},
-              'url_expr':        {KEY: 'action'} },
-          'permission':
-            { '#text':           {KEY: None} } }
-
-InitializeClass(ActionProvidersConfigurator)
+    doc = PrettyDocument()
+    doc.appendChild(exporter.exportNode(doc))
+    context.writeDataFile(_FILENAME, doc.toprettyxml(' '), 'text/xml')
+    return 'Actions tool exported.'

Modified: CMF/trunk/CMFSetup/tests/test_actions.py
===================================================================
--- CMF/trunk/CMFSetup/tests/test_actions.py	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFSetup/tests/test_actions.py	2005-10-09 19:59:31 UTC (rev 39025)
@@ -20,13 +20,19 @@
 import Zope2
 Zope2.startup()
 
+import Products
 from Acquisition import Implicit
 from Acquisition import aq_parent
 from OFS.Folder import Folder
 from OFS.OrderedFolder import OrderedFolder
+from Products.Five import zcml
+from zope.app.tests.placelesssetup import PlacelessSetup
+from zope.interface import implements
+
 from Products.CMFCore.ActionProviderBase import ActionProviderBase
 from Products.CMFCore.interfaces.portal_actions \
     import ActionProvider as IActionProvider
+from Products.CMFCore.interfaces import IActionsTool
 
 from common import BaseRegistryTests
 from common import DummyExportContext
@@ -53,6 +59,10 @@
 
 class DummyActionsTool( DummyTool ):
 
+    implements(IActionsTool)
+    id = 'portal_actions'
+    meta_type = 'CMF Actions Tool'
+
     def __init__( self ):
 
         self._providers = []
@@ -69,11 +79,10 @@
 
         self._providers = [ x for x in self._providers if x != provider_name ]
 
-class _ActionSetup( BaseRegistryTests ):
+class _ActionSetup(PlacelessSetup, BaseRegistryTests):
 
     def _initSite( self, foo=2, bar=2 ):
-
-        self.root.site = Folder( id='site' )
+        self.root.site = Folder(id='site')
         site = self.root.site
 
         site.portal_membership = DummyMembershipTool()
@@ -111,148 +120,38 @@
 
         return site
 
-class ActionProvidersConfiguratorTests( _ActionSetup ):
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        BaseRegistryTests.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
 
-    def _getTargetClass( self ):
+    def tearDown(self):
+        BaseRegistryTests.tearDown(self)
+        PlacelessSetup.tearDown(self)
 
-        from Products.CMFSetup.actions import ActionProvidersConfigurator
-        return ActionProvidersConfigurator
-
-    def test_listProviderInfo_normal( self ):
-
-        site = self._initSite()
-
-        EXPECTED = [ { 'id' : 'portal_actions'
-                     , 'actions' : []
-                     }
-                   , { 'id' : 'portal_foo'
-                     , 'actions' : [ { 'id' : 'foo'
-                                     , 'title' : 'Foo'
-                                     , 'description' : ''
-                                     , 'action' : 'string:${object_url}/foo'
-                                     , 'condition' : 'python:1'
-                                     , 'permissions' : ()
-                                     , 'category' : 'dummy'
-                                     , 'visible' : True
-                                     }
-                                   ]
-                     }
-                   , { 'id' : 'portal_bar'
-                     , 'actions' : [ { 'id' : 'bar'
-                                     , 'title' : 'Bar'
-                                     , 'description' : ''
-                                     , 'action' : 'string:${object_url}/bar'
-                                     , 'condition' : 'python:0'
-                                     , 'permissions' : ('Manage portal',)
-                                     , 'category' : 'dummy'
-                                     , 'visible' : False
-                                     }
-                                   ]
-                     }
-                   ]
-
-        configurator = self._makeOne( site )
-
-        info_list = configurator.listProviderInfo()
-        self.assertEqual( len( info_list ), len( EXPECTED ) )
-
-        for found, expected in zip( info_list, EXPECTED ):
-            self.assertEqual( found, expected )
-
-    def test_generateXML_empty( self ):
-
-        site = self._initSite( 0, 0 )
-        configurator = self._makeOne( site ).__of__( site )
-        self._compareDOM( configurator.generateXML(), _EMPTY_EXPORT )
-
-    def test_generateXML_normal( self ):
-
-        site = self._initSite()
-        configurator = self._makeOne( site ).__of__( site )
-        self._compareDOM( configurator.generateXML(), _NORMAL_EXPORT )
-
-
-    def test_parseXML_empty( self ):
-
-        site = self._initSite( 0, 0 )
-        configurator = self._makeOne( site )
-
-        tool_info = configurator.parseXML( _EMPTY_EXPORT )
-        self.assertEqual( len(tool_info), 3 )
-
-        self.assertEqual( len( tool_info[ 'providers' ] ), 1 )
-
-        info = tool_info[ 'providers' ][ 0 ]
-        self.assertEqual( info[ 'id' ], 'portal_actions' )
-        self.assertEqual( len( info[ 'actions' ] ), 0 )
-
-    def test_parseXML_normal( self ):
-
-        site = self._initSite( 1, 1 )
-
-        configurator = self._makeOne( site )
-        tool_info = configurator.parseXML( _NORMAL_EXPORT )
-        self.assertEqual( len(tool_info), 3 )
-
-        self.assertEqual( len( tool_info['providers'] ), 3 )
-
-        info = tool_info[ 'providers' ][ 0 ]
-        self.assertEqual( info[ 'id' ], 'portal_actions' )
-        self.assertEqual( len( info[ 'actions' ] ), 0 )
-
-        info = tool_info[ 'providers' ][ 1 ]
-        self.assertEqual( info[ 'id' ], 'portal_foo' )
-        self.assertEqual( len( info[ 'actions' ] ), 1 )
-
-        action = info[ 'actions' ][ 0 ]
-        self.assertEqual( action[ 'id' ], 'foo' )
-        self.assertEqual( action[ 'title' ], 'Foo' )
-        self.assertEqual( action[ 'action' ]
-                        , 'string:${object_url}/foo' )
-        self.assertEqual( action[ 'condition' ], 'python:1' )
-        self.assertEqual( action[ 'permissions' ], () )
-        self.assertEqual( action[ 'category' ], 'dummy' )
-        self.assertEqual( action[ 'visible' ], True )
-
-        info = tool_info[ 'providers' ][ 2 ]
-        self.assertEqual( info[ 'id' ], 'portal_bar' )
-        self.assertEqual( len( info[ 'actions' ] ), 1 )
-
-        action = info[ 'actions' ][ 0 ]
-        self.assertEqual( action[ 'id' ], 'bar' )
-        self.assertEqual( action[ 'title' ], 'Bar' )
-        self.assertEqual( action[ 'action' ]
-                        , 'string:${object_url}/bar' )
-        self.assertEqual( action[ 'condition' ], 'python:0' )
-        self.assertEqual( action[ 'permissions' ], ('Manage portal',) )
-        self.assertEqual( action[ 'category' ], 'dummy' )
-        self.assertEqual( action[ 'visible' ], False )
-
-
-
 _EMPTY_EXPORT = """\
 <?xml version="1.0"?>
-<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider id="portal_actions">
- </action-provider>
-</actions-tool>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+</object>
 """
 
 _NORMAL_EXPORT = """\
 <?xml version="1.0"?>
-<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider id="portal_actions">
- </action-provider>
- <action-provider id="portal_foo">
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
+ <action-provider name="portal_foo">
   <action action_id="foo"
           title="Foo"
           url_expr="string:${object_url}/foo"
           condition_expr="python:1"
           category="dummy"
-          visible="True">
-  </action>
-</action-provider>
- <action-provider id="portal_bar">
+          visible="True"/>
+ </action-provider>
+ <action-provider name="portal_bar">
   <action action_id="bar"
           title="Bar"
           url_expr="string:${object_url}/bar"
@@ -262,57 +161,58 @@
    <permission>Manage portal</permission>
   </action>
  </action-provider>
-</actions-tool>
+</object>
 """
 
 _NEWSYTLE_EXPORT = """\
 <?xml version="1.0"?>
-<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider id="portal_actions">
- </action-provider>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
  <object name="dummy" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="foo" meta_type="CMF Action">
-  <property name="title">Foo</property>
-  <property name="description"></property>
-  <property name="url_expr">string:${object_url}/foo</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python:1</property>
-  <property name="permissions"></property>
-  <property name="visible">True</property>
+  <object name="foo" meta_type="CMF Action">
+   <property name="title">Foo</property>
+   <property name="description"></property>
+   <property name="url_expr">string:${object_url}/foo</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 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>
-</actions-tool>
+</object>
 """
 
 _I18N_IMPORT = """\
 <?xml version="1.0"?>
-<actions-tool xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <action-provider id="portal_actions">
- </action-provider>
+<object meta_type="CMF Actions Tool" name="portal_actions" \
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <action-provider name="portal_actions"/>
  <object name="dummy" meta_type="CMF Action Category">
   <property name="title"></property>
- <object name="foo" meta_type="CMF Action" i18n:domain="foo_domain">
-  <property name="title" i18n:translate="">Foo</property>
-  <property name="description" i18n:translate=""></property>
-  <property name="url_expr">string:${object_url}/foo</property>
-  <property name="icon_expr"></property>
-  <property name="available_expr">python:1</property>
-  <property name="permissions"></property>
-  <property name="visible">True</property>
+  <object name="foo" meta_type="CMF Action" i18n:domain="foo_domain">
+   <property name="title" i18n:translate="">Foo</property>
+   <property name="description" i18n:translate=""></property>
+   <property name="url_expr">string:${object_url}/foo</property>
+   <property name="icon_expr"></property>
+   <property name="available_expr">python:1</property>
+   <property name="permissions"></property>
+   <property name="visible">True</property>
+  </object>
  </object>
- </object>
-</actions-tool>
+</object>
 """
 
 _INSERT_IMPORT = """\
@@ -581,7 +481,6 @@
 
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite( ActionProvidersConfiguratorTests ),
         unittest.makeSuite( Test_exportActionProviders ),
         unittest.makeSuite( Test_importActionProviders ),
         ))

Deleted: CMF/trunk/CMFSetup/xml/apcExport.xml
===================================================================
--- CMF/trunk/CMFSetup/xml/apcExport.xml	2005-10-09 19:31:59 UTC (rev 39024)
+++ CMF/trunk/CMFSetup/xml/apcExport.xml	2005-10-09 19:59:31 UTC (rev 39025)
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-<actions-tool xmlns:tal="http://xml.zope.org/namespaces/tal"
-   tal:attributes="xmlns:i18n string:http://xml.zope.org/namespaces/i18n">
- <tal:loop tal:repeat="info context/listProviderInfo"
- ><action-provider id="portal_actions"
-                  tal:attributes="id info/id;" >
-  <action action_id="folder_contents"
-          title="Folder Contents"
-          condition_expr=""
-          url_expr="string:${folder_url}/folder_contents"
-          category="folder"
-          visible="True"
-          tal:repeat="action info/actions"
-          tal:attributes="action_id action/id;
-                          title action/title;
-                          condition_expr action/condition;
-                          url_expr action/action;
-                          category action/category;
-                          visible action/visible;
-                         ">
-   <permission
-      tal:repeat="permission action/permissions"
-      tal:content="permission">View</permission>
-  </action>
- </action-provider></tal:loop
-><tal:span tal:define="sub_infos context/listSubobjectInfos"
-     tal:replace="structure python: context.generateObjectNodes(sub_infos)"/>
-</actions-tool>



More information about the CMF-checkins mailing list