[CMF-checkins] SVN: CMF/trunk/ - converted CookieCrumbler and MailHost setup handlers to new style

Yvo Schubbe y.2005- at wcm-solutions.de
Wed Oct 5 06:44:01 EDT 2005


Log message for revision 38762:
  - converted CookieCrumbler and MailHost setup handlers to new style
  - improved PrettyDocument output
  - updated CMFDefault default profile
  

Changed:
  U   CMF/trunk/CMFCore/CookieCrumbler.py
  U   CMF/trunk/CMFCore/configure.zcml
  U   CMF/trunk/CMFCore/interfaces/_tools.py
  A   CMF/trunk/CMFCore/nodeadapters.py
  U   CMF/trunk/CMFCore/tests/testCookieCrumbler.py
  A   CMF/trunk/CMFCore/tests/test_nodeadapters.py
  A   CMF/trunk/CMFDefault/profiles/default/cookieauth.xml
  A   CMF/trunk/CMFDefault/profiles/default/mailhost.xml
  U   CMF/trunk/CMFSetup/cookieauth.py
  U   CMF/trunk/CMFSetup/mailhost.py
  U   CMF/trunk/CMFSetup/tests/test_cookieauth.py
  U   CMF/trunk/CMFSetup/tests/test_mailhost.py
  D   CMF/trunk/CMFSetup/xml/ccExport.xml
  D   CMF/trunk/CMFSetup/xml/mhcExport.xml
  A   CMF/trunk/GenericSetup/MailHost/
  A   CMF/trunk/GenericSetup/MailHost/__init__.py
  A   CMF/trunk/GenericSetup/MailHost/adapters.py
  A   CMF/trunk/GenericSetup/MailHost/configure.zcml
  A   CMF/trunk/GenericSetup/MailHost/tests/
  A   CMF/trunk/GenericSetup/MailHost/tests/__init__.py
  A   CMF/trunk/GenericSetup/MailHost/tests/test_adapters.py
  U   CMF/trunk/GenericSetup/PluginIndexes/tests/test_adapters.py
  U   CMF/trunk/GenericSetup/ZCatalog/tests/test_adapters.py
  U   CMF/trunk/GenericSetup/configure.zcml
  U   CMF/trunk/GenericSetup/tests/test_utils.py
  U   CMF/trunk/GenericSetup/utils.py

-=-
Modified: CMF/trunk/CMFCore/CookieCrumbler.py
===================================================================
--- CMF/trunk/CMFCore/CookieCrumbler.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/CookieCrumbler.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -17,20 +17,21 @@
 
 from base64 import encodestring, decodestring
 from urllib import quote, unquote
-import sys
 
 from Acquisition import aq_inner, aq_parent
 from DateTime import DateTime
-from AccessControl import getSecurityManager, ClassSecurityInfo, Permissions
+from AccessControl import ClassSecurityInfo, Permissions
 from ZPublisher import BeforeTraverse
 import Globals
 from Globals import HTMLFile
-from zLOG import LOG, ERROR
 from ZPublisher.HTTPRequest import HTTPRequest
 from OFS.Folder import Folder
 from zExceptions import Redirect
+from zope.interface import implements
 
+from interfaces import ICookieCrumbler
 
+
 # Constants.
 ATTEMPT_NONE = 0       # No attempt at authentication
 ATTEMPT_LOGIN = 1      # Attempt to log in
@@ -40,15 +41,19 @@
 ViewManagementScreens = Permissions.view_management_screens
 
 
-class CookieCrumblerDisabled (Exception):
-    """Cookie crumbler should not be used for a certain request"""
+class CookieCrumblerDisabled(Exception):
 
+    """Cookie crumbler should not be used for a certain request.
+    """
 
-class CookieCrumbler (Folder):
-    '''
-    Reads cookies during traversal and simulates the HTTP
-    authentication headers.
-    '''
+
+class CookieCrumbler(Folder):
+
+    """Reads cookies during traversal and simulates the HTTP auth headers.
+    """
+
+    implements(ICookieCrumbler)
+
     meta_type = 'Cookie Crumbler'
 
     security = ClassSecurityInfo()
@@ -89,9 +94,9 @@
     auto_login_page = 'login_form'
     unauth_page = ''
     logout_page = 'logged_out'
-    local_cookie_path = 0
+    local_cookie_path = False
     cache_header_value = 'private'
-    log_username = 1
+    log_username = True
 
     security.declarePrivate('delRequestVar')
     def delRequestVar(self, req, name):

Modified: CMF/trunk/CMFCore/configure.zcml
===================================================================
--- CMF/trunk/CMFCore/configure.zcml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/configure.zcml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -9,4 +9,16 @@
     file="exportimport.zcml"
     />
 
+  <adapter
+      factory=".nodeadapters.CookieCrumblerNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeExporter"
+      for=".interfaces.ICookieCrumbler"
+      />
+
+  <adapter
+      factory=".nodeadapters.CookieCrumblerNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeImporter"
+      for=".interfaces.ICookieCrumbler"
+      />
+
 </configure>

Modified: CMF/trunk/CMFCore/interfaces/_tools.py
===================================================================
--- CMF/trunk/CMFCore/interfaces/_tools.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/interfaces/_tools.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -371,6 +371,15 @@
 
 
 #
+#   Cookie crumbler interfaces.
+#
+class ICookieCrumbler(Interface):
+
+    """Reads cookies during traversal and simulates the HTTP auth headers.
+    """
+
+
+#
 #   Discussion tool interfaces.
 #
 class IOldstyleDiscussionTool(Interface):

Added: CMF/trunk/CMFCore/nodeadapters.py
===================================================================
--- CMF/trunk/CMFCore/nodeadapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/nodeadapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""CMFCore node adapters.
+
+$Id$
+"""
+
+from Products.GenericSetup.interfaces import PURGE
+from Products.GenericSetup.utils import NodeAdapterBase
+from Products.GenericSetup.utils import PropertyManagerHelpers
+
+from interfaces import ICookieCrumbler
+
+
+class CookieCrumblerNodeAdapter(NodeAdapterBase, PropertyManagerHelpers):
+
+    """Node im- and exporter for CookieCrumbler.
+    """
+
+    __used_for__ = ICookieCrumbler
+
+    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.
+        """
+        if mode == PURGE:
+            self._purgeProperties()
+
+        self._initProperties(node, mode)


Property changes on: CMF/trunk/CMFCore/nodeadapters.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: CMF/trunk/CMFCore/tests/testCookieCrumbler.py
===================================================================
--- CMF/trunk/CMFCore/tests/testCookieCrumbler.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/tests/testCookieCrumbler.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -17,7 +17,6 @@
 
 import base64
 from cStringIO import StringIO
-import sys
 import unittest
 import urllib
 
@@ -29,7 +28,6 @@
 from AccessControl.SecurityManagement import noSecurityManager
 from ZPublisher.HTTPRequest import HTTPRequest
 from ZPublisher.HTTPResponse import HTTPResponse
-from ZPublisher.BaseRequest import RequestContainer
 
 from Products.CMFCore.CookieCrumbler \
      import CookieCrumbler, manage_addCC, Redirect
@@ -95,7 +93,12 @@
     def tearDown(self):
         noSecurityManager()
 
+    def test_z3interfaces(self):
+        from zope.interface.verify import verifyClass
+        from Products.CMFCore.interfaces import ICookieCrumbler
 
+        verifyClass(ICookieCrumbler, CookieCrumbler)
+
     def testNoCookies(self):
         # verify the cookie crumbler doesn't break when no cookies are given
         self.req.traverse('/')

Added: CMF/trunk/CMFCore/tests/test_nodeadapters.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_nodeadapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFCore/tests/test_nodeadapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,67 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""CMFCore node adapter unit tests.
+
+$Id$
+"""
+
+import unittest
+import Testing
+
+import Products
+from Products.Five import zcml
+from Products.GenericSetup.testing import NodeAdapterTestCase
+from zope.app.tests.placelesssetup import PlacelessSetup
+
+
+_COOKIECRUMBLER_XML = """\
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">__ac</property>
+ <property name="name_cookie">__ac_name</property>
+ <property name="pw_cookie">__ac_password</property>
+ <property name="persist_cookie">__ac_persistent</property>
+ <property name="auto_login_page">login_form</property>
+ <property name="logout_page">logged_out</property>
+ <property name="unauth_page"></property>
+ <property name="local_cookie_path">False</property>
+ <property name="cache_header_value">private</property>
+ <property name="log_username">True</property>
+</object>
+"""
+
+
+class CookieCrumblerNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.CMFCore.nodeadapters import CookieCrumblerNodeAdapter
+
+        return CookieCrumblerNodeAdapter
+
+    def setUp(self):
+        from Products.CMFCore.CookieCrumbler import CookieCrumbler
+
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.CMFCore)
+
+        self._obj = CookieCrumbler('foo_cookiecrumbler')
+        self._XML = _COOKIECRUMBLER_XML
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(CookieCrumblerNodeAdapterTests),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: CMF/trunk/CMFCore/tests/test_nodeadapters.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: CMF/trunk/CMFDefault/profiles/default/cookieauth.xml
===================================================================
--- CMF/trunk/CMFDefault/profiles/default/cookieauth.xml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFDefault/profiles/default/cookieauth.xml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<object name="cookie_authentication" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">__ac</property>
+ <property name="name_cookie">__ac_name</property>
+ <property name="pw_cookie">__ac_password</property>
+ <property name="persist_cookie">__ac_persistent</property>
+ <property name="auto_login_page">login_form</property>
+ <property name="logout_page">logged_out</property>
+ <property name="unauth_page"></property>
+ <property name="local_cookie_path">False</property>
+ <property name="cache_header_value">private</property>
+ <property name="log_username">True</property>
+</object>


Property changes on: CMF/trunk/CMFDefault/profiles/default/cookieauth.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: CMF/trunk/CMFDefault/profiles/default/mailhost.xml
===================================================================
--- CMF/trunk/CMFDefault/profiles/default/mailhost.xml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFDefault/profiles/default/mailhost.xml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<object name="MailHost" meta_type="Mail Host" smtp_host="localhost"
+   smtp_port="25" smtp_pwd="" smtp_uid=""/>


Property changes on: CMF/trunk/CMFDefault/profiles/default/mailhost.xml
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: CMF/trunk/CMFSetup/cookieauth.py
===================================================================
--- CMF/trunk/CMFSetup/cookieauth.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/cookieauth.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
+# 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.
@@ -10,134 +10,54 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" CMFSetup:  Mailhost import/export
+"""Cookie crumbler setup handlers.
 
 $Id$
 """
 
-from AccessControl import ClassSecurityInfo
-from AccessControl.Permission import Permission
-from Globals import InitializeClass
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from xml.dom.minidom import parseString
 
 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 ExportConfiguratorBase, ImportConfiguratorBase
-from utils import CONVERTER, DEFAULT, KEY
-
-
-#
-#   Configurator entry points
-#
 _FILENAME = 'cookieauth.xml'
 
-def importCookieCrumbler( context ):
 
-    """ Import cookiecrumbler settings from an XML file.
+def importCookieCrumbler(context):
+    """ Import cookie crumbler settings from an XML file.
     """
     site = context.getSite()
-    encoding = context.getEncoding()
+    mode = context.shouldPurge() and PURGE or UPDATE
+    cctool = getToolByName(site, 'cookie_authentication')
 
-    if context.shouldPurge():
-        # steps to follow to remove old settings
-        pass
+    body = context.readDataFile(_FILENAME)
+    if body is None:
+        return 'Cookie crumbler: Nothing to import.'
 
-    text = context.readDataFile( _FILENAME )
+    importer = INodeImporter(cctool, None)
+    if importer is None:
+        return 'Cookie crumbler: Import adapter misssing.'
 
-    if text is not None:
+    importer.importNode(parseString(body).documentElement, mode=mode)
+    return 'Cookie crumbler settings imported.'
 
-        ccc = CookieCrumblerImportConfigurator( site, encoding )
-        cc_info = ccc.parseXML( text )
-
-        # now act on the settings we've retrieved
-        cc = site.cookie_authentication
-        props = ccc.parseXML(text)
-
-        cc.auth_cookie = props['auth_cookie']
-        cc.name_cookie = props['name_cookie']
-        cc.pw_cookie = props['pw_cookie']
-        cc.persist_cookie = props['persist_cookie']
-        cc.auto_login_page = props['auto_login_page']
-        cc.logout_page = props['logout_page']
-        cc.unauth_page = props['unauth_page']
-        cc.local_cookie_path = props['local_cookie_path']
-        cc.cache_header_value = props['cache_header_value']
-        cc.log_username = props['log_username']
-
-        return 'Cookie crumbler settings imported.'
-
-
-def exportCookieCrumbler( context ):
-
-    """ Export cookiecrumbler properties as an XML file
+def exportCookieCrumbler(context):
+    """ Export cookie crumbler settings as an XML file.
     """
     site = context.getSite()
-    mhc = CookieCrumblerExportConfigurator( site ).__of__( site )
-    text = mhc.generateXML()
 
-    context.writeDataFile( _FILENAME, text, 'text/xml' )
+    cctool = getToolByName(site, 'cookie_authentication', None)
+    if cctool is None:
+        return 'Cookie crumbler: Nothing to export.'
 
-    return 'CookieCrumbler properties exported.'
+    exporter = INodeExporter(cctool)
+    if exporter is None:
+        return 'Cookie crumbler: Export adapter misssing.'
 
-
-class CookieCrumblerExportConfigurator(ExportConfiguratorBase):
-    """ Synthesize XML description of cc properties.
-    """
-    security = ClassSecurityInfo()
-
-    security.declareProtected( ManagePortal, 'getCookieCrumblerInfo' )
-    def getCookieCrumblerInfo( self ):
-        """ List the valid role IDs for our site.
-        """
-        cc = self._site.cookie_authentication
-        config = {}
-        config['auth_cookie'] = cc.auth_cookie
-        config['name_cookie'] = cc.name_cookie
-        config['pw_cookie'] = cc.pw_cookie
-        config['persist_cookie'] = cc.persist_cookie
-        config['auto_login_page'] = cc.auto_login_page
-        config['logout_page'] = cc.logout_page
-        config['unauth_page'] = cc.unauth_page
-        config['local_cookie_path'] = cc.local_cookie_path
-        config['cache_header_value'] = cc.cache_header_value
-        config['log_username'] = cc.log_username
-        return config
-
-    def _getExportTemplate(self):
-
-        return PageTemplateFile('ccExport.xml', _xmldir)
-
-
-InitializeClass(CookieCrumblerExportConfigurator)
-
-class CookieCrumblerImportConfigurator(ImportConfiguratorBase):
-
-    def _getImportMapping(self):
-
-        return {'cookiecrumbler':
-                  { 'auth_cookie': {},
-                    'name_cookie': {},
-                    'pw_cookie': {},
-                    'persist_cookie': {},
-                    'auto_login_page': {},
-                    'logout_page': {},
-                    'unauth_page': {},
-                    'local_cookie_path': {CONVERTER: self._convertToBoolean},
-                    'cache_header_value': {},
-                    'log_username': {CONVERTER: self._convertToBoolean},
-                  }
-               }
-
-InitializeClass(CookieCrumblerImportConfigurator)
-
-# BBB: will be removed in CMF 1.7
-class CookieCrumblerConfigurator(CookieCrumblerImportConfigurator,
-                                 CookieCrumblerExportConfigurator):
-    def __init__(self, site, encoding=None):
-        CookieCrumblerImportConfigurator.__init__(self, site, encoding)
-        CookieCrumblerExportConfigurator.__init__(self, site, encoding)
-
-InitializeClass(CookieCrumblerConfigurator)
-
+    doc = PrettyDocument()
+    doc.appendChild(exporter.exportNode(doc))
+    context.writeDataFile(_FILENAME, doc.toprettyxml(' '), 'text/xml')
+    return 'Cookie crumbler settings exported.'

Modified: CMF/trunk/CMFSetup/mailhost.py
===================================================================
--- CMF/trunk/CMFSetup/mailhost.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/mailhost.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
+# 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.
@@ -10,125 +10,54 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" CMFSetup:  Mailhost import/export
+"""Mailhost setup handlers.
 
 $Id$
 """
 
-from AccessControl import ClassSecurityInfo
-from AccessControl.Permission import Permission
-from Globals import InitializeClass
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from xml.dom.minidom import parseString
 
 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 ExportConfiguratorBase, ImportConfiguratorBase
-from utils import CONVERTER, DEFAULT, KEY
-
-
-#
-#   Configurator entry points
-#
 _FILENAME = 'mailhost.xml'
 
-def importMailHost( context ):
 
+def importMailHost(context):
     """ Import mailhost settings from an XML file.
     """
     site = context.getSite()
-    encoding = context.getEncoding()
+    mode = context.shouldPurge() and PURGE or UPDATE
+    mailhost = getToolByName(site, 'MailHost')
 
-    if context.shouldPurge():
-        # steps to follow to remove old settings
-        pass
+    body = context.readDataFile(_FILENAME)
+    if body is None:
+        return 'Mailhost: Nothing to import.'
 
-    text = context.readDataFile( _FILENAME )
+    importer = INodeImporter(mailhost, None)
+    if importer is None:
+        return 'Mailhost: Import adapter misssing.'
 
-    if text is not None:
-
-        mhc = MailHostImportConfigurator( site, encoding )
-        mh_info = mhc.parseXML( text )
-
-        # now act on the settings we've retrieved
-        mh = getToolByName(site, 'MailHost')
-
-        mh.smtp_host = mh_info['smtp_host']
-        mh.smtp_port = mh_info['smtp_port']
-        mh.smtp_uid = mh_info['smtp_uid']
-        mh.smtp_pwd = mh_info['smtp_pwd']
-
+    importer.importNode(parseString(body).documentElement, mode=mode)
     return 'Mailhost settings imported.'
 
-
-def exportMailHost( context ):
-
-    """ Export mailhost properties as an XML file
+def exportMailHost(context):
+    """ Export mailhost settings as an XML file.
     """
     site = context.getSite()
-    mhc = MailHostExportConfigurator( site ).__of__( site )
-    text = mhc.generateXML()
 
-    context.writeDataFile( _FILENAME, text, 'text/xml' )
+    mailhost = getToolByName(site, 'MailHost', None)
+    if mailhost is None:
+        return 'Mailhost: Nothing to export.'
 
-    return 'MailHost properties exported.'
+    exporter = INodeExporter(mailhost)
+    if exporter is None:
+        return 'Mailhost: Export adapter misssing.'
 
-
-class MailHostExportConfigurator(ExportConfiguratorBase):
-    """ Synthesize XML description of mailhost properties.
-    """
-    security = ClassSecurityInfo()
-
-    security.declareProtected( ManagePortal, 'getMailHostInfo' )
-    def getMailHostInfo( self ):
-        """ List the valid role IDs for our site.
-        """
-        mh = getToolByName(self._site, 'MailHost')
-
-        config = {}
-        config['id'] = mh.getId()
-        config['smtp_host'] = mh.smtp_host
-        config['smtp_port'] = int(mh.smtp_port)
-        config['smtp_uid'] = mh.smtp_uid
-        config['smtp_pwd'] = mh.smtp_pwd
-        config['i18n_domain'] = ''
-
-        return config
-
-    def _getExportTemplate(self):
-
-        return PageTemplateFile('mhcExport.xml', _xmldir)
-
-InitializeClass(MailHostExportConfigurator)
-
-
-class MailHostImportConfigurator(ImportConfiguratorBase):
-
-    def _getImportMapping(self):
-
-        return {
-          'mailhost':
-            { 'i18n:domain':{},
-              'id':         {},
-              'smtp_host':  {},
-              'smtp_port':  {},
-              'smtp_uid':   {},
-              'smtp_pwd':   {},
-              'xmlns:i18n': {} },
-          }
-
-InitializeClass(MailHostImportConfigurator)
-
-# BBB: will be removed in CMF 1.7
-class MailHostConfigurator(MailHostImportConfigurator
-                          ,MailHostExportConfigurator
-                          ):
-
-    def __init__(self, site, encoding=None):
-        MailHostImportConfigurator.__init__(self, site, encoding=None)
-        MailHostExportConfigurator.__init__(self, site, encoding=None)
-
-InitializeClass(MailHostConfigurator)
-
-
+    doc = PrettyDocument()
+    doc.appendChild(exporter.exportNode(doc))
+    context.writeDataFile(_FILENAME, doc.toprettyxml(' '), 'text/xml')
+    return 'Mailhost settings exported.'

Modified: CMF/trunk/CMFSetup/tests/test_cookieauth.py
===================================================================
--- CMF/trunk/CMFSetup/tests/test_cookieauth.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/tests/test_cookieauth.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
+# 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.
@@ -10,67 +10,32 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" Cookiecrumbler properties export / import unit tests.
+"""Cookie crumbler 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 zope.app.tests.placelesssetup import PlacelessSetup
 
+from Products.CMFCore.CookieCrumbler import CookieCrumbler
+
 from common import BaseRegistryTests
 from common import DummyExportContext
 from common import DummyImportContext
 
 
-_DEFAULT_EXPORT = """\
-<?xml version="1.0"?>
-<cookiecrumbler auth_cookie="__ac" cache_header_value="private"
-    name_cookie="__ac_name" log_username="1"
-    persist_cookie="__ac_persistent"
-    pw_cookie="__ac_password" local_cookie_path="0"
-    auto_login_page="login_form" unauth_page=""
-    logout_page="logged_out"/>
-"""
+class _CookieCrumblerSetup(PlacelessSetup, BaseRegistryTests):
 
-_CHANGED_EXPORT = """\
-<?xml version="1.0"?>
-<cookiecrumbler auth_cookie="value1" cache_header_value="value2"
-    name_cookie="value3" log_username="0"
-    persist_cookie="value4"
-    pw_cookie="value5" local_cookie_path="1"
-    auto_login_page="value6" unauth_page="value7"
-    logout_page="value8"/>
-"""
-
-class DummySite(Folder):
-    pass
-
-
-class DummyCookieCrumbler:
-
-    auth_cookie = '__ac'
-    cache_header_value = 'private'
-    name_cookie = '__ac_name'
-    log_username = 1
-    persist_cookie = '__ac_persistent'
-    pw_cookie = '__ac_password'
-    local_cookie_path = 0
-    auto_login_page = 'login_form'
-    unauth_page = ''
-    logout_page = 'logged_out'
-
-class _CookieCrumblerSetup(BaseRegistryTests):
-
     def _initSite(self, use_changed=False):
-
-        self.root.site = DummySite()
+        self.root.site = Folder(id='site')
         site = self.root.site
-        site.cookie_authentication = DummyCookieCrumbler()
-        cc = site.cookie_authentication
+        cc = site.cookie_authentication = CookieCrumbler('foo_cookiecrumbler')
  
         if use_changed:
             cc.auth_cookie = 'value1'
@@ -86,93 +51,91 @@
 
         return site
 
-class CookieCrumblerConfiguratorTests(_CookieCrumblerSetup):
+    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.cookieauth import CookieCrumblerConfigurator
-        return CookieCrumblerConfigurator
 
-    def test_generateXML_default( self ):
+_DEFAULT_EXPORT = """\
+<?xml version="1.0"?>
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">__ac</property>
+ <property name="name_cookie">__ac_name</property>
+ <property name="pw_cookie">__ac_password</property>
+ <property name="persist_cookie">__ac_persistent</property>
+ <property name="auto_login_page">login_form</property>
+ <property name="logout_page">logged_out</property>
+ <property name="unauth_page"></property>
+ <property name="local_cookie_path">False</property>
+ <property name="cache_header_value">private</property>
+ <property name="log_username">True</property>
+</object>
+"""
 
-        site = self._initSite()
-        configurator = self._makeOne( site ).__of__( site )
+_CHANGED_EXPORT = """\
+<?xml version="1.0"?>
+<object name="foo_cookiecrumbler" meta_type="Cookie Crumbler">
+ <property name="auth_cookie">value1</property>
+ <property name="name_cookie">value3</property>
+ <property name="pw_cookie">value5</property>
+ <property name="persist_cookie">value4</property>
+ <property name="auto_login_page">value6</property>
+ <property name="logout_page">value8</property>
+ <property name="unauth_page">value7</property>
+ <property name="local_cookie_path">True</property>
+ <property name="cache_header_value">value2</property>
+ <property name="log_username">False</property>
+</object>
+"""
 
-        self._compareDOM( configurator.generateXML(), _DEFAULT_EXPORT )
 
-    def test_generateXML_changed( self ):
+class Test_exportCookieCrumbler(_CookieCrumblerSetup):
 
-        site = self._initSite(use_changed=True)
-        configurator = self._makeOne( site ).__of__( site )
+    def test_unchanged(self):
+        from Products.CMFSetup.cookieauth import exportCookieCrumbler
 
-        self._compareDOM( configurator.generateXML(), _CHANGED_EXPORT )
+        site = self._initSite(use_changed=False)
+        context = DummyExportContext(site)
+        exportCookieCrumbler(context)
 
-    def test_parseXML_default( self ):
+        self.assertEqual(len(context._wrote), 1)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'cookieauth.xml')
+        self._compareDOM(text, _DEFAULT_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
 
-        site = self._initSite()
-        configurator = self._makeOne(site)
-        props = configurator.parseXML(_DEFAULT_EXPORT)
+    def test_changed(self):
+        from Products.CMFSetup.cookieauth import exportCookieCrumbler
 
-        self.assertEqual( props['auth_cookie'],'__ac')
-        self.assertEqual( props['cache_header_value'],'private')
-        self.assertEqual( props['name_cookie'],'__ac_name')
-        self.assertEqual( props['log_username'],1)
-        self.assertEqual( props['persist_cookie'],'__ac_persistent')
-        self.assertEqual( props['pw_cookie'],'__ac_password')
-        self.assertEqual( props['local_cookie_path'],0)
-        self.assertEqual( props['auto_login_page'],'login_form')
-        self.assertEqual( props['unauth_page'],'')
-        self.assertEqual( props['logout_page'],'logged_out')
+        site = self._initSite(use_changed=True)
+        context = DummyExportContext(site)
+        exportCookieCrumbler(context)
 
-    def test_parseXML_changed( self ):
+        self.assertEqual(len(context._wrote), 1)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'cookieauth.xml')
+        self._compareDOM(text, _CHANGED_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
 
-        site = self._initSite()
-        configurator = self._makeOne(site)
-        props = configurator.parseXML(_CHANGED_EXPORT)
 
-        self.assertEqual( props['auth_cookie'],'value1')
-        self.assertEqual( props['cache_header_value'],'value2')
-        self.assertEqual( props['name_cookie'],'value3')
-        self.assertEqual( props['log_username'],0)
-        self.assertEqual( props['persist_cookie'],'value4')
-        self.assertEqual( props['pw_cookie'],'value5')
-        self.assertEqual( props['local_cookie_path'],1)
-        self.assertEqual( props['auto_login_page'],'value6')
-        self.assertEqual( props['unauth_page'],'value7')
-        self.assertEqual( props['logout_page'],'value8')
-
-
 class Test_importCookieCrumbler(_CookieCrumblerSetup):
 
     def test_normal(self):
-        site = self._initSite()
-        context = DummyImportContext(site)
-        context._files['cookieauth.xml'] = _CHANGED_EXPORT
-
         from Products.CMFSetup.cookieauth import importCookieCrumbler
-        importCookieCrumbler(context)
 
+        site = self._initSite()
         cc = site.cookie_authentication
-        self.assertEqual( cc.auth_cookie, 'value1' )
-        self.assertEqual( cc.cache_header_value, 'value2' )
-        self.assertEqual( cc.name_cookie, 'value3' )
-        self.assertEqual( cc.log_username, 0 )
-        self.assertEqual( cc.persist_cookie, 'value4' )
-        self.assertEqual( cc.pw_cookie, 'value5' )
-        self.assertEqual( cc.local_cookie_path, 1 )
-        self.assertEqual( cc.auto_login_page, 'value6' )
-        self.assertEqual( cc.unauth_page, 'value7' )
-        self.assertEqual( cc.logout_page, 'value8' )
 
-    def test_normal_encode_as_ascii(self):
-        site = self._initSite()
-        context = DummyImportContext(site, encoding='ascii')
+        context = DummyImportContext(site)
         context._files['cookieauth.xml'] = _CHANGED_EXPORT
-
-        from Products.CMFSetup.cookieauth import importCookieCrumbler
         importCookieCrumbler(context)
 
-        cc = site.cookie_authentication
         self.assertEqual( cc.auth_cookie, 'value1' )
         self.assertEqual( cc.cache_header_value, 'value2' )
         self.assertEqual( cc.name_cookie, 'value3' )
@@ -185,38 +148,8 @@
         self.assertEqual( cc.logout_page, 'value8' )
 
 
-class Test_exportCookieCrumbler(_CookieCrumblerSetup):
-
-    def test_unchanged(self):
-        site = self._initSite( use_changed=False )
-        context = DummyExportContext(site)
-
-        from Products.CMFSetup.cookieauth import exportCookieCrumbler
-        exportCookieCrumbler(context)
-
-        self.assertEqual( len(context._wrote), 1 )
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'cookieauth.xml')
-        self._compareDOM(text, _DEFAULT_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-    def test_changed(self):
-        site = self._initSite( use_changed=True )
-        context = DummyExportContext( site )
-
-        from Products.CMFSetup.cookieauth import exportCookieCrumbler
-        exportCookieCrumbler(context)
-
-        self.assertEqual( len(context._wrote), 1 )
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'cookieauth.xml')
-        self._compareDOM(text, _CHANGED_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(CookieCrumblerConfiguratorTests),
         unittest.makeSuite(Test_exportCookieCrumbler),
         unittest.makeSuite(Test_importCookieCrumbler),
         ))

Modified: CMF/trunk/CMFSetup/tests/test_mailhost.py
===================================================================
--- CMF/trunk/CMFSetup/tests/test_mailhost.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/tests/test_mailhost.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
+# 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.
@@ -10,59 +10,31 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-""" MailHost properties export / import unit tests.
+"""Mailhost 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.MailHost.MailHost import MailHost
+from zope.app.tests.placelesssetup import PlacelessSetup
 
 from common import BaseRegistryTests
 from common import DummyExportContext
 from common import DummyImportContext
 
 
-_DEFAULT_EXPORT = """\
-<?xml version="1.0"?>
-<mailhost id="MailHost" smtp_pwd="" smtp_port="25"
-          smtp_host="localhost.localdomain" i18n:domain="" smtp_uid=""
-          xmlns:i18n="http://xml.zope.org/namespaces/i18n"/>
-"""
+class _MailHostSetup(PlacelessSetup, BaseRegistryTests):
 
-_CHANGED_EXPORT = """\
-<?xml version="1.0"?>
-<mailhost id="MailHost" smtp_pwd="value1" smtp_port="1"
-          smtp_host="value2" i18n:domain="" smtp_uid="value3"
-          xmlns:i18n="http://xml.zope.org/namespaces/i18n"/>
-"""
-
-class DummySite(Folder):
-    pass
-
-
-class DummyMailHost:
-
-    smtp_port='25'
-    smtp_host="localhost.localdomain"
-    smtp_uid=""
-    smtp_pwd=""
-    id='MailHost'
-
-    def getId(self):
-       return self.id
-
-class _MailHostSetup(BaseRegistryTests):
-
     def _initSite(self, use_changed=False):
-
-        self.root.site = DummySite()
+        self.root.site = Folder(id='site')
         site = self.root.site
-        site.MailHost = DummyMailHost()
-        mh = site.MailHost
+        mh = site.MailHost = MailHost('MailHost')
  
         if use_changed:
            mh.smtp_port='1'
@@ -70,116 +42,81 @@
            mh.smtp_host="value2"
            mh.smtp_uid="value3"
 
-
         return site
 
-class MailHostConfiguratorTests(_MailHostSetup):
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+        BaseRegistryTests.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.GenericSetup.MailHost)
 
-    def _getTargetClass(self):
+    def tearDown(self):
+        BaseRegistryTests.tearDown(self)
+        PlacelessSetup.tearDown(self)
 
-        from Products.CMFSetup.mailhost import MailHostConfigurator
-        return MailHostConfigurator
 
-    def test_generateXML_default( self ):
+_DEFAULT_EXPORT = """\
+<?xml version="1.0"?>
+<object name="MailHost" meta_type="Mail Host" smtp_host="localhost"
+   smtp_port="25" smtp_pwd="" smtp_uid=""/>
+"""
 
-        site = self._initSite()
-        configurator = self._makeOne( site ).__of__( site )
+_CHANGED_EXPORT = """\
+<?xml version="1.0"?>
+<object name="MailHost" meta_type="Mail Host" smtp_host="value2"
+   smtp_port="1" smtp_pwd="value1" smtp_uid="value3"/>
+"""
 
-        self._compareDOM( configurator.generateXML(), _DEFAULT_EXPORT )
 
-    def test_generateXML_changed( self ):
+class Test_exportMailHost(_MailHostSetup):
 
-        site = self._initSite(use_changed=True)
-        configurator = self._makeOne( site ).__of__( site )
+    def test_unchanged(self):
+        from Products.CMFSetup.mailhost import exportMailHost
 
-        self._compareDOM( configurator.generateXML(), _CHANGED_EXPORT )
+        site = self._initSite(use_changed=False)
+        context = DummyExportContext(site)
+        exportMailHost(context)
 
-    def test_parseXML_default( self ):
+        self.assertEqual(len(context._wrote), 1)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'mailhost.xml')
+        self._compareDOM(text, _DEFAULT_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
 
-        site = self._initSite()
-        configurator = self._makeOne(site)
-        props = configurator.parseXML(_DEFAULT_EXPORT)
+    def test_changed(self):
+        from Products.CMFSetup.mailhost import exportMailHost
 
-        self.assertEqual( props['smtp_port'],'25')
-        self.assertEqual( props['smtp_host'],'localhost.localdomain')
-        self.assertEqual( props['smtp_uid'],'')
-        self.assertEqual( props['smtp_pwd'],'')
+        site = self._initSite(use_changed=True)
+        context = DummyExportContext(site)
+        exportMailHost(context)
 
-    def test_parseXML_changed( self ):
+        self.assertEqual(len(context._wrote), 1)
+        filename, text, content_type = context._wrote[0]
+        self.assertEqual(filename, 'mailhost.xml')
+        self._compareDOM(text, _CHANGED_EXPORT)
+        self.assertEqual(content_type, 'text/xml')
 
-        site = self._initSite()
-        configurator = self._makeOne(site)
-        props = configurator.parseXML(_CHANGED_EXPORT)
 
-        self.assertEqual( props['smtp_pwd'], 'value1' )
-        self.assertEqual( props['smtp_host'], 'value2' )
-        self.assertEqual( props['smtp_uid'], 'value3' )
-        self.assertEqual( props['smtp_port'], '1' )
-
-
 class Test_importMailHost(_MailHostSetup):
 
     def test_normal(self):
-        site = self._initSite()
-        context = DummyImportContext(site)
-        context._files['mailhost.xml'] = _CHANGED_EXPORT
-
         from Products.CMFSetup.mailhost import importMailHost
-        importMailHost(context)
 
+        site = self._initSite()
         mh = site.MailHost
-        self.assertEqual( mh.smtp_pwd, 'value1' )
-        self.assertEqual( mh.smtp_host, 'value2' )
-        self.assertEqual( mh.smtp_uid, 'value3' )
-        self.assertEqual( mh.smtp_port, '1' )
 
-    def test_normal_encode_as_ascii(self):
-        site = self._initSite()
-        context = DummyImportContext(site, encoding='ascii')
+        context = DummyImportContext(site)
         context._files['mailhost.xml'] = _CHANGED_EXPORT
-
-        from Products.CMFSetup.mailhost import importMailHost
         importMailHost(context)
 
-        mh = site.MailHost
         self.assertEqual( mh.smtp_pwd, 'value1' )
         self.assertEqual( mh.smtp_host, 'value2' )
         self.assertEqual( mh.smtp_uid, 'value3' )
-        self.assertEqual( mh.smtp_port, '1' )
+        self.assertEqual( mh.smtp_port, 1 )
 
 
-class Test_exportMailHost(_MailHostSetup):
-
-    def test_unchanged(self):
-        site = self._initSite( use_changed=False )
-        context = DummyExportContext(site)
-
-        from Products.CMFSetup.mailhost import exportMailHost
-        exportMailHost(context)
-
-        self.assertEqual( len(context._wrote), 1 )
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'mailhost.xml')
-        self._compareDOM(text, _DEFAULT_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-    def test_changed(self):
-        site = self._initSite( use_changed=True )
-        context = DummyExportContext( site )
-
-        from Products.CMFSetup.mailhost import exportMailHost
-        exportMailHost(context)
-
-        self.assertEqual( len(context._wrote), 1 )
-        filename, text, content_type = context._wrote[0]
-        self.assertEqual(filename, 'mailhost.xml')
-        self._compareDOM(text, _CHANGED_EXPORT)
-        self.assertEqual(content_type, 'text/xml')
-
-
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(MailHostConfiguratorTests),
         unittest.makeSuite(Test_exportMailHost),
         unittest.makeSuite(Test_importMailHost),
         ))

Deleted: CMF/trunk/CMFSetup/xml/ccExport.xml
===================================================================
--- CMF/trunk/CMFSetup/xml/ccExport.xml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/xml/ccExport.xml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<cookiecrumbler xmlns:tal="http://xml.zope.org/namespaces/tal"
-    tal:define="cc_info context/getCookieCrumblerInfo"
-    tal:attributes="auth_cookie cc_info/auth_cookie;
-                    name_cookie cc_info/name_cookie;
-                    pw_cookie cc_info/pw_cookie;
-                    persist_cookie cc_info/persist_cookie;
-                    auto_login_page cc_info/auto_login_page;
-                    logout_page cc_info/logout_page;
-                    unauth_page cc_info/unauth_page;
-                    local_cookie_path cc_info/local_cookie_path;
-                    cache_header_value cc_info/cache_header_value;
-                    log_username cc_info/log_username;" />

Deleted: CMF/trunk/CMFSetup/xml/mhcExport.xml
===================================================================
--- CMF/trunk/CMFSetup/xml/mhcExport.xml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/CMFSetup/xml/mhcExport.xml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<mailhost xmlns:tal="http://xml.zope.org/namespaces/tal"
-          id="some_id"
-          tal:define="mh_info here/getMailHostInfo"
-          tal:attributes="xmlns:i18n string:http://xml.zope.org/namespaces/i18n;
-                          i18n:domain mh_info/i18n_domain;
-                          id mh_info/id;
-                          smtp_host mh_info/smtp_host;
-                          smtp_port mh_info/smtp_port;
-                          smtp_uid mh_info/smtp_uid;
-                          smtp_pwd mh_info/smtp_pwd;" />
-

Added: CMF/trunk/GenericSetup/MailHost/__init__.py
===================================================================
--- CMF/trunk/GenericSetup/MailHost/__init__.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/MailHost/__init__.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -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.
+#
+##############################################################################
+"""MailHost support.
+
+$Id$
+"""


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

Added: CMF/trunk/GenericSetup/MailHost/adapters.py
===================================================================
--- CMF/trunk/GenericSetup/MailHost/adapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/MailHost/adapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,48 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""MailHost node adapters.
+
+$Id$
+"""
+
+from Products.GenericSetup.interfaces import PURGE
+from Products.GenericSetup.utils import NodeAdapterBase
+
+from Products.MailHost.interfaces import IMailHost
+
+
+class MailHostNodeAdapter(NodeAdapterBase):
+
+    """Node im- and exporter for MailHost.
+    """
+
+    __used_for__ = IMailHost
+
+    def exportNode(self, doc):
+        """Export the object as a DOM node.
+        """
+        self._doc = doc
+        node = self._getObjectNode('object')
+        node.setAttribute('smtp_host', str(self.context.smtp_host))
+        node.setAttribute('smtp_port', str(self.context.smtp_port))
+        node.setAttribute('smtp_uid', self.context.smtp_uid)
+        node.setAttribute('smtp_pwd', self.context.smtp_pwd)
+        return node
+
+    def importNode(self, node, mode=PURGE):
+        """Import the object from the DOM node.
+        """
+        self.context.smtp_host = str(node.getAttribute('smtp_host'))
+        self.context.smtp_port = int(node.getAttribute('smtp_port'))
+        self.context.smtp_uid = node.getAttribute('smtp_uid')
+        self.context.smtp_pwd = node.getAttribute('smtp_pwd')


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

Added: CMF/trunk/GenericSetup/MailHost/configure.zcml
===================================================================
--- CMF/trunk/GenericSetup/MailHost/configure.zcml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/MailHost/configure.zcml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,17 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    >
+
+  <adapter
+      factory=".adapters.MailHostNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeExporter"
+      for="Products.MailHost.interfaces.IMailHost"
+      />
+
+  <adapter
+      factory=".adapters.MailHostNodeAdapter"
+      provides="Products.GenericSetup.interfaces.INodeImporter"
+      for="Products.MailHost.interfaces.IMailHost"
+      />
+
+</configure>


Property changes on: CMF/trunk/GenericSetup/MailHost/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: CMF/trunk/GenericSetup/MailHost/tests/__init__.py
===================================================================
--- CMF/trunk/GenericSetup/MailHost/tests/__init__.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/MailHost/tests/__init__.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -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.
+#
+##############################################################################
+"""MailHost support tests.
+
+$Id$
+"""


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

Added: CMF/trunk/GenericSetup/MailHost/tests/test_adapters.py
===================================================================
--- CMF/trunk/GenericSetup/MailHost/tests/test_adapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/MailHost/tests/test_adapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""MailHost node adapter unit tests.
+
+$Id$
+"""
+
+import unittest
+import Testing
+
+import Products.Five
+import Products.GenericSetup.MailHost
+from Products.Five import zcml
+from Products.GenericSetup.testing import NodeAdapterTestCase
+from zope.app.tests.placelesssetup import PlacelessSetup
+
+
+_MAILHOST_XML = """\
+<object name="foo_mailhost" meta_type="Mail Host" smtp_host="localhost"
+   smtp_port="25" smtp_pwd="" smtp_uid=""/>
+"""
+
+
+class MailHostNodeAdapterTests(PlacelessSetup, NodeAdapterTestCase):
+
+    def _getTargetClass(self):
+        from Products.GenericSetup.MailHost.adapters \
+                import MailHostNodeAdapter
+
+        return MailHostNodeAdapter
+
+    def setUp(self):
+        from Products.MailHost.MailHost import MailHost
+
+        PlacelessSetup.setUp(self)
+        zcml.load_config('meta.zcml', Products.Five)
+        zcml.load_config('configure.zcml', Products.GenericSetup.MailHost)
+
+        self._obj = MailHost('foo_mailhost')
+        self._XML = _MAILHOST_XML
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(MailHostNodeAdapterTests),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


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

Modified: CMF/trunk/GenericSetup/PluginIndexes/tests/test_adapters.py
===================================================================
--- CMF/trunk/GenericSetup/PluginIndexes/tests/test_adapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/PluginIndexes/tests/test_adapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -32,8 +32,8 @@
 """
 
 _DATERANGE_XML = """\
-<index name="foo_daterange" meta_type="DateRangeIndex" since_field="bar" \
-until_field="baz"/>
+<index name="foo_daterange" meta_type="DateRangeIndex" since_field="bar"
+   until_field="baz"/>
 """
 
 _FIELD_XML = """\

Modified: CMF/trunk/GenericSetup/ZCatalog/tests/test_adapters.py
===================================================================
--- CMF/trunk/GenericSetup/ZCatalog/tests/test_adapters.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/ZCatalog/tests/test_adapters.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -44,8 +44,8 @@
 %s <index name="foo_date" meta_type="DateIndex">
   <property name="index_naive_time_as_local">True</property>
  </index>
- <index name="foo_daterange" meta_type="DateRangeIndex" since_field="bar" \
-until_field="baz"/>
+ <index name="foo_daterange" meta_type="DateRangeIndex" since_field="bar"
+    until_field="baz"/>
  <index name="foo_field" meta_type="FieldIndex">
   <indexed_attr value="bar"/>
  </index>

Modified: CMF/trunk/GenericSetup/configure.zcml
===================================================================
--- CMF/trunk/GenericSetup/configure.zcml	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/configure.zcml	2005-10-05 10:44:00 UTC (rev 38762)
@@ -2,6 +2,8 @@
     xmlns="http://namespaces.zope.org/zope"
     >
 
+  <include package=".MailHost"/>
+
   <include package=".PluginIndexes"/>
 
   <include package=".ZCatalog"/>

Modified: CMF/trunk/GenericSetup/tests/test_utils.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_utils.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/tests/test_utils.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -36,10 +36,10 @@
  <property name="foo_string" type="string"></property>
  <property name="foo_text" type="text"></property>
  <property name="foo_tokens" type="tokens"/>
- <property name="foo_selection" select_variable="foobarbaz" \
-type="selection"></property>
- <property name="foo_mselection" select_variable="foobarbaz" \
-type="multiple selection"/>
+ <property name="foo_selection" select_variable="foobarbaz"
+    type="selection"></property>
+ <property name="foo_mselection" select_variable="foobarbaz"
+    type="multiple selection"/>
  <property name="foo_boolean0" type="boolean">False</property>
 </dummy>
 """
@@ -58,15 +58,15 @@
  <property name="foo_long" type="long">1</property>
  <property name="foo_string" type="string">Foo String</property>
  <property name="foo_text" type="text">Foo
-Text</property>
+  Text</property>
  <property name="foo_tokens" type="tokens">
   <element value="Foo"/>
   <element value="Tokens"/>
  </property>
- <property name="foo_selection" select_variable="foobarbaz" \
-type="selection">Foo</property>
- <property name="foo_mselection" select_variable="foobarbaz" \
-type="multiple selection">
+ <property name="foo_selection" select_variable="foobarbaz"
+    type="selection">Foo</property>
+ <property name="foo_mselection" select_variable="foobarbaz"
+    type="multiple selection">
   <element value="Foo"/>
   <element value="Baz"/>
  </property>
@@ -88,12 +88,12 @@
  <property name="foo_long">1</property>
  <property name="foo_string">Foo String</property>
  <property name="foo_text">Foo
-Text</property>
+  Text</property>
  <property name="foo_tokens">
   <element value="Foo"/>
   <element value="Tokens"/></property>
- <property name="foo_selection" type="selection" \
-select_variable="foobarbaz">Foo</property>
+ <property name="foo_selection" type="selection"
+    select_variable="foobarbaz">Foo</property>
  <property name="foo_mselection">
   <element value="Foo"/>
   <element value="Baz"/>

Modified: CMF/trunk/GenericSetup/utils.py
===================================================================
--- CMF/trunk/GenericSetup/utils.py	2005-10-05 00:15:49 UTC (rev 38761)
+++ CMF/trunk/GenericSetup/utils.py	2005-10-05 10:44:00 UTC (rev 38762)
@@ -18,7 +18,6 @@
 import os
 from inspect import getdoc
 from xml.dom.minidom import _nssplit
-from xml.dom.minidom import _write_data
 from xml.dom.minidom import Document
 from xml.dom.minidom import Element
 from xml.dom.minidom import Node
@@ -30,6 +29,7 @@
 from Acquisition import Implicit
 from Globals import InitializeClass
 from Globals import package_home
+from TAL.TALDefs import attrEscape
 from zope.interface import implements
 
 from exceptions import BadRequest
@@ -286,8 +286,38 @@
 InitializeClass(ConfiguratorBase)
 
 
-# XXX: Is there any code available in Zope that generates pretty XML? If not,
-#      this code has to be improved.
+class _LineWrapper:
+
+    def __init__(self, writer, indent, newl, max):
+        self._writer = writer
+        self._indent = indent
+        self._newl = newl
+        self._max = max
+        self._length = 0
+        self._queue = self._indent
+
+    def queue(self, text):
+        self._queue += text
+
+    def write(self, text='', enforce=False):
+        self._queue += text
+
+        if 0 < self._length > self._max - len(self._queue):
+            self._writer.write(self._newl)
+            self._length = 0
+            self._queue = '%s  %s' % (self._indent, self._queue)
+
+        if self._queue != self._indent:
+            self._writer.write(self._queue)
+            self._length += len(self._queue)
+            self._queue = ''
+
+        if 0 < self._length and enforce:
+            self._writer.write(self._newl)
+            self._length = 0
+            self._queue = self._indent
+
+
 class _Element(Element):
 
     """minidom element with 'pretty' XML output.
@@ -297,8 +327,10 @@
         # indent = current indentation
         # addindent = indentation to add to higher levels
         # newl = newline string
-        writer.write(indent+"<" + self.tagName)
+        wrapper = _LineWrapper(writer, indent, newl, 78)
+        wrapper.write('<%s' % self.tagName)
 
+        # move 'name', 'meta_type' and 'title' to the top, sort the rest 
         attrs = self._get_attributes()
         a_names = attrs.keys()
         a_names.sort()
@@ -313,25 +345,27 @@
             a_names.insert(0, 'name')
 
         for a_name in a_names:
-            writer.write(" %s=\"" % a_name)
-            _write_data(writer, attrs[a_name].value)
-            writer.write("\"")
+            wrapper.write()
+            a_value = attrEscape(attrs[a_name].value)
+            wrapper.queue(' %s="%s"' % (a_name, a_value))
+
         if self.childNodes:
-            if self.firstChild.nodeType == Node.TEXT_NODE:
-                writer.write(">")
-            else:
-                writer.write(">%s"%(newl))
+            wrapper.queue('>')
             for node in self.childNodes:
                 if node.nodeType == Node.TEXT_NODE:
-                    writer.write(node.data)
+                    textlines = node.data.splitlines()
+                    if textlines:
+                        wrapper.queue(textlines.pop(0))
+                    if textlines:
+                        for textline in textlines:
+                            wrapper.write('', True)
+                            wrapper.queue(' %s' % textline)
                 else:
-                    node.writexml(writer,indent+addindent,addindent,newl)
-            if self.lastChild.nodeType == Node.TEXT_NODE:
-                writer.write("</%s>%s" % (self.tagName,newl))
-            else:
-                writer.write("%s</%s>%s" % (indent,self.tagName,newl))
+                    wrapper.write('', True)
+                    node.writexml(writer, indent+addindent, addindent, newl)
+            wrapper.write('</%s>' % self.tagName, True)
         else:
-            writer.write("/>%s"%(newl))
+            wrapper.write('/>', True)
 
 
 class PrettyDocument(Document):
@@ -395,7 +429,8 @@
         for child in node.childNodes:
             if child.nodeName != '#text':
                 continue
-            text += child.nodeValue.lstrip()
+            lines = [ line.lstrip() for line in child.nodeValue.splitlines() ]
+            text += '\n'.join(lines)
         return text
 
     def _getNodeTextBoolean(self, node):



More information about the CMF-checkins mailing list