[CMF-checkins] SVN: CMF/trunk/ - converted types tool setup handlers to new style

Yvo Schubbe y.2005- at wcm-solutions.de
Thu Nov 24 06:39:06 EST 2005


Log message for revision 40355:
  - converted types tool setup handlers to new style
  - converted type info add form to a view, sharing code and template with the dc workflow add form

Changed:
  U   CMF/trunk/CMFCore/TypesTool.py
  U   CMF/trunk/CMFCore/__init__.py
  U   CMF/trunk/CMFCore/browser/configure.zcml
  U   CMF/trunk/CMFCore/configure.zcml
  U   CMF/trunk/CMFCore/exportimport/configure.zcml
  U   CMF/trunk/CMFCore/exportimport/tests/test_typeinfo.py
  U   CMF/trunk/CMFCore/exportimport/typeinfo.py
  U   CMF/trunk/CMFCore/tests/test_TypesTool.py
  D   CMF/trunk/CMFCore/www/addTypeInfo.zpt
  D   CMF/trunk/CMFSetup/tests/test_typeinfo.py
  U   CMF/trunk/CMFSetup/typeinfo.py
  D   CMF/trunk/CMFSetup/xml/ticToolExport.xml
  D   CMF/trunk/DCWorkflow/browser/addDCWorkflowDefinition.pt
  U   CMF/trunk/DCWorkflow/browser/configure.zcml
  U   CMF/trunk/DCWorkflow/browser/workflow.py
  U   CMF/trunk/DCWorkflow/configure.zcml
  A   CMF/trunk/GenericSetup/browser/
  A   CMF/trunk/GenericSetup/browser/__init__.py
  A   CMF/trunk/GenericSetup/browser/addWithPresettings.pt

-=-
Modified: CMF/trunk/CMFCore/TypesTool.py
===================================================================
--- CMF/trunk/CMFCore/TypesTool.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/TypesTool.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -17,7 +17,6 @@
 
 from sys import exc_info
 from warnings import warn
-from xml.dom.minidom import parseString
 
 import Products
 from AccessControl import ClassSecurityInfo
@@ -39,8 +38,6 @@
 def MessageID(val, domain): # XXX performance?
     return MessageFactory(domain)(val)
 
-from Products.GenericSetup.interfaces import INodeImporter
-
 from ActionProviderBase import ActionProviderBase
 from exceptions import AccessControl_Unauthorized
 from exceptions import BadRequest
@@ -68,9 +65,8 @@
 
 class TypeInformation(SimpleItemWithProperties, ActionProviderBase):
 
+    """ Base class for information about a content type.
     """
-    Base class for information about a content type.
-    """
 
     _isTypeInformation = 1
 
@@ -454,14 +450,12 @@
 
 class FactoryTypeInformation(TypeInformation):
 
+    """ Portal content factory.
     """
-    Portal content factory.
-    """
 
     implements(ITypeInformation)
     __implements__ = z2ITypeInformation
 
-    meta_type = 'Factory-based Type Information'
     security = ClassSecurityInfo()
 
     _properties = (TypeInformation._basic_properties + (
@@ -563,14 +557,12 @@
 
 class ScriptableTypeInformation( TypeInformation ):
 
+    """ Invokes a script rather than a factory to create the content.
     """
-    Invokes a script rather than a factory to create the content.
-    """
 
     implements(ITypeInformation)
     __implements__ = z2ITypeInformation
 
-    meta_type = 'Scriptable Type Information'
     security = ClassSecurityInfo()
 
     _properties = (TypeInformation._basic_properties + (
@@ -619,86 +611,6 @@
 InitializeClass( ScriptableTypeInformation )
 
 
-_addTypeInfo_template = PageTemplateFile('addTypeInfo.zpt', _wwwdir)
-
-def manage_addFactoryTIForm(dispatcher, REQUEST):
-    """ Get the add form for factory-based type infos.
-    """
-    template = _addTypeInfo_template.__of__(dispatcher)
-    meta_type = FactoryTypeInformation.meta_type
-    return template(add_meta_type=meta_type,
-                    profiles=_getProfileInfo(dispatcher, meta_type))
-
-def manage_addScriptableTIForm(dispatcher, REQUEST):
-    """ Get the add form for scriptable type infos.
-    """
-    template = _addTypeInfo_template.__of__(dispatcher)
-    meta_type = ScriptableTypeInformation.meta_type
-    return template(add_meta_type=meta_type,
-                    profiles=_getProfileInfo(dispatcher, meta_type))
-
-def _getProfileInfo(dispatcher, meta_type):
-    profiles = []
-    stool = getToolByName(dispatcher, 'portal_setup', None)
-    if stool:
-        for info in stool.listContextInfos():
-            type_ids = []
-            context = stool._getImportContext(info['id'])
-            filenames = context.listDirectory('types')
-            if filenames is None:
-                continue
-            for filename in filenames:
-                body = context.readDataFile(filename, subdir='types')
-                if body is None:
-                    continue
-                root = parseString(body).documentElement
-                if root.getAttribute('meta_type') == meta_type:
-                    type_id = root.getAttribute('name')
-                    type_ids.append(type_id)
-            if not type_ids:
-                continue
-            type_ids.sort()
-            profiles.append({'id': info['id'],
-                             'title': info['title'],
-                             'type_ids': tuple(type_ids)})
-    return tuple(profiles)
-
-def manage_addTypeInfo(dispatcher, add_meta_type, id, settings_id='',
-                       REQUEST=None):
-    """Add a new TypeInformation object of type 'add_meta_type' with ID 'id'.
-    """
-    settings_node = None
-    if settings_id:
-        stool = getToolByName(dispatcher, 'portal_setup', None)
-        if stool:
-            profile_id, type_id = settings_id.split('/')
-            context = stool._getImportContext(profile_id)
-            filenames = context.listDirectory('types')
-            for filename in filenames or ():
-                body = context.readDataFile(filename, subdir='types')
-                if body is not None:
-                    root = parseString(body).documentElement
-                    if root.getAttribute('name') != type_id:
-                        continue
-                    if root.getAttribute('meta_type') == add_meta_type:
-                        settings_node = root
-                        if not id:
-                            id = type_id
-                        break
-    for mt in Products.meta_types:
-        if mt['name'] == add_meta_type:
-            klass = mt['instance']
-            break
-    else:
-        raise ValueError('Meta type %s is not a type class.' % add_meta_type)
-    obj = klass(id)
-    if settings_node:
-        INodeImporter(obj).importNode(settings_node)
-    dispatcher._setObject(id, obj)
-
-    if REQUEST:
-        return dispatcher.manage_main(dispatcher, REQUEST)
-
 allowedTypes = [
     'Script (Python)',
     'Python Method',
@@ -710,9 +622,8 @@
 class TypesTool(UniqueObject, IFAwareObjectManager, Folder,
                 ActionProviderBase):
 
+    """ Provides a configurable registry of portal content types.
     """
-        Provides a configurable registry of portal content types.
-    """
 
     implements(ITypesTool)
     __implements__ = (z2ITypesTool, ActionProviderBase.__implements__)

Modified: CMF/trunk/CMFCore/__init__.py
===================================================================
--- CMF/trunk/CMFCore/__init__.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/__init__.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -36,7 +36,6 @@
 
 from interfaces import IAction
 from interfaces import IActionCategory
-from interfaces import ITypeInformation
 from permissions import AddPortalFolders
 from permissions import ManagePortal
 
@@ -143,24 +142,10 @@
         visibility=None,
         interfaces=(IAction,))
 
-    context.registerClass(
-        TypesTool.FactoryTypeInformation,
-        permission=ManagePortal,
-        constructors=(TypesTool.manage_addFactoryTIForm,
-                      TypesTool.manage_addTypeInfo),
-        icon='images/typeinfo.gif',
-        visibility=None,
-        interfaces=(ITypeInformation,))
-
-    context.registerClass(
-        TypesTool.ScriptableTypeInformation,
-        permission=ManagePortal,
-        constructors=(TypesTool.manage_addScriptableTIForm,
-                      TypesTool.manage_addTypeInfo),
-        icon='images/typeinfo.gif',
-        visibility=None,
-        interfaces=(ITypeInformation,))
-
+    utils.registerIcon(TypesTool.FactoryTypeInformation,
+                       'images/typeinfo.gif', globals())
+    utils.registerIcon(TypesTool.ScriptableTypeInformation,
+                       'images/typeinfo.gif', globals())
     utils.registerIcon(FSDTMLMethod.FSDTMLMethod,
                        'images/fsdtml.gif', globals())
     utils.registerIcon(FSPythonScript.FSPythonScript,

Modified: CMF/trunk/CMFCore/browser/configure.zcml
===================================================================
--- CMF/trunk/CMFCore/browser/configure.zcml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/browser/configure.zcml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -7,6 +7,28 @@
 
   <five:traversable class="Products.CMFCore.WorkflowTool.WorkflowTool"/>
 
+  <five:traversable class="Products.CMFCore.TypesTool.TypesTool"/>
+
+  <configure package="Products.GenericSetup.browser">
+
+    <browser:page
+        for="zope.app.container.interfaces.IAdding"
+        name="addFactoryTypeInformation.html"
+        template="addWithPresettings.pt"
+        class="Products.CMFCore.browser.typeinfo.FactoryTypeInformationAddView"
+        permission="cmf.ManagePortal"
+        />
+
+    <browser:page
+        for="zope.app.container.interfaces.IAdding"
+        name="addScriptableTypeInformation.html"
+        template="addWithPresettings.pt"
+        class="Products.CMFCore.browser.typeinfo.ScriptableTypeInformationAddView"
+        permission="cmf.ManagePortal"
+        />
+
+  </configure>
+
   <!-- Set up default menus as action categories. -->
   <browser:menu
     id="object"

Modified: CMF/trunk/CMFCore/configure.zcml
===================================================================
--- CMF/trunk/CMFCore/configure.zcml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/configure.zcml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,12 +1,26 @@
 <configure
-    xmlns="http://namespaces.zope.org/zope">
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    >
 
-  <include
-      package=".browser"
+  <include package=".browser"/>
+
+  <include package=".exportimport"/>
+
+  <five:registerClass
+      class=".TypesTool.FactoryTypeInformation"
+      meta_type="Factory-based Type Information"
+      addview="addFactoryTypeInformation.html"
+      permission="cmf.ManagePortal"
+      global="False"
       />
 
-  <include
-      package=".exportimport"
+  <five:registerClass
+      class=".TypesTool.ScriptableTypeInformation"
+      meta_type="Scriptable Type Information"
+      addview="addScriptableTypeInformation.html"
+      permission="cmf.ManagePortal"
+      global="False"
       />
 
 </configure>

Modified: CMF/trunk/CMFCore/exportimport/configure.zcml
===================================================================
--- CMF/trunk/CMFCore/exportimport/configure.zcml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/exportimport/configure.zcml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -111,15 +111,17 @@
       />
 
   <adapter
-      factory=".typeinfo.TypeInformationNodeAdapter"
-      provides="Products.GenericSetup.interfaces.INodeExporter"
-      for="Products.CMFCore.interfaces.ITypeInformation"
+      factory=".typeinfo.TypeInformationXMLAdapter"
+      provides="Products.GenericSetup.interfaces.IBody"
+      for="Products.CMFCore.interfaces.ITypeInformation
+           Products.GenericSetup.interfaces.ISetupContext"
       />
 
   <adapter
-      factory=".typeinfo.TypeInformationNodeAdapter"
-      provides="Products.GenericSetup.interfaces.INodeImporter"
-      for="Products.CMFCore.interfaces.ITypeInformation"
+      factory=".typeinfo.TypesToolXMLAdapter"
+      provides="Products.GenericSetup.interfaces.IBody"
+      for="Products.CMFCore.interfaces.ITypesTool
+           Products.GenericSetup.interfaces.ISetupContext"
       />
 
   <adapter

Modified: CMF/trunk/CMFCore/exportimport/tests/test_typeinfo.py
===================================================================
--- CMF/trunk/CMFCore/exportimport/tests/test_typeinfo.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/exportimport/tests/test_typeinfo.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -10,21 +10,33 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Types tool node adapter unit tests.
+"""Types tool xml adapter and setup handler unit tests.
 
 $Id$
 """
 
 import unittest
 import Testing
-import Zope2
-Zope2.startup()
 
+import Products
+from OFS.Folder import Folder
+from Products.Five import zcml
+
+from Products.CMFCore.permissions import View
+from Products.CMFCore.permissions import AccessContentsInformation
+from Products.CMFCore.permissions import ModifyPortalContent
 from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.GenericSetup.testing import NodeAdapterTestCase
+from Products.CMFCore.TypesTool import FactoryTypeInformation
+from Products.CMFCore.TypesTool import ScriptableTypeInformation
+from Products.CMFCore.TypesTool import TypesTool
+from Products.GenericSetup.testing import BodyAdapterTestCase
+from Products.GenericSetup.tests.common import BaseRegistryTests
+from Products.GenericSetup.tests.common import DummyExportContext
+from Products.GenericSetup.tests.common import DummyImportContext
 
 
-_FTI_XML = """\
+_FTI_BODY = """\
+<?xml version="1.0"?>
 <object name="foo_fti" meta_type="Factory-based Type Information"
    xmlns:i18n="http://xml.zope.org/namespaces/i18n">
  <property name="title"></property>
@@ -46,14 +58,22 @@
 </object>
 """
 
+_TYPESTOOL_BODY = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"></property>
+ <object name="foo_type" meta_type="Factory-based Type Information"/>
+</object>
+"""
 
-class TypeInformationNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
 
+class TypeInformationXMLAdapterTests(BodyAdapterTestCase):
+
     def _getTargetClass(self):
         from Products.CMFCore.exportimport.typeinfo \
-                import TypeInformationNodeAdapter
+                import TypeInformationXMLAdapter
 
-        return TypeInformationNodeAdapter
+        return TypeInformationXMLAdapter
 
     def _populate(self, obj):
         obj.addAction('foo_action', 'Foo', 'string:${object_url}/foo',
@@ -77,22 +97,612 @@
         self.assertEqual(obj._actions[0].condition.text, 'python:1')
 
     def setUp(self):
+        import Products.CMFCore
         from Products.CMFCore.TypesTool import FactoryTypeInformation
-        import Products.CMFCore.exportimport
-        import Products.Five
-        from Products.Five import zcml
 
+        BodyAdapterTestCase.setUp(self)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        self._obj = FactoryTypeInformation('foo_fti')
+        self._BODY = _FTI_BODY
+
+
+class TypesToolXMLAdapterTests(BodyAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.CMFCore.exportimport.typeinfo \
+                import TypesToolXMLAdapter
+
+        return TypesToolXMLAdapter
+
+    def _populate(self, obj):
+        from Products.CMFCore.TypesTool import FactoryTypeInformation
+
+        obj._setObject('foo_type', FactoryTypeInformation('foo_type'))
+
+    def setUp(self):
+        import Products.CMFCore
+        from Products.CMFCore.TypesTool import TypesTool
+
+        BodyAdapterTestCase.setUp(self)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        self._obj = TypesTool()
+        self._BODY = _TYPESTOOL_BODY
+
+
+class _TypeInfoSetup(PlacelessSetup, BaseRegistryTests):
+
+    def _initSite(self, foo=0):
+        self.root.site = Folder(id='site')
+        site = self.root.site
+        ttool = site.portal_types = TypesTool()
+
+        if foo == 1:
+            fti = _TI_LIST[0].copy()
+            ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
+            sti = _TI_LIST[1].copy()
+            ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
+        elif foo == 2:
+            fti = _TI_LIST_WITH_FILENAME[0].copy()
+            ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
+            sti = _TI_LIST_WITH_FILENAME[1].copy()
+            ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
+
+        return site
+
+    def setUp(self):
         PlacelessSetup.setUp(self)
+        BaseRegistryTests.setUp(self)
         zcml.load_config('meta.zcml', Products.Five)
-        zcml.load_config('configure.zcml', Products.CMFCore.exportimport)
+        zcml.load_config('permissions.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
 
-        self._obj = FactoryTypeInformation('foo_fti')
-        self._XML = _FTI_XML
+    def tearDown(self):
+        BaseRegistryTests.tearDown(self)
+        PlacelessSetup.tearDown(self)
 
 
+_TI_LIST = ({
+    'id':                    'foo',
+    'title':                 'Foo',
+    'description':           'Foo things',
+    'i18n_domain':           'foo_domain',
+    'content_meta_type':     'Foo Thing',
+    'content_icon':          'foo.png',
+    'product':               'CMFSetup',
+    'factory':               'addFoo',
+    'immediate_view':        'foo_view',
+    'filter_content_types':  False,
+    'allowed_content_types': (),
+    'allow_discussion':      False,
+    'global_allow':          False,
+    'aliases': {'(Default)': 'foo_view',
+                'view':      'foo_view',
+                },
+    'actions': ({'id':     'view',
+                 'name':   'View',
+                 'action': 'string:${object_url}/foo_view',
+                 'permissions': (View,),
+                 },
+                {'id':     'edit',
+                 'name':   'Edit',
+                 'action': 'string:${object_url}/foo_edit_form',
+                 'permissions': (ModifyPortalContent,),
+                 },
+                {'id':     'metadata',
+                 'name':   'Metadata',
+                 'action': 'string:${object_url}/metadata_edit_form',
+                 'permissions': (ModifyPortalContent,),
+                 },
+                ),
+    }, {
+    'id':                    'bar',
+    'title':                 'Bar',
+    'description':           'Bar things',
+    'content_meta_type':     'Bar Thing',
+    'content_icon':          'bar.png',
+    'constructor_path':      'make_bar',
+    'permission':            'Add portal content',
+    'immediate_view':        'bar_view',
+    'filter_content_types':  True,
+    'allowed_content_types': ('foo',),
+    'allow_discussion':      True,
+    'global_allow':          True,
+    'aliases': {'(Default)': 'bar_view',
+                'view':      'bar_view',
+                },
+    'actions': ({'id':     'view',
+                 'name':   'View',
+                 'action': 'string:${object_url}/bar_view',
+                 'permissions': (View,),
+                 },
+                {'id':     'edit',
+                 'name':   'Edit',
+                 'action': 'string:${object_url}/bar_edit_form',
+                 'permissions': (ModifyPortalContent,),
+                 },
+                {'id':     'contents',
+                 'name':   'Contents',
+                 'action': 'string:${object_url}/folder_contents',
+                 'permissions': (AccessContentsInformation,),
+                 },
+                {'id':     'metadata',
+                 'name':   'Metadata',
+                 'action': 'string:${object_url}/metadata_edit_form',
+                 'permissions': (ModifyPortalContent,),
+                 },
+               ),
+    })
+
+_TI_LIST_WITH_FILENAME = []
+
+for original in _TI_LIST:
+    duplicate = original.copy()
+    duplicate['id'] = '%s object' % original['id']
+    _TI_LIST_WITH_FILENAME.append(duplicate)
+
+_EMPTY_TOOL_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+</object>
+"""
+
+_EMPTY_TOOL_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+</types-tool>
+"""
+
+_NORMAL_TOOL_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+ <object name="bar" meta_type="Scriptable Type Information"/>
+ <object name="foo" meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_NORMAL_TOOL_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="bar" />
+ <type id="foo" />
+</types-tool>
+"""
+
+_FILENAME_EXPORT = """\
+<?xml version="1.0"?>
+<object name="portal_types" meta_type="CMF Types Tool">
+ <property name="title"/>
+ <object name="bar object" meta_type="Scriptable Type Information"/>
+ <object name="foo object" meta_type="Factory-based Type Information"/>
+</object>
+"""
+
+_FILENAME_EXPORT_V1 = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="bar object" filename="types/bar_object.xml" />
+ <type id="foo object" filename="types/foo_object.xml" />
+</types-tool>
+"""
+
+_UPDATE_TOOL_IMPORT = """\
+<?xml version="1.0"?>
+<types-tool>
+ <type id="foo"/>
+</types-tool>
+"""
+
+_FOO_OLD_EXPORT = """\
+<?xml version="1.0"?>
+<type-info
+   id="%s"
+   kind="Factory-based Type Information"
+   title="Foo"
+   meta_type="Foo Thing"
+   icon="foo.png"
+   product="CMFSetup"
+   factory="addFoo"
+   immediate_view="foo_view"
+   filter_content_types="False"
+   allow_discussion="False"
+   global_allow="False" >
+  <description>Foo things</description>
+  <aliases>
+   <alias from="(Default)" to="foo_view" />
+   <alias from="view" to="foo_view" />
+  </aliases>
+  <action
+     action_id="view"
+     title="View"
+     url_expr="string:${object_url}/foo_view"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>View</permission>
+  </action>
+  <action
+     action_id="edit"
+     title="Edit"
+     url_expr="string:${object_url}/foo_edit_form"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>Modify portal content</permission>
+  </action>
+  <action
+     action_id="metadata"
+     title="Metadata"
+     url_expr="string:${object_url}/metadata_edit_form"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>Modify portal content</permission>
+  </action>
+</type-info>
+"""
+
+_FOO_EXPORT = """\
+<?xml version="1.0"?>
+<object name="%s" meta_type="Factory-based Type Information"
+   i18n:domain="foo_domain" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title" i18n:translate="">Foo</property>
+ <property name="description" i18n:translate="">Foo things</property>
+ <property name="content_icon">foo.png</property>
+ <property name="content_meta_type">Foo Thing</property>
+ <property name="product">CMFSetup</property>
+ <property name="factory">addFoo</property>
+ <property name="immediate_view">foo_view</property>
+ <property name="global_allow">False</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types"/>
+ <property name="allow_discussion">False</property>
+ <alias from="(Default)" to="foo_view"/>
+ <alias from="view" to="foo_view"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    url_expr="string:${object_url}/foo_view" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    url_expr="string:${object_url}/foo_edit_form" visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+ <action title="Metadata" action_id="metadata" category="object"
+    condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
+    visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+</object>
+"""
+
+_BAR_OLD_EXPORT = """\
+<?xml version="1.0"?>
+<type-info
+   id="%s"
+   kind="Scriptable Type Information"
+   title="Bar"
+   meta_type="Bar Thing"
+   icon="bar.png"
+   constructor_path="make_bar"
+   permission="Add portal content"
+   immediate_view="bar_view"
+   filter_content_types="True"
+   allow_discussion="True"
+   global_allow="True" >
+  <description>Bar things</description>
+  <allowed_content_type>foo</allowed_content_type>
+  <aliases>
+   <alias from="(Default)" to="bar_view" />
+   <alias from="view" to="bar_view" />
+  </aliases>
+  <action
+     action_id="view"
+     title="View"
+     url_expr="string:${object_url}/bar_view"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>View</permission>
+  </action>
+  <action
+     action_id="edit"
+     title="Edit"
+     url_expr="string:${object_url}/bar_edit_form"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>Modify portal content</permission>
+  </action>
+  <action
+     action_id="contents"
+     title="Contents"
+     url_expr="string:${object_url}/folder_contents"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>Access contents information</permission>
+  </action>
+  <action
+     action_id="metadata"
+     title="Metadata"
+     url_expr="string:${object_url}/metadata_edit_form"
+     condition_expr=""
+     category="object"
+     visible="True">
+   <permission>Modify portal content</permission>
+  </action>
+</type-info>
+"""
+
+_BAR_EXPORT = """\
+<?xml version="1.0"?>
+<object name="%s" meta_type="Scriptable Type Information"
+   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+ <property name="title">Bar</property>
+ <property name="description">Bar things</property>
+ <property name="content_icon">bar.png</property>
+ <property name="content_meta_type">Bar Thing</property>
+ <property name="permission">Add portal content</property>
+ <property name="constructor_path">make_bar</property>
+ <property name="immediate_view">bar_view</property>
+ <property name="global_allow">True</property>
+ <property name="filter_content_types">True</property>
+ <property name="allowed_content_types">
+  <element value="foo"/>
+ </property>
+ <property name="allow_discussion">True</property>
+ <alias from="(Default)" to="bar_view"/>
+ <alias from="view" to="bar_view"/>
+ <action title="View" action_id="view" category="object" condition_expr=""
+    url_expr="string:${object_url}/bar_view" visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" action_id="edit" category="object" condition_expr=""
+    url_expr="string:${object_url}/bar_edit_form" visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+ <action title="Contents" action_id="contents" category="object"
+    condition_expr="" url_expr="string:${object_url}/folder_contents"
+    visible="True">
+  <permission value="Access contents information"/>
+ </action>
+ <action title="Metadata" action_id="metadata" category="object"
+    condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
+    visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+</object>
+"""
+
+_UPDATE_FOO_IMPORT = """\
+<object name="foo">
+ <alias from="spam" to="eggs"/>
+</object>
+"""
+
+
+class exportTypesToolTests(_TypeInfoSetup):
+
+    def test_empty(self):
+        from Products.CMFSetup.typeinfo import exportTypesTool
+
+        site = self._initSite()
+        context = DummyExportContext(site)
+        exportTypesTool(context)
+
+        self.assertEqual(len(context._wrote), 1)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'typestool.xml')
+        self._compareDOM(text, _EMPTY_TOOL_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
+
+    def test_normal(self):
+        from Products.CMFSetup.typeinfo import exportTypesTool
+
+        site = self._initSite(1)
+        context = DummyExportContext(site)
+        exportTypesTool(context)
+
+        self.assertEqual(len(context._wrote), 3)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'typestool.xml')
+        self._compareDOM(text, _NORMAL_TOOL_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
+
+        filename, text, content_type = context._wrote[2]
+        self.assertEqual(filename, 'types/bar.xml')
+        self._compareDOM(text, _BAR_EXPORT % 'bar')
+        self.assertEqual(content_type, 'text/xml')
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'types/foo.xml')
+        self._compareDOM(text, _FOO_EXPORT % 'foo')
+        self.assertEqual(content_type, 'text/xml')
+
+    def test_with_filenames(self):
+        from Products.CMFSetup.typeinfo import exportTypesTool
+
+        site = self._initSite(2)
+        context = DummyExportContext(site)
+        exportTypesTool(context)
+
+        self.assertEqual(len(context._wrote), 3)
+
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'typestool.xml')
+        self._compareDOM(text, _FILENAME_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
+
+        filename, text, content_type = context._wrote[2]
+        self.assertEqual(filename, 'types/bar_object.xml')
+        self._compareDOM(text, _BAR_EXPORT % 'bar object')
+        self.assertEqual(content_type, 'text/xml')
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'types/foo_object.xml')
+        self._compareDOM(text, _FOO_EXPORT % 'foo object')
+        self.assertEqual(content_type, 'text/xml')
+
+
+class importTypesToolTests(_TypeInfoSetup):
+
+    _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT
+    _FILENAME_EXPORT = _FILENAME_EXPORT
+    _NORMAL_TOOL_EXPORT = _NORMAL_TOOL_EXPORT
+
+    def test_empty_default_purge(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite(1)
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 2)
+
+        context = DummyImportContext(site)
+        context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 0)
+
+    def test_empty_explicit_purge(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite(1)
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 2)
+
+        context = DummyImportContext(site, True)
+        context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 0)
+
+    def test_empty_skip_purge(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite(1)
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 2)
+
+        context = DummyImportContext(site, False)
+        context._files['typestool.xml'] = self._EMPTY_TOOL_EXPORT
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 2)
+
+    def test_normal(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite()
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 0)
+
+        context = DummyImportContext(site)
+        context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+        context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
+        context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 2)
+        self.failUnless('foo' in tool.objectIds())
+        self.failUnless('bar' in tool.objectIds())
+
+    def test_old_xml(self):
+        from Products.CMFSetup.typeinfo import exportTypesTool
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite()
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 0)
+
+        context = DummyImportContext(site)
+        context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+        context._files['types/foo.xml'] = _FOO_OLD_EXPORT % 'foo'
+        context._files['types/bar.xml'] = _BAR_OLD_EXPORT % 'bar'
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 2)
+        self.failUnless('foo' in tool.objectIds())
+        self.failUnless('bar' in tool.objectIds())
+
+        context = DummyExportContext(site)
+        exportTypesTool(context)
+
+        filename, text, content_type = context._wrote[1]
+        self.assertEqual(filename, 'types/bar.xml')
+        self._compareDOM(text, _BAR_EXPORT % 'bar')
+        self.assertEqual(content_type, 'text/xml')
+
+    def test_with_filenames(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite()
+        tool = site.portal_types
+
+        self.assertEqual(len(tool.objectIds()), 0)
+
+        context = DummyImportContext(site)
+        context._files['typestool.xml'] = self._FILENAME_EXPORT
+        context._files['types/foo_object.xml'] = _FOO_EXPORT % 'foo object'
+        context._files['types/bar_object.xml'] = _BAR_EXPORT % 'bar object'
+        importTypesTool(context)
+
+        self.assertEqual(len(tool.objectIds()), 2)
+        self.failUnless('foo object' in tool.objectIds())
+        self.failUnless('bar object' in tool.objectIds())
+
+    def test_normal_update(self):
+        from Products.CMFSetup.typeinfo import importTypesTool
+
+        site = self._initSite()
+        tool = site.portal_types
+
+        context = DummyImportContext(site)
+        context._files['typestool.xml'] = self._NORMAL_TOOL_EXPORT
+        context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
+        context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
+        importTypesTool(context)
+
+        self.assertEqual(tool.foo.title, 'Foo')
+        self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
+        self.assertEqual(tool.foo.content_icon, 'foo.png')
+        self.assertEqual(tool.foo.immediate_view, 'foo_view')
+        self.assertEqual(tool.foo._aliases,
+                         {'(Default)': 'foo_view', 'view': 'foo_view'})
+
+        context = DummyImportContext(site, False)
+        context._files['typestool.xml'] = _UPDATE_TOOL_IMPORT
+        context._files['types/foo.xml'] = _UPDATE_FOO_IMPORT
+        importTypesTool(context)
+
+        self.assertEqual(tool.foo.title, 'Foo')
+        self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
+        self.assertEqual(tool.foo.content_icon, 'foo.png')
+        self.assertEqual(tool.foo.immediate_view, 'foo_view')
+        self.assertEqual(tool.foo._aliases,
+               {'(Default)': 'foo_view', 'view': 'foo_view', 'spam': 'eggs'})
+
+class importTypesToolV1Tests(importTypesToolTests):
+
+    _EMPTY_TOOL_EXPORT = _EMPTY_TOOL_EXPORT_V1
+    _FILENAME_EXPORT = _FILENAME_EXPORT_V1
+    _NORMAL_TOOL_EXPORT = _NORMAL_TOOL_EXPORT_V1
+
+
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(TypeInformationNodeAdapterTests),
+        unittest.makeSuite(TypeInformationXMLAdapterTests),
+        unittest.makeSuite(TypesToolXMLAdapterTests),
+        unittest.makeSuite(exportTypesToolTests),
+        unittest.makeSuite(importTypesToolTests),
+        unittest.makeSuite(importTypesToolV1Tests),
         ))
 
 if __name__ == '__main__':

Modified: CMF/trunk/CMFCore/exportimport/typeinfo.py
===================================================================
--- CMF/trunk/CMFCore/exportimport/typeinfo.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/exportimport/typeinfo.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -10,26 +10,42 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Types tool node adapters.
+"""Types tool xml adapters and setup handlers.
 
 $Id$
 """
 
+from xml.dom.minidom import parseString
+
+import Products
+from zope.app import zapi
+
+from Products.GenericSetup.interfaces import IBody
 from Products.GenericSetup.interfaces import PURGE
+from Products.GenericSetup.utils import exportObjects
 from Products.GenericSetup.utils import I18NURI
-from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import importObjects
+from Products.GenericSetup.utils import ObjectManagerHelpers
 from Products.GenericSetup.utils import PropertyManagerHelpers
+from Products.GenericSetup.utils import XMLAdapterBase
 
 from Products.CMFCore.interfaces import ITypeInformation
+from Products.CMFCore.interfaces import ITypesTool
+from Products.CMFCore.utils import getToolByName
 
 
-class TypeInformationNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
+_FILENAME = 'typestool.xml'
 
+
+class TypeInformationXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):
+
     """Node im- and exporter for TypeInformation.
     """
 
     __used_for__ = ITypeInformation
 
+    _LOGGER_ID = 'typestool'
+
     def exportNode(self, doc):
         """Export the object as a DOM node.
         """
@@ -39,6 +55,8 @@
         node.appendChild(self._extractProperties())
         node.appendChild(self._extractAliases())
         node.appendChild(self._extractActions())
+
+        self._logger.info('\'%s\' type info exported.' % self.context.getId())
         return node
 
     def importNode(self, node, mode=PURGE):
@@ -54,6 +72,8 @@
         self._initAliases(node, mode)
         self._initActions(node, mode)
 
+        self._logger.info('\'%s\' type info imported.' % self.context.getId())
+
     def _extractAliases(self):
         fragment = self._doc.createDocumentFragment()
         aliases = self.context.getMethodAliases().items()
@@ -176,3 +196,103 @@
             permission = node.getAttribute('permission')
             obj._updateProperty('constructor_path', constructor_path)
             obj._updateProperty('permission', permission)
+
+
+class TypesToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers,
+                          PropertyManagerHelpers):
+
+    """Node im- and exporter for TypesTool.
+    """
+
+    __used_for__ = ITypesTool
+
+    _LOGGER_ID = 'typestool'
+
+    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())
+
+        self._logger.info('Types tool exported.')
+        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)
+        self._initBBBObjects(node, mode)
+
+        self._logger.info('Types tool imported.')
+
+    def _initBBBObjects(self, node, mode):
+        for child in node.childNodes:
+            if child.nodeName != 'type':
+                continue
+            parent = self.context
+
+            obj_id = str(child.getAttribute('id'))
+            if obj_id not in parent.objectIds():
+                filename = str(child.getAttribute('filename'))
+                if not filename:
+                    filename = 'types/%s.xml' % obj_id.replace(' ', '_')
+                body = self.environ.readDataFile(filename)
+                if body is None:
+                    break
+                root = parseString(body).documentElement
+                if root.getAttribute('name') != obj_id:
+                    if root.getAttribute('id') != obj_id:
+                        break
+                meta_type = str(root.getAttribute('kind'))
+                if not meta_type:
+                    meta_type = str(root.getAttribute('meta_type'))
+                for mt_info in Products.meta_types:
+                    if mt_info['name'] == meta_type:
+                        parent._setObject(obj_id, mt_info['instance'](obj_id))
+                        break
+
+
+def importTypesTool(context):
+    """Import types tool and content types from XML files.
+    """
+    site = context.getSite()
+    logger = context.getLogger('typestool')
+    tool = getToolByName(site, 'portal_types')
+
+    body = context.readDataFile(_FILENAME)
+    if body is None:
+        logger.info('Nothing to import.')
+        return
+
+    importer = zapi.queryMultiAdapter((tool, context), IBody)
+    if importer is None:
+        logger.warning('Import adapter misssing.')
+        return
+
+    importer.body = body
+    importObjects(tool, 'types', context)
+
+def exportTypesTool(context):
+    """Export types tool content types as a set of XML files.
+    """
+    site = context.getSite()
+    logger = context.getLogger('typestool')
+    tool = getToolByName(site, 'portal_types')
+    if tool is None:
+        logger.info('Nothing to export.')
+        return
+
+    exporter = zapi.queryMultiAdapter((tool, context), IBody)
+    if exporter is None:
+        logger.warning('Export adapter misssing.')
+        return
+
+    context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)
+    exportObjects(tool, 'types', context)

Modified: CMF/trunk/CMFCore/tests/test_TypesTool.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_TypesTool.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/tests/test_TypesTool.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -17,16 +17,16 @@
 
 from unittest import TestCase, TestSuite, makeSuite, main
 import Testing
-import Zope2
-Zope2.startup()
 
+import Products
 from AccessControl import Unauthorized
 from AccessControl.SecurityManagement import newSecurityManager
 from AccessControl.SecurityManagement import noSecurityManager
 from AccessControl.SecurityManager import setSecurityPolicy
 from Acquisition import aq_base
+from Products.Five import zcml
 from Products.PythonScripts.PythonScript import PythonScript
-from Products.PythonScripts.standard import url_quote
+from Products.PythonScripts.standard import html_quote
 from webdav.NullResource import NullResource
 
 from Products.CMFCore.ActionInformation import ActionInformation
@@ -38,6 +38,7 @@
 from Products.CMFCore.tests.base.dummy import DummyUserFolder
 from Products.CMFCore.tests.base.security import OmnipotentUser
 from Products.CMFCore.tests.base.security import UserWithRoles
+from Products.CMFCore.tests.base.testcase import PlacelessSetup
 from Products.CMFCore.tests.base.testcase import SecurityTest
 from Products.CMFCore.tests.base.testcase import WarningInterceptor
 from Products.CMFCore.tests.base.tidata import FTIDATA_ACTIONS
@@ -52,8 +53,30 @@
 from Products.CMFCore.tests.base.tidata import STI_SCRIPT
 
 
-class TypesToolTests(SecurityTest, WarningInterceptor):
+_TRAVERSE_ZCML = """
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:five="http://namespaces.zope.org/five"
+    >
 
+  <adapter
+      for="*"
+      factory=".traversable.FiveTraversable"
+      provides="zope.app.traversing.interfaces.ITraversable"
+      />
+
+  <adapter
+      for="*"
+      factory="zope.app.traversing.adapters.Traverser"
+      provides="zope.app.traversing.interfaces.ITraverser"
+      />
+
+</configure>
+"""
+
+
+class TypesToolTests(PlacelessSetup, SecurityTest, WarningInterceptor):
+
     def _makeOne(self):
         from Products.CMFCore.TypesTool import TypesTool
 
@@ -62,7 +85,13 @@
     def setUp( self ):
         from Products.CMFCore.TypesTool import FactoryTypeInformation as FTI
 
+        PlacelessSetup.setUp(self)
         SecurityTest.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('permissions.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.Five.browser)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+        zcml.load_string(_TRAVERSE_ZCML)
 
         self.site = DummySite('site').__of__(self.root)
         self.acl_users = self.site._setObject( 'acl_users', DummyUserFolder() )
@@ -72,6 +101,7 @@
 
     def tearDown(self):
         SecurityTest.tearDown(self)
+        PlacelessSetup.tearDown(self)
         self._free_warning_output()
 
     def test_z2interfaces(self):
@@ -105,9 +135,9 @@
         # so we check for that. If we've got it, something is b0rked.
         for factype in tool.all_meta_types():
             meta_types[factype['name']]=1
-            # The url_quote below is necessary 'cos of the one in
+            # The html_quote below is necessary 'cos of the one in
             # main.dtml. Could be removed once that is gone.
-            act = tool.unrestrictedTraverse(url_quote(factype['action']))
+            act = tool.unrestrictedTraverse(html_quote(factype['action']))
             self.failIf(type(aq_base(act)) is NullResource)
 
         # Check the ones we're expecting are there

Deleted: CMF/trunk/CMFCore/www/addTypeInfo.zpt
===================================================================
--- CMF/trunk/CMFCore/www/addTypeInfo.zpt	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFCore/www/addTypeInfo.zpt	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,47 +0,0 @@
-<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
-<h2 tal:define="form_title string:Add ${options/add_meta_type}"
-    tal:replace="structure context/manage_form_title">FORM TITLE</h2>
-
-<p class="form-help">A type information object defines a portal type.</p>
-
-<form action="manage_addTypeInfo" method="post">
-<input type="hidden" name="add_meta_type" value=""
-   tal:attributes="value options/add_meta_type" />
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
-  <td>
-   <div class="form-label">ID</div>
-  </td>
-  <td>
-   <input type="text" name="id" size="40" />
-  </td>
- </tr>
- <tr tal:condition="options/profiles">
-  <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="type_id profile/type_ids"
-             tal:attributes="value string:${profile/id}/${type_id}"
-             tal:content="type_id">TYPE ID</option></optgroup>
-   </select>
-  </td>
- </tr>
- <tr>
-  <td>
-   &nbsp;
-  </td>
-  <td>
-   <input class="form-element" type="submit" name="submit" value="Add" /> 
-  </td>
- </tr>
-</table>
-</form>
-
-<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>

Deleted: CMF/trunk/CMFSetup/tests/test_typeinfo.py
===================================================================
--- CMF/trunk/CMFSetup/tests/test_typeinfo.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFSetup/tests/test_typeinfo.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,690 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Types tool setup handler unit tests.
-
-$Id$
-"""
-
-import unittest
-import Testing
-import Zope2
-Zope2.startup()
-
-import Products
-from OFS.Folder import Folder
-from Products.Five import zcml
-
-from Products.CMFCore.permissions import View
-from Products.CMFCore.permissions import AccessContentsInformation
-from Products.CMFCore.permissions import ModifyPortalContent
-from Products.CMFCore.tests.base.testcase import PlacelessSetup
-from Products.CMFCore.TypesTool import FactoryTypeInformation
-from Products.CMFCore.TypesTool import ScriptableTypeInformation
-from Products.CMFCore.TypesTool import TypesTool
-from Products.GenericSetup.tests.common import BaseRegistryTests
-from Products.GenericSetup.tests.common import DummyExportContext
-from Products.GenericSetup.tests.common import DummyImportContext
-
-
-class _TypeInfoSetup(PlacelessSetup, BaseRegistryTests):
-
-    def _initSite(self, foo=0):
-        self.root.site = Folder(id='site')
-        site = self.root.site
-        ttool = site.portal_types = TypesTool()
-
-        if foo == 1:
-            fti = _TI_LIST[0].copy()
-            ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
-            sti = _TI_LIST[1].copy()
-            ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
-        elif foo == 2:
-            fti = _TI_LIST_WITH_FILENAME[0].copy()
-            ttool._setObject(fti['id'], FactoryTypeInformation(**fti))
-            sti = _TI_LIST_WITH_FILENAME[1].copy()
-            ttool._setObject(sti['id'], ScriptableTypeInformation(**sti))
-
-        return site
-
-    def setUp(self):
-        PlacelessSetup.setUp(self)
-        BaseRegistryTests.setUp(self)
-        zcml.load_config('meta.zcml', Products.Five)
-        zcml.load_config('configure.zcml', Products.CMFCore)
-
-    def tearDown(self):
-        BaseRegistryTests.tearDown(self)
-        PlacelessSetup.tearDown(self)
-
-
-class TypesToolExportConfiguratorTests(_TypeInfoSetup):
-
-    def _getTargetClass(self):
-
-        from Products.CMFSetup.typeinfo import TypesToolExportConfigurator
-        return TypesToolExportConfigurator
-
-    def test_listTypeInfo_empty(self):
-
-        site = self._initSite()
-        configurator = self._makeOne(site).__of__(site)
-
-        self.assertEqual(len(configurator.listTypeInfo()), 0)
-
-    def test_listTypeInfo_filled(self):
-
-        site = self._initSite(1)
-        configurator = self._makeOne(site).__of__(site)
-
-        self.assertEqual(len(configurator.listTypeInfo()), len(_TI_LIST))
-
-        info_list = configurator.listTypeInfo()
-        self.assertEqual(len(info_list), len(_TI_LIST))
-
-        _marker = object()
-
-        for i in range(len(_TI_LIST)):
-            found = info_list[i]
-            expected = _TI_LIST[1-i]
-            self.assertEqual(found['id'], expected['id'])
-            self.failUnless(found.get('filename', _marker) is _marker)
-
-    def test_listTypeInfo_with_filename (self):
-
-        site = self._initSite(2)
-        configurator = self._makeOne(site).__of__(site)
-
-        info_list = configurator.listTypeInfo()
-        self.assertEqual(len(info_list), len(_TI_LIST_WITH_FILENAME))
-
-        for i in range(len(_TI_LIST_WITH_FILENAME)):
-            found = info_list[i]
-            expected = _TI_LIST_WITH_FILENAME[1-i]
-            self.assertEqual(found['id'], expected['id'])
-            self.assertEqual(found['filename'],
-                             'types/%s.xml'
-                             % expected['id'].replace(' ', '_')
-                             )
-
-    def test_generateXML_empty(self):
-
-        site = self._initSite()
-        configurator = self._makeOne(site).__of__(site)
-        self._compareDOM(configurator.generateXML(), _EMPTY_TOOL_EXPORT)
-
-    def test_generateXML_normal(self):
-
-        site = self._initSite(1)
-        configurator = self._makeOne(site).__of__(site)
-        self._compareDOM(configurator.generateXML(), _NORMAL_TOOL_EXPORT)
-
-    def test_generateXML_explicit_filename(self):
-
-        site = self._initSite(2)
-        configurator = self._makeOne(site).__of__(site)
-        self._compareDOM(configurator.generateXML(), _FILENAME_EXPORT)
-
-
-class TypesToolImportConfiguratorTests(_TypeInfoSetup):
-
-    def _getTargetClass(self):
-
-        from Products.CMFSetup.typeinfo import TypesToolImportConfigurator
-        return TypesToolImportConfigurator
-
-    def test_parseXML_empty(self):
-
-        site = self._initSite()
-        configurator = self._makeOne(site).__of__(site)
-
-        tool_info = configurator.parseXML(_EMPTY_TOOL_EXPORT)
-        self.assertEqual(len(tool_info['types']), 0)
-
-    def test_parseXML_normal(self):
-
-        site = self._initSite()
-        configurator = self._makeOne(site).__of__(site)
-
-        tool_info = configurator.parseXML(_NORMAL_TOOL_EXPORT)
-        self.assertEqual(len(tool_info['types']), 2)
-
-        type_info = tool_info['types'][1]
-        self.assertEqual(type_info['id'], 'foo')
-        self.assertEqual(type_info['filename'], 'types/foo.xml')
-        type_info = tool_info['types'][0]
-        self.assertEqual(type_info['id'], 'bar')
-        self.assertEqual(type_info['filename'], 'types/bar.xml')
-
-    def test_parseXML_with_filename(self):
-
-        site = self._initSite()
-        configurator = self._makeOne(site).__of__(site)
-
-        tool_info = configurator.parseXML(_FILENAME_EXPORT)
-        self.assertEqual(len(tool_info['types']), 2)
-
-        type_info = tool_info['types'][1]
-        self.assertEqual(type_info['id'], 'foo object')
-        self.assertEqual(type_info['filename'], 'types/foo_object.xml')
-        type_info = tool_info['types'][0]
-        self.assertEqual(type_info['id'], 'bar object')
-        self.assertEqual(type_info['filename'], 'types/bar_object.xml')
-
-
-_TI_LIST = ({
-    'id':                    'foo',
-    'title':                 'Foo',
-    'description':           'Foo things',
-    'i18n_domain':           'foo_domain',
-    'content_meta_type':     'Foo Thing',
-    'content_icon':          'foo.png',
-    'product':               'CMFSetup',
-    'factory':               'addFoo',
-    'immediate_view':        'foo_view',
-    'filter_content_types':  False,
-    'allowed_content_types': (),
-    'allow_discussion':      False,
-    'global_allow':          False,
-    'aliases': {'(Default)': 'foo_view',
-                'view':      'foo_view',
-                },
-    'actions': ({'id':     'view',
-                 'name':   'View',
-                 'action': 'string:${object_url}/foo_view',
-                 'permissions': (View,),
-                 },
-                {'id':     'edit',
-                 'name':   'Edit',
-                 'action': 'string:${object_url}/foo_edit_form',
-                 'permissions': (ModifyPortalContent,),
-                 },
-                {'id':     'metadata',
-                 'name':   'Metadata',
-                 'action': 'string:${object_url}/metadata_edit_form',
-                 'permissions': (ModifyPortalContent,),
-                 },
-                ),
-    }, {
-    'id':                    'bar',
-    'title':                 'Bar',
-    'description':           'Bar things',
-    'content_meta_type':     'Bar Thing',
-    'content_icon':          'bar.png',
-    'constructor_path':      'make_bar',
-    'permission':            'Add portal content',
-    'immediate_view':        'bar_view',
-    'filter_content_types':  True,
-    'allowed_content_types': ('foo',),
-    'allow_discussion':      True,
-    'global_allow':          True,
-    'aliases': {'(Default)': 'bar_view',
-                'view':      'bar_view',
-                },
-    'actions': ({'id':     'view',
-                 'name':   'View',
-                 'action': 'string:${object_url}/bar_view',
-                 'permissions': (View,),
-                 },
-                {'id':     'edit',
-                 'name':   'Edit',
-                 'action': 'string:${object_url}/bar_edit_form',
-                 'permissions': (ModifyPortalContent,),
-                 },
-                {'id':     'contents',
-                 'name':   'Contents',
-                 'action': 'string:${object_url}/folder_contents',
-                 'permissions': (AccessContentsInformation,),
-                 },
-                {'id':     'metadata',
-                 'name':   'Metadata',
-                 'action': 'string:${object_url}/metadata_edit_form',
-                 'permissions': (ModifyPortalContent,),
-                 },
-               ),
-    })
-
-_TI_LIST_WITH_FILENAME = []
-
-for original in _TI_LIST:
-    duplicate = original.copy()
-    duplicate['id'] = '%s object' % original['id']
-    _TI_LIST_WITH_FILENAME.append(duplicate)
-
-_EMPTY_TOOL_EXPORT = """\
-<?xml version="1.0"?>
-<types-tool>
-</types-tool>
-"""
-
-_NORMAL_TOOL_EXPORT = """\
-<?xml version="1.0"?>
-<types-tool>
- <type id="bar" />
- <type id="foo" />
-</types-tool>
-"""
-
-_FILENAME_EXPORT = """\
-<?xml version="1.0"?>
-<types-tool>
- <type id="bar object" filename="types/bar_object.xml" />
- <type id="foo object" filename="types/foo_object.xml" />
-</types-tool>
-"""
-
-_UPDATE_TOOL_IMPORT = """\
-<?xml version="1.0"?>
-<types-tool>
- <type id="foo"/>
-</types-tool>
-"""
-
-_FOO_OLD_EXPORT = """\
-<?xml version="1.0"?>
-<type-info
-   id="%s"
-   kind="Factory-based Type Information"
-   title="Foo"
-   meta_type="Foo Thing"
-   icon="foo.png"
-   product="CMFSetup"
-   factory="addFoo"
-   immediate_view="foo_view"
-   filter_content_types="False"
-   allow_discussion="False"
-   global_allow="False" >
-  <description>Foo things</description>
-  <aliases>
-   <alias from="(Default)" to="foo_view" />
-   <alias from="view" to="foo_view" />
-  </aliases>
-  <action
-     action_id="view"
-     title="View"
-     url_expr="string:${object_url}/foo_view"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>View</permission>
-  </action>
-  <action
-     action_id="edit"
-     title="Edit"
-     url_expr="string:${object_url}/foo_edit_form"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>Modify portal content</permission>
-  </action>
-  <action
-     action_id="metadata"
-     title="Metadata"
-     url_expr="string:${object_url}/metadata_edit_form"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>Modify portal content</permission>
-  </action>
-</type-info>
-"""
-
-_FOO_EXPORT = """\
-<?xml version="1.0"?>
-<object name="%s" meta_type="Factory-based Type Information"
-   i18n:domain="foo_domain" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <property name="title" i18n:translate="">Foo</property>
- <property name="description" i18n:translate="">Foo things</property>
- <property name="content_icon">foo.png</property>
- <property name="content_meta_type">Foo Thing</property>
- <property name="product">CMFSetup</property>
- <property name="factory">addFoo</property>
- <property name="immediate_view">foo_view</property>
- <property name="global_allow">False</property>
- <property name="filter_content_types">False</property>
- <property name="allowed_content_types"/>
- <property name="allow_discussion">False</property>
- <alias from="(Default)" to="foo_view"/>
- <alias from="view" to="foo_view"/>
- <action title="View" action_id="view" category="object" condition_expr=""
-    url_expr="string:${object_url}/foo_view" visible="True">
-  <permission value="View"/>
- </action>
- <action title="Edit" action_id="edit" category="object" condition_expr=""
-    url_expr="string:${object_url}/foo_edit_form" visible="True">
-  <permission value="Modify portal content"/>
- </action>
- <action title="Metadata" action_id="metadata" category="object"
-    condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
-    visible="True">
-  <permission value="Modify portal content"/>
- </action>
-</object>
-"""
-
-_BAR_OLD_EXPORT = """\
-<?xml version="1.0"?>
-<type-info
-   id="%s"
-   kind="Scriptable Type Information"
-   title="Bar"
-   meta_type="Bar Thing"
-   icon="bar.png"
-   constructor_path="make_bar"
-   permission="Add portal content"
-   immediate_view="bar_view"
-   filter_content_types="True"
-   allow_discussion="True"
-   global_allow="True" >
-  <description>Bar things</description>
-  <allowed_content_type>foo</allowed_content_type>
-  <aliases>
-   <alias from="(Default)" to="bar_view" />
-   <alias from="view" to="bar_view" />
-  </aliases>
-  <action
-     action_id="view"
-     title="View"
-     url_expr="string:${object_url}/bar_view"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>View</permission>
-  </action>
-  <action
-     action_id="edit"
-     title="Edit"
-     url_expr="string:${object_url}/bar_edit_form"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>Modify portal content</permission>
-  </action>
-  <action
-     action_id="contents"
-     title="Contents"
-     url_expr="string:${object_url}/folder_contents"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>Access contents information</permission>
-  </action>
-  <action
-     action_id="metadata"
-     title="Metadata"
-     url_expr="string:${object_url}/metadata_edit_form"
-     condition_expr=""
-     category="object"
-     visible="True">
-   <permission>Modify portal content</permission>
-  </action>
-</type-info>
-"""
-
-_BAR_EXPORT = """\
-<?xml version="1.0"?>
-<object name="%s" meta_type="Scriptable Type Information"
-   xmlns:i18n="http://xml.zope.org/namespaces/i18n">
- <property name="title">Bar</property>
- <property name="description">Bar things</property>
- <property name="content_icon">bar.png</property>
- <property name="content_meta_type">Bar Thing</property>
- <property name="permission">Add portal content</property>
- <property name="constructor_path">make_bar</property>
- <property name="immediate_view">bar_view</property>
- <property name="global_allow">True</property>
- <property name="filter_content_types">True</property>
- <property name="allowed_content_types">
-  <element value="foo"/>
- </property>
- <property name="allow_discussion">True</property>
- <alias from="(Default)" to="bar_view"/>
- <alias from="view" to="bar_view"/>
- <action title="View" action_id="view" category="object" condition_expr=""
-    url_expr="string:${object_url}/bar_view" visible="True">
-  <permission value="View"/>
- </action>
- <action title="Edit" action_id="edit" category="object" condition_expr=""
-    url_expr="string:${object_url}/bar_edit_form" visible="True">
-  <permission value="Modify portal content"/>
- </action>
- <action title="Contents" action_id="contents" category="object"
-    condition_expr="" url_expr="string:${object_url}/folder_contents"
-    visible="True">
-  <permission value="Access contents information"/>
- </action>
- <action title="Metadata" action_id="metadata" category="object"
-    condition_expr="" url_expr="string:${object_url}/metadata_edit_form"
-    visible="True">
-  <permission value="Modify portal content"/>
- </action>
-</object>
-"""
-
-_UPDATE_FOO_IMPORT = """\
-<object name="foo">
- <alias from="spam" to="eggs"/>
-</object>
-"""
-
-
-class Test_exportTypesTool(_TypeInfoSetup):
-
-    def test_empty(self):
-        from Products.CMFSetup.typeinfo import exportTypesTool
-
-        site = self._initSite()
-        context = DummyExportContext(site)
-        exportTypesTool(context)
-
-        self.assertEqual(len(context._wrote), 1)
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'typestool.xml')
-        self._compareDOM(text, _EMPTY_TOOL_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-    def test_normal(self):
-        from Products.CMFSetup.typeinfo import exportTypesTool
-
-        site = self._initSite(1)
-        context = DummyExportContext(site)
-        exportTypesTool(context)
-
-        self.assertEqual(len(context._wrote), 3)
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'typestool.xml')
-        self._compareDOM(text, _NORMAL_TOOL_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-        filename, text, content_type = context._wrote[1]
-        self.assertEqual(filename, 'types/bar.xml')
-        self._compareDOM(text, _BAR_EXPORT % 'bar')
-        self.assertEqual(content_type, 'text/xml')
-
-        filename, text, content_type = context._wrote[2]
-        self.assertEqual(filename, 'types/foo.xml')
-        self._compareDOM(text, _FOO_EXPORT % 'foo')
-        self.assertEqual(content_type, 'text/xml')
-
-    def test_with_filenames(self):
-        from Products.CMFSetup.typeinfo import exportTypesTool
-
-        site = self._initSite(2)
-        context = DummyExportContext(site)
-        exportTypesTool(context)
-
-        self.assertEqual(len(context._wrote), 3)
-
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'typestool.xml')
-        self._compareDOM(text, _FILENAME_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-        filename, text, content_type = context._wrote[1]
-        self.assertEqual(filename, 'types/bar_object.xml')
-        self._compareDOM(text, _BAR_EXPORT % 'bar object')
-        self.assertEqual(content_type, 'text/xml')
-
-        filename, text, content_type = context._wrote[2]
-        self.assertEqual(filename, 'types/foo_object.xml')
-        self._compareDOM(text, _FOO_EXPORT % 'foo object')
-        self.assertEqual(content_type, 'text/xml')
-
-class Test_importTypesTool(_TypeInfoSetup):
-
-    def test_empty_default_purge(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite(1)
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 2)
-
-        context = DummyImportContext(site)
-        context._files['typestool.xml'] = _EMPTY_TOOL_EXPORT
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 0)
-
-    def test_empty_explicit_purge(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite(1)
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 2)
-
-        context = DummyImportContext(site, True)
-        context._files['typestool.xml'] = _EMPTY_TOOL_EXPORT
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 0)
-
-    def test_empty_skip_purge(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite(1)
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 2)
-
-        context = DummyImportContext(site, False)
-        context._files['typestool.xml'] = _EMPTY_TOOL_EXPORT
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 2)
-
-    def test_normal(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite()
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 0)
-
-        context = DummyImportContext(site)
-        context._files['typestool.xml'] = _NORMAL_TOOL_EXPORT
-        context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
-        context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 2)
-        self.failUnless('foo' in tool.objectIds())
-        self.failUnless('bar' in tool.objectIds())
-
-    def test_old_xml(self):
-        from Products.CMFSetup.typeinfo import exportTypesTool
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite()
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 0)
-
-        context = DummyImportContext(site)
-        context._files['typestool.xml'] = _NORMAL_TOOL_EXPORT
-        context._files['types/foo.xml'] = _FOO_OLD_EXPORT % 'foo'
-        context._files['types/bar.xml'] = _BAR_OLD_EXPORT % 'bar'
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 2)
-        self.failUnless('foo' in tool.objectIds())
-        self.failUnless('bar' in tool.objectIds())
-
-        context = DummyExportContext(site)
-        exportTypesTool(context)
-
-        filename, text, content_type = context._wrote[1]
-        self.assertEqual(filename, 'types/bar.xml')
-        self._compareDOM(text, _BAR_EXPORT % 'bar')
-        self.assertEqual(content_type, 'text/xml')
-
-    def test_with_filenames(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite()
-        tool = site.portal_types
-
-        self.assertEqual(len(tool.objectIds()), 0)
-
-        context = DummyImportContext(site)
-        context._files['typestool.xml'] = _FILENAME_EXPORT
-        context._files['types/foo_object.xml'] = _FOO_EXPORT % 'foo object'
-        context._files['types/bar_object.xml'] = _BAR_EXPORT % 'bar object'
-        importTypesTool(context)
-
-        self.assertEqual(len(tool.objectIds()), 2)
-        self.failUnless('foo object' in tool.objectIds())
-        self.failUnless('bar object' in tool.objectIds())
-
-    def test_normal_update(self):
-        from Products.CMFSetup.typeinfo import importTypesTool
-
-        site = self._initSite()
-        tool = site.portal_types
-
-        context = DummyImportContext(site)
-        context._files['typestool.xml'] = _NORMAL_TOOL_EXPORT
-        context._files['types/foo.xml'] = _FOO_EXPORT % 'foo'
-        context._files['types/bar.xml'] = _BAR_EXPORT % 'bar'
-        importTypesTool(context)
-
-        self.assertEqual(tool.foo.title, 'Foo')
-        self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
-        self.assertEqual(tool.foo.content_icon, 'foo.png')
-        self.assertEqual(tool.foo.immediate_view, 'foo_view')
-        self.assertEqual(tool.foo._aliases,
-                         {'(Default)': 'foo_view', 'view': 'foo_view'})
-
-        context = DummyImportContext(site, False)
-        context._files['typestool.xml'] = _UPDATE_TOOL_IMPORT
-        context._files['types/foo.xml'] = _UPDATE_FOO_IMPORT
-        importTypesTool(context)
-
-        self.assertEqual(tool.foo.title, 'Foo')
-        self.assertEqual(tool.foo.content_meta_type, 'Foo Thing')
-        self.assertEqual(tool.foo.content_icon, 'foo.png')
-        self.assertEqual(tool.foo.immediate_view, 'foo_view')
-        self.assertEqual(tool.foo._aliases,
-               {'(Default)': 'foo_view', 'view': 'foo_view', 'spam': 'eggs'})
-
-
-def test_suite():
-    return unittest.TestSuite((
-        unittest.makeSuite(TypesToolExportConfiguratorTests),
-        unittest.makeSuite(TypesToolImportConfiguratorTests),
-        unittest.makeSuite(Test_exportTypesTool),
-        unittest.makeSuite(Test_importTypesTool),
-       ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Modified: CMF/trunk/CMFSetup/typeinfo.py
===================================================================
--- CMF/trunk/CMFSetup/typeinfo.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFSetup/typeinfo.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -10,187 +10,10 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" Types tool export / import
+"""Types tool setup handlers.
 
 $Id$
 """
 
-from xml.dom.minidom import parseString
-
-import Products
-from AccessControl import ClassSecurityInfo
-from Globals import InitializeClass
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-
-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 ImportConfiguratorBase, ExportConfiguratorBase
-from utils import CONVERTER, DEFAULT, KEY
-
-_FILENAME = 'typestool.xml'
-
-
-def importTypesTool(context):
-    """ Import types tool and content types from XML files.
-    """
-    site = context.getSite()
-    mode = context.shouldPurge() and PURGE or UPDATE
-    ttool = getToolByName(site, 'portal_types')
-
-    if context.shouldPurge():
-        for type in ttool.objectIds():
-            ttool._delObject(type)
-
-    ttc = TypesToolImportConfigurator(site)
-    xml = context.readDataFile(_FILENAME)
-    if xml is None:
-        return 'Types tool: Nothing to import.'
-
-    tool_info = ttc.parseXML(xml)
-
-    for type_info in tool_info['types']:
-
-        filename = type_info['filename']
-        sep = filename.rfind('/')
-        if sep == -1:
-            body = context.readDataFile( filename )
-        else:
-            body = context.readDataFile( filename[sep+1:], filename[:sep] )
-
-        if body is None:
-            continue
-
-        root = parseString(body).documentElement
-        ti_id = str(root.getAttribute('name'))
-        if not ti_id:
-            # BBB: for CMF 1.5 profiles
-            #      ID moved from 'id' to 'name'.
-            ti_id = str(root.getAttribute('id'))
-        if ti_id not in ttool.objectIds():
-            # BBB: for CMF 1.5 profiles
-            #     'kind' is now 'meta_type', the old 'meta_type' attribute
-            #      was replaced by a property element.
-            meta_type = str(root.getAttribute('kind'))
-            if not meta_type:
-                meta_type = str(root.getAttribute('meta_type'))
-            for mt_info in Products.meta_types:
-                if mt_info['name'] == meta_type:
-                    ttool._setObject(ti_id, mt_info['instance'](ti_id))
-                    break
-            else:
-                raise ValueError('unknown meta_type \'%s\'' % ti_id)
-
-        ti = ttool.getTypeInfo(ti_id)
-        importer = INodeImporter(ti, None)
-        if importer is None:
-            continue
-
-        importer.importNode(root, mode=mode)
-
-    # XXX: YAGNI?
-    # importScriptsToContainer(ttool, ('typestool_scripts',),
-    #                          context)
-
-    return 'Types tool imported.'
-
-def exportTypesTool(context):
-    """ Export types tool content types as a set of XML files.
-    """
-    site = context.getSite()
-
-    ttool = getToolByName(site, 'portal_types')
-    if ttool is None:
-        return 'Types tool: Nothing to export.'
-
-    ttc = TypesToolExportConfigurator(site).__of__(site)
-    tool_xml = ttc.generateXML()
-    context.writeDataFile(_FILENAME, tool_xml, 'text/xml')
-
-    for ti_id in ttool.listContentTypes():
-        type_filename = '%s.xml' % ti_id.replace( ' ', '_' )
-        ti = getattr(ttool, ti_id)
-
-        exporter = INodeExporter(ti)
-        if exporter is None:
-            continue
-
-        doc = PrettyDocument()
-        doc.appendChild(exporter.exportNode(doc))
-        context.writeDataFile(type_filename, doc.toprettyxml(' '), 'text/xml',
-                              'types')
-
-    # XXX: YAGNI?
-    # exportScriptsFromContainer(ttool, ('typestool_scripts',))
-
-    return 'Types tool exported'
-
-
-class TypesToolImportConfigurator(ImportConfiguratorBase):
-
-    def _getImportMapping(self):
-
-        return {
-          'types-tool':
-            { 'type':     {KEY: 'types', DEFAULT: (),
-                           CONVERTER: self._convertTypes} },
-          'type':
-            { 'id':       {},
-              'filename': {DEFAULT: '%(id)s'} } }
-
-    def _convertTypes(self, val):
-
-        for type in val:
-            if type['filename'] == type['id']:
-                type['filename'] = _getTypeFilename( type['filename'] )
-
-        return val
-
-InitializeClass(TypesToolImportConfigurator)
-
-
-class TypesToolExportConfigurator(ExportConfiguratorBase):
-
-    security = ClassSecurityInfo()
-
-    security.declareProtected( ManagePortal, 'listTypeInfo' )
-    def listTypeInfo( self ):
-
-        """ Return a list of mappings for each type info in the site.
-
-        o These mappings are pretty much equivalent to the stock
-          'factory_type_information' elements used everywhere in the
-          CMF.
-        """
-        result = []
-        typestool = getToolByName( self._site, 'portal_types' )
-
-        type_ids = typestool.listContentTypes()
-
-        for type_id in type_ids:
-            info = {'id': type_id}
-
-            if ' ' in type_id:
-                info['filename'] = _getTypeFilename(type_id)
-
-            result.append(info)
-
-        return result
-
-    def _getExportTemplate(self):
-
-        return PageTemplateFile('ticToolExport.xml', _xmldir)
-
-InitializeClass(TypesToolExportConfigurator)
-
-
-def _getTypeFilename( type_id ):
-
-    """ Return the name of the file which holds info for a given type.
-    """
-    return 'types/%s.xml' % type_id.replace( ' ', '_' )
+from Products.CMFCore.exportimport.typeinfo import exportTypesTool
+from Products.CMFCore.exportimport.typeinfo import importTypesTool

Deleted: CMF/trunk/CMFSetup/xml/ticToolExport.xml
===================================================================
--- CMF/trunk/CMFSetup/xml/ticToolExport.xml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/CMFSetup/xml/ticToolExport.xml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<types-tool xmlns:tal="http://xml.zope.org/namespaces/tal">
- <type id="TYPE_ID"
-       tal:repeat="info here/listTypeInfo"
-       tal:attributes="id info/id;
-                       filename info/filename | default;
-                      " />
-</types-tool>

Deleted: CMF/trunk/DCWorkflow/browser/addDCWorkflowDefinition.pt
===================================================================
--- CMF/trunk/DCWorkflow/browser/addDCWorkflowDefinition.pt	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/DCWorkflow/browser/addDCWorkflowDefinition.pt	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,46 +0,0 @@
-<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
-<h2 tal:define="form_title view/title"
-    tal:replace="structure context/manage_form_title">FORM TITLE</h2>
-
-<p class="form-help" tal:content="view/description">DESCRIPTION TEXT.</p>
-
-<form action="." method="post"
-   tal:attributes="action request/ACTUAL_URL">
-<table cellspacing="0" cellpadding="2" border="0">
- <tr>
-  <td>
-   <div class="form-label">ID</div>
-  </td>
-  <td>
-   <input type="text" name="add_input_name" size="40" />
-  </td>
- </tr>
- <tr tal:condition="view/getProfileInfos">
-  <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 view/getProfileInfos"
-       tal:attributes="label profile/title">
-     <option value="SETTINGS_ID"
-             tal:repeat="obj_id profile/obj_ids"
-             tal:attributes="value string:${profile/id}/${obj_id}"
-             tal:content="obj_id">OBJ ID</option></optgroup>
-   </select>
-  </td>
- </tr>
- <tr>
-  <td>
-   &nbsp;
-  </td>
-  <td>
-   <input class="form-element" type="submit" name="submit_add" value="Add" /> 
-  </td>
- </tr>
-</table>
-</form>
-
-<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>

Modified: CMF/trunk/DCWorkflow/browser/configure.zcml
===================================================================
--- CMF/trunk/DCWorkflow/browser/configure.zcml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/DCWorkflow/browser/configure.zcml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,12 +1,13 @@
 <configure
     xmlns:browser="http://namespaces.zope.org/browser"
+    package="Products.GenericSetup.browser"
     >
 
   <browser:page
       for="zope.app.container.interfaces.IAdding"
       name="addDCWorkflowDefinition.html"
-      template="addDCWorkflowDefinition.pt"
-      class=".workflow.DCWorkflowDefinitionAddView"
+      template="addWithPresettings.pt"
+      class="Products.DCWorkflow.browser.workflow.DCWorkflowDefinitionAddView"
       permission="cmf.ManagePortal"
       />
 

Modified: CMF/trunk/DCWorkflow/browser/workflow.py
===================================================================
--- CMF/trunk/DCWorkflow/browser/workflow.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/DCWorkflow/browser/workflow.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -20,37 +20,21 @@
 from zope.app import zapi
 
 from Products.CMFCore.utils import getToolByName
+from Products.GenericSetup.browser.utils import AddWithPresettingsViewBase
 from Products.GenericSetup.interfaces import IBody
 
 from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
 
 
-class DCWorkflowDefinitionAddView:
+class DCWorkflowDefinitionAddView(AddWithPresettingsViewBase):
 
     """Add view for DCWorkflowDefinition.
     """
 
-    title = u'Add DC Workflow Definition'
+    klass = DCWorkflowDefinition
 
     description = u'Add a web-configurable workflow.'
 
-    meta_type = DCWorkflowDefinition.meta_type
-
-    def __call__(self, add_input_name='', settings_id='', submit_add=''):
-        if submit_add:
-            if settings_id:
-                profile_id, obj_id = settings_id.split('/')
-                if not add_input_name:
-                    self.request.set('add_input_name', obj_id)
-                obj = DCWorkflowDefinition('temp')
-                self._init(obj, profile_id, obj_id)
-            else:
-                obj = DCWorkflowDefinition('temp')
-            self.context.add(obj)
-            self.request.response.redirect(self.context.nextURL())
-            return ''
-        return self.index()
-
     def getProfileInfos(self):
         profiles = []
         stool = getToolByName(self, 'portal_setup', None)
@@ -58,9 +42,9 @@
             for info in stool.listContextInfos():
                 obj_ids = []
                 context = stool._getImportContext(info['id'])
-                dirnames = context.listDirectory('workflows')
-                for dirname in dirnames or ():
-                    filename = 'workflows/%s/definition.xml' % dirname
+                file_ids = context.listDirectory('workflows')
+                for file_id in file_ids or ():
+                    filename = 'workflows/%s/definition.xml' % file_id
                     body = context.readDataFile(filename)
                     if body is None:
                         continue
@@ -75,7 +59,7 @@
                                  'obj_ids': tuple(obj_ids)})
         return tuple(profiles)
 
-    def _init(self, obj, profile_id, obj_id):
+    def _initSettings(self, obj, profile_id, obj_id):
         stool = getToolByName(self, 'portal_setup', None)
         if stool is None:
             return

Modified: CMF/trunk/DCWorkflow/configure.zcml
===================================================================
--- CMF/trunk/DCWorkflow/configure.zcml	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/DCWorkflow/configure.zcml	2005-11-24 11:39:06 UTC (rev 40355)
@@ -1,6 +1,7 @@
 <configure
     xmlns="http://namespaces.zope.org/zope"
-    xmlns:five="http://namespaces.zope.org/five">
+    xmlns:five="http://namespaces.zope.org/five"
+    >
 
   <include package=".browser"/>
 

Added: CMF/trunk/GenericSetup/browser/__init__.py
===================================================================
--- CMF/trunk/GenericSetup/browser/__init__.py	2005-11-24 11:20:28 UTC (rev 40354)
+++ CMF/trunk/GenericSetup/browser/__init__.py	2005-11-24 11:39:06 UTC (rev 40355)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""GenericSetup browser views.
+
+$Id$
+"""


Property changes on: CMF/trunk/GenericSetup/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Copied: CMF/trunk/GenericSetup/browser/addWithPresettings.pt (from rev 40340, CMF/trunk/DCWorkflow/browser/addDCWorkflowDefinition.pt)



More information about the CMF-checkins mailing list