[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/OFS/Folder - Folder.py:1.1.2.10 FolderLimit.py:1.1.4.4 LoadedFolder.py:1.1.4.4

Gary Poster garyposter@earthlink.net
Mon, 29 Apr 2002 19:20:33 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/OFS/Folder
In directory cvs.zope.org:/tmp/cvs-serv1556/App/OFS/Folder

Modified Files:
      Tag: Zope-3x-branch
	Folder.py FolderLimit.py LoadedFolder.py 
Log Message:
ComponentArchitecture reorganization; addition of for_container; addition of IWriteContainer.isAddable.

good news: all tests pass; bad news: after the new security system, my changes have some problems.  I had to punt on the default contents view of all folders for instance--hasServiceManager is causing a problem for some reason I couldn't divine, even with Shane's Checker tool.  I commented out the offending code on the contents.pt just to keep things up.

I tagged before committing: gary_CA-reorganization

changes more in depth (as I understand it, all or most approved :-) ):

(in ComponentArchitecture:)
 * changing implementation names to Global* (i.e., AdapterService becomes 
GlobalAdapterService) and giving each its own file (many are clumped together 
in hooks.py)
 * removing hooks.py in ComponentArchitecture, putting all functions in appropriate module above (i.e. getAdapter will be in the adapter module)
 * largely removing indirection (_hook) except for getService and 
getNextService
 * changing IServiceService.py to IServiceManager
 * changing Service.py to GlobalServiceManager.py (and class name too)
 * removing "provide*" functions (i.e., provideAdapter, provideUtility, etc.) 
and "defineService" from the __init__.py imports
 * change all global services to classes with appropriate methods as per 
interfaces
 * update all tests 
 * remove all of the "provide*" functions from the interfaces
 * renamed IComponentArchitecture to IPlacefulComponentArchitecture (hereafter IPCA), after long discussion with SteveA 
 * list Resources as one of core CA services in IPlacefulComponentArchitecture
 * build actual IPCA interface, not just import of service interfaces (because we want IPCA to be placeful, but the service interfaces do not need to be)
 * place functions implementing ICA actually in __init__
 * explicitly setting up services in zcml
 * created Global service interfaces, and placed the "provides" and "set" and "define" functions there: however, to keep the main interfaces clean and clear, I placed these global interfaces in the same file as the global implementations, hoping to clarify that these are not reusable interfaces but descriptive, one-time interfaces
 * built PlacefulSetup in Zope.ComponentArchitecture.tests for more specific CleanUp (a subclass).  PlacefulSetup is in the tests folder of the local ServiceManager.  AddableSetup also is available, in the AddableService tests.

(elsewhere in Zope3)
 * built for_container in addables
 * built isAddable for containers (after discussion with Jim, we decided an addable "contains" attribute in the zcml might not be the way to go.  I chose the isAddable approach for a number of reasons)
 * addableservice does some more checks in getting the addable list, pertinent to the above and to whether it can find the appropriate factories
 * a few more tests: a start of one in the local event service, and some more here and there

I'm sorry to add to the confusion of the big security changes, but I needed to either trash these changes or commit them: I'm a bit out of time for the moment.  If all else fails, again, I did tag the previous version.



=== Zope3/lib/python/Zope/App/OFS/Folder/Folder.py 1.1.2.9 => 1.1.2.10 ===
 from types import StringTypes
 
+from Zope.App.OFS.Container.Exceptions import UnaddableError
+
 _marker = object()
 
 class IFolder(IContainer, IServiceManagerContainer):
@@ -82,6 +84,8 @@
         """Add the given object to the folder under the given name."""
         if type(name) in StringTypes and len(name)==0:
             raise ValueError
+        if not self.isAddable(getattr(object,'__implements__', None)):
+            raise UnaddableError (self, object, name)
         self.data[name] = object
 
     def delObject(self, name):
@@ -89,5 +93,6 @@
            if the object is not found."""
         del self.data[name]
 
-        
+    def isAddable(self, interfaces):
+        return 1
 


=== Zope3/lib/python/Zope/App/OFS/Folder/FolderLimit.py 1.1.4.3 => 1.1.4.4 ===
 
 from Zope.App.OFS.Container.IContainerLimit import IContainerLimit
+from Zope.App.OFS.Container.Exceptions import UnaddableError
 
 
-class FolderLimitExeededError(Exception):
+class FolderLimitExceededError(UnaddableError):
     """Exception that is raised, when the limit of the folder was
        reached."""
     pass


=== Zope3/lib/python/Zope/App/OFS/Folder/LoadedFolder.py 1.1.4.3 => 1.1.4.4 ===
 
 - Define what content objects can be added (user)
+  (* notice isAddable; adding an interfaces service could make
+  this functionality more usable TTW)
   + add the option to the configuration zpt
   + how does the security work for this? like if this folder is
     created under a folder that doesnt allow images for example?
@@ -33,10 +35,26 @@
 """
 
 from Folder import Folder, IFolder
-from FolderLimit import FolderLimit, FolderLimitExeededError
+from FolderLimit import FolderLimit, FolderLimitExceededError
 from OrderedFolder import OrderedFolder
 from types import StringTypes
 
+from Zope.App.OFS.Container.Exceptions import UnaddableError
+
+
+def membership_check(group, item): # use later for more interesting isAddable implementations
+    if type(group) is tuple:
+        for inter in group:
+            if membership_check(inter, item):
+                return 1
+        return 0
+    if type(item) is tuple:
+        for inter in item:
+            if membership_check(group, inter):
+                return 1
+        return 0
+    return group is item or issubclass(item, group)
+
 
 class ILoadedFolder(IFolder):
     """The standard Zope Loaded Folder object interface."""
@@ -91,8 +109,12 @@
         """Add the given object to the folder under the given name."""
         if type(name) in StringTypes and len(name)==0:
             raise ValueError
+        if not self.isAddable(getattr(object,'__implements__', None)):
+            raise UnaddableError (self, object, name)
         if self.isLimitReached():
-            raise FolderLimitExeededError, 'The folder\'s limit was exeeded.' 
+            raise FolderLimitExceededError(self, object,
+                       'The folder\'s limit (%d item%s) was exeeded.' %
+                       (self.getLimit(), self.getLimit()==1 and "" or "s" ))
         else:
             self.data[name] = object
             if name not in self._orderedIds:
@@ -106,3 +128,6 @@
         ids = list(self._orderedIds)
         ids.remove(name)
         self._orderedIds = tuple(ids)
+
+    def isAddable(self, interfaces):
+        return 1 # could return 0 if self.isLimitReached(), and eliminate check above...