[CMF-checkins] SVN: CMF/trunk/ Added 'for_' argument to profile registry operations.

Tres Seaver tseaver at palladion.com
Mon Nov 21 11:49:38 EST 2005


Log message for revision 40299:
  Added 'for_' argument to profile registry operations.
  
  A profile may be registered and queried as appropriate to a specific
  site interface;  the default value, 'None', indicates that the profile
  is relevant to any site.
  
  Note that this is essentially an adapter lookup;  perhaps we should
  reimplement it so.
  
  

Changed:
  U   CMF/trunk/CHANGES.txt
  U   CMF/trunk/GenericSetup/interfaces.py
  U   CMF/trunk/GenericSetup/registry.py
  U   CMF/trunk/GenericSetup/tests/test_registry.py

-=-
Modified: CMF/trunk/CHANGES.txt
===================================================================
--- CMF/trunk/CHANGES.txt	2005-11-21 15:57:05 UTC (rev 40298)
+++ CMF/trunk/CHANGES.txt	2005-11-21 16:49:38 UTC (rev 40299)
@@ -2,6 +2,12 @@
 
   New Features
 
+    - GenericSetup:  added 'for_' argument to profile registry operations.
+      A profile may be registered and queried as appropriate to a specific
+      site interface;  the default value, 'None', indicates that the profile
+      is relevant to any site.  Note that this is essentially an adapter
+      lookup;  perhaps we should reimplement it so.
+
     - CMFTopic:  added specialized GenericSetup support for topics, to
       allow capturing criteria in a single XML file.
 

Modified: CMF/trunk/GenericSetup/interfaces.py
===================================================================
--- CMF/trunk/GenericSetup/interfaces.py	2005-11-21 15:57:05 UTC (rev 40298)
+++ CMF/trunk/GenericSetup/interfaces.py	2005-11-21 16:49:38 UTC (rev 40299)
@@ -352,7 +352,7 @@
 
     """ API for profile registry.
     """
-    def getProfileInfo( profile_id ):
+    def getProfileInfo( profile_id, for_=None ):
 
         """ Return a mapping describing a registered filesystem profile.
 
@@ -370,18 +370,36 @@
              relative (None for absolute paths).
 
           'type' -- either BASE or EXTENSION
+        
+        o 'for_', if passed, should be the interface specifying the "site
+            type" for which the profile is relevant, e.g.
+            Products.CMFCore.interfaces.ISiteRoot or
+            Products.PluggableAuthService.interfaces.IPluggableAuthService.
+            If 'None', list all profiles.
         """
 
-    def listProfiles():
+    def listProfiles( for_=None ):
 
         """ Return a list of IDs for registered profiles.
+        
+        o 'for_', if passed, should be the interface specifying the "site
+            type" for which the profile is relevant, e.g.
+            Products.CMFCore.interfaces.ISiteRoot or
+            Products.PluggableAuthService.interfaces.IPluggableAuthService.
+            If 'None', list all profiles.
         """
 
-    def listProfileInfo():
+    def listProfileInfo( for_=None ):
 
         """ Return a list of mappings describing registered profiles.
 
         o See 'getProfileInfo' for a description of the mappings' keys.
+        
+        o 'for_', if passed, should be the interface specifying the "site
+            type" for which the profile is relevant, e.g.
+            Products.CMFCore.interfaces.ISiteRoot or
+            Products.PluggableAuthService.interfaces.IPluggableAuthService.
+            If 'None', list all profiles.
         """
 
     def registerProfile( name
@@ -390,6 +408,7 @@
                        , path
                        , product=None
                        , profile_type=BASE
+                       , for_=None
                        ):
         """ Add a new profile to the registry.
 
@@ -398,6 +417,12 @@
 
         o If 'product' is passed, then 'path' should be interpreted as
           relative to the corresponding product directory.
+        
+        o 'for_', if passed, should be the interface specifying the "site
+          type" for which the profile is relevant, e.g.
+          Products.CMFCore.interfaces.ISiteRoot or
+          Products.PluggableAuthService.interfaces.IPluggableAuthService.
+          If 'None', the profile might be used in any site.
         """
 
 class ISetupTool( Interface ):

Modified: CMF/trunk/GenericSetup/registry.py
===================================================================
--- CMF/trunk/GenericSetup/registry.py	2005-11-21 15:57:05 UTC (rev 40298)
+++ CMF/trunk/GenericSetup/registry.py	2005-11-21 16:49:38 UTC (rev 40299)
@@ -531,26 +531,37 @@
         self.clear()
 
     security.declareProtected( ManagePortal, '' )
-    def getProfileInfo( self, profile_id ):
+    def getProfileInfo( self, profile_id, for_=None ):
 
         """ See IProfileRegistry.
         """
         result = self._profile_info[ profile_id ]
+        if for_ is not None:
+            if not issubclass( for_, result['for'] ):
+                raise KeyError, profile_id
         return result.copy()
 
     security.declareProtected( ManagePortal, 'listProfiles' )
-    def listProfiles( self ):
+    def listProfiles( self, for_=None ):
 
         """ See IProfileRegistry.
         """
-        return tuple( self._profile_ids )
+        result = []
+        for profile_id in self._profile_ids:
+            info = self.getProfileInfo( profile_id )
+            if for_ is None or issubclass( for_, info['for'] ):
+                result.append( profile_id )
+        return tuple( result )
 
     security.declareProtected( ManagePortal, 'listProfileInfo' )
-    def listProfileInfo( self ):
+    def listProfileInfo( self, for_=None ):
 
         """ See IProfileRegistry.
         """
-        return [ self.getProfileInfo( id ) for id in self.listProfiles() ]
+        candidates = [ self.getProfileInfo( id )
+                        for id in self.listProfiles() ]
+        return [ x for x in candidates
+                    if for_ is None or issubclass( for_, x['for'] ) ]
 
     security.declareProtected( ManagePortal, 'registerProfile' )
     def registerProfile( self
@@ -560,6 +571,7 @@
                        , path
                        , product=None
                        , profile_type=BASE
+                       , for_=None
                        ):
         """ See IProfileRegistry.
         """
@@ -575,6 +587,7 @@
                , 'path' : path
                , 'product' : product
                , 'type': profile_type
+               , 'for': for_
                }
 
         self._profile_info[ profile_id ] = info

Modified: CMF/trunk/GenericSetup/tests/test_registry.py
===================================================================
--- CMF/trunk/GenericSetup/tests/test_registry.py	2005-11-21 15:57:05 UTC (rev 40298)
+++ CMF/trunk/GenericSetup/tests/test_registry.py	2005-11-21 16:49:38 UTC (rev 40299)
@@ -23,6 +23,7 @@
 from OFS.Folder import Folder
 from Products.GenericSetup.tests.common import BaseRegistryTests
 from Products.GenericSetup import EXTENSION
+from zope.interface import Interface
 
 from conformance import ConformsToIStepRegistry
 from conformance import ConformsToIImportStepRegistry
@@ -1024,6 +1025,16 @@
 </tool-setup>
 """
 
+class ISite(Interface):
+    pass
+
+class IDerivedSite(ISite):
+    pass
+
+class IAnotherSite(Interface):
+    pass
+
+
 class ProfileRegistryTests( BaseRegistryTests
                           , ConformsToIProfileRegistry
                           ):
@@ -1071,21 +1082,86 @@
         self.assertEqual( info[ 'path' ], PATH )
         self.assertEqual( info[ 'product' ], PRODUCT )
         self.assertEqual( info[ 'type' ], PROFILE_TYPE )
+        self.assertEqual( info[ 'for' ], None )
 
     def test_registerProfile_duplicate( self ):
 
-        PROFILE_ID = 'one'
+        NAME = 'one'
         TITLE = 'One'
         DESCRIPTION = 'One profile'
         PATH = '/path/to/one'
 
         registry = self._makeOne()
-        registry.registerProfile( PROFILE_ID, TITLE, DESCRIPTION, PATH )
+        registry.registerProfile( NAME, TITLE, DESCRIPTION, PATH )
         self.assertRaises( KeyError
                          , registry.registerProfile
-                         , PROFILE_ID, TITLE, DESCRIPTION, PATH )
+                         , NAME, TITLE, DESCRIPTION, PATH )
 
 
+    def test_registerProfile_site_type( self ):
+
+        NAME = 'one'
+        TITLE = 'One'
+        DESCRIPTION = 'One profile'
+        PATH = '/path/to/one'
+        PRODUCT = 'TestProduct'
+        PROFILE_ID = 'TestProduct:one'
+        PROFILE_TYPE = EXTENSION
+        FOR = ISite
+        NOT_FOR = IAnotherSite
+        DERIVED_FOR = IDerivedSite
+
+        registry = self._makeOne()
+        registry.registerProfile( NAME
+                                , TITLE
+                                , DESCRIPTION
+                                , PATH
+                                , PRODUCT
+                                , PROFILE_TYPE
+                                , for_=FOR
+                                )
+
+
+        self.assertEqual( len( registry.listProfiles() ), 1 )
+        self.assertEqual( len( registry.listProfiles( for_=FOR ) ), 1 )
+        self.assertEqual( len( registry.listProfiles( for_=DERIVED_FOR ) )
+                        , 1 )
+        self.assertEqual( len( registry.listProfiles( for_=NOT_FOR ) )
+                        , 0 )
+
+        self.assertEqual( len( registry.listProfileInfo() ), 1 )
+        self.assertEqual( len( registry.listProfileInfo( for_=FOR ) ), 1 )
+        self.assertEqual( len( registry.listProfileInfo( for_=DERIVED_FOR ) )
+                        , 1 )
+        self.assertEqual( len( registry.listProfileInfo( for_=NOT_FOR ) )
+                        , 0 )
+
+        # Verify that these lookups succeed...
+        info1 = registry.getProfileInfo( PROFILE_ID )
+        info2 = registry.getProfileInfo( PROFILE_ID, for_=FOR )
+        info3 = registry.getProfileInfo( PROFILE_ID, for_=DERIVED_FOR )
+
+        self.assertEqual(info1, info2)
+        self.assertEqual(info1, info3)
+
+        # ...and that this one fails.
+        self.assertRaises( KeyError
+                         , registry.getProfileInfo
+                         , PROFILE_ID
+                         , for_=NOT_FOR
+                         )
+
+        info = registry.getProfileInfo( PROFILE_ID , for_=FOR )
+
+        self.assertEqual( info[ 'id' ], PROFILE_ID )
+        self.assertEqual( info[ 'title' ], TITLE )
+        self.assertEqual( info[ 'description' ], DESCRIPTION )
+        self.assertEqual( info[ 'path' ], PATH )
+        self.assertEqual( info[ 'product' ], PRODUCT )
+        self.assertEqual( info[ 'type' ], PROFILE_TYPE )
+        self.assertEqual( info[ 'for' ], FOR )
+
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite( ImportStepRegistryTests ),



More information about the CMF-checkins mailing list