[Checkins] SVN: grok/trunk/src/grok/ Added an event to Grok. This event, called ApplicationInitializedEvent.

Souheil CHELFOUH souheil at chelfouh.com
Thu Oct 8 16:35:08 EDT 2009


Log message for revision 104952:
  Added an event to Grok. This event, called ApplicationInitializedEvent.
  This event is supposed to be fired after the persistence of the site.
  It allows to use handlers, at the application creation, that need to be sure they can access the local utilities.
  Added a test to demonstrate the behavior.
  

Changed:
  U   grok/trunk/src/grok/__init__.py
  A   grok/trunk/src/grok/events.py
  A   grok/trunk/src/grok/ftests/events/
  A   grok/trunk/src/grok/ftests/events/__init__.py
  A   grok/trunk/src/grok/ftests/events/application_init.py
  U   grok/trunk/src/grok/ftests/test_grok_functional.py
  U   grok/trunk/src/grok/interfaces.py

-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2009-10-08 20:19:18 UTC (rev 104951)
+++ grok/trunk/src/grok/__init__.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -77,6 +77,7 @@
     ObjectRemovedEvent,
     ContainerModifiedEvent)
 
+from grok.events import ApplicationInitializedEvent
 from grok.components import Model, View
 from grok.components import XMLRPC, REST, JSON
 from grok.components import Traverser
@@ -85,6 +86,7 @@
 from grok.components import Indexes
 from grok.components import Role
 from grok.interfaces import IRESTSkinType, IRESTLayer
+from grok.interfaces import IApplicationInitializedEvent
 
 from grok.directive import (
     permissions, site, restskin, traversable)

Added: grok/trunk/src/grok/events.py
===================================================================
--- grok/trunk/src/grok/events.py	                        (rev 0)
+++ grok/trunk/src/grok/events.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2006-2007 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.
+#
+##############################################################################
+"""Events for Grok application components.
+
+The events described here are *not* trigged by Grok itself. They are
+conveniently provided to be used in your own application.
+
+"""
+from grok import interfaces
+from zope.interface import implements
+
+
+class ApplicationInitializedEvent(object):
+    """A Grok Application has been created and is now ready to be used.
+    """
+    implements(interfaces.IApplicationInitializedEvent)
+
+    def __init__(self, app):
+        assert interfaces.IApplication.providedBy(app)
+        self.object = app

Added: grok/trunk/src/grok/ftests/events/__init__.py
===================================================================
--- grok/trunk/src/grok/ftests/events/__init__.py	                        (rev 0)
+++ grok/trunk/src/grok/ftests/events/__init__.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -0,0 +1 @@
+# this is a package

Added: grok/trunk/src/grok/ftests/events/application_init.py
===================================================================
--- grok/trunk/src/grok/ftests/events/application_init.py	                        (rev 0)
+++ grok/trunk/src/grok/ftests/events/application_init.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -0,0 +1,86 @@
+"""
+==========================
+Application initialization
+==========================
+
+The application initialization is an important moment of your
+application's life. This creation process is responsible for the
+local utilities and the catalog indexes' creation. Let's create a site
+to demonstrate the different steps.
+
+  >>> root = getRootFolder()
+
+The life cycle of an application is made of 2 major events :
+ObjectCreatedEvent and ObjectAddedEvent.
+
+ObjectCreatedEvent shoud be triggered when an application is
+instanciated. At this step, the application doesn't have a site
+manager yet.
+  
+  >>> site = Herd()
+  >>> notify(grok.ObjectCreatedEvent(site))
+  >>> setSite(site)
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: no site manager defined
+
+As the application is instanciated and notified as "created", we can
+now persist it. This operation will fire the "ObjectAddedEvent". This
+event is trigged by the container and the associated event handlers
+will create the site manager. Once the site manager is created, Grok's
+subscribers will create the local utilities and the indexes.
+
+This particular step is often used to trigger the creation of
+content. However, as the event handlers are not ordered, we can not be
+sure that our handler will be called after the local utilities
+creation. This can be quite annoying : the content created by our
+handler may not be regitered in the Catalog and the IntIds utility.
+
+To demonstrate this behavior, we now persist the application. This
+will trigger a test handler that queries the Catalog::
+
+  >>> root['site'] = site
+  Catalog can not be found !
+
+Now our application is persisted, the site manager and the local
+utilities are created. We can safely use our application. An event is
+provided by Grok, to be fired at this step. The same test event shows
+that we can now work on an operational environment:
+
+  >>> notify(grok.ApplicationInitializedEvent(site))
+  <zope.app.catalog.catalog.Catalog object at ...>
+
+"""
+import grok
+from grok import index
+from zope.event import notify
+from zope.schema import TextLine
+from zope.interface import Interface
+from zope.component import queryUtility
+from zope.app.component.hooks import setSite
+from zope.app.catalog.interfaces import ICatalog
+
+
+class Herd(grok.Container, grok.Application):
+    pass
+
+
+class IPachyderm(Interface):
+    tusks = TextLine(title = u"About the tusks")
+
+
+class TuskIndex(grok.Indexes):
+    grok.context(IPachyderm)
+    grok.site(Herd)
+
+    tusks = index.Text()
+
+
+ at grok.subscribe(Herd, grok.IObjectAddedEvent)
+ at grok.subscribe(Herd, grok.IApplicationInitializedEvent)
+def CatalogTester(application, event):
+    catalog = queryUtility(ICatalog, context=application)
+    if catalog is None:
+        print "Catalog can not be found !"
+    else:
+        print catalog

Modified: grok/trunk/src/grok/ftests/test_grok_functional.py
===================================================================
--- grok/trunk/src/grok/ftests/test_grok_functional.py	2009-10-08 20:19:18 UTC (rev 104951)
+++ grok/trunk/src/grok/ftests/test_grok_functional.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -71,7 +71,7 @@
 def test_suite():
     suite = unittest.TestSuite()
     for name in ['xmlrpc', 'traversal', 'form', 'url', 'security',
-                 'catalog', 'site', 'rest', 'viewlet','json']:
+                 'catalog', 'site', 'rest', 'viewlet', 'json', 'events']:
         suite.addTest(suiteFromPackage(name))
     return suite
 

Modified: grok/trunk/src/grok/interfaces.py
===================================================================
--- grok/trunk/src/grok/interfaces.py	2009-10-08 20:19:18 UTC (rev 104951)
+++ grok/trunk/src/grok/interfaces.py	2009-10-08 20:35:08 UTC (rev 104952)
@@ -15,6 +15,7 @@
 """
 from zope import interface
 from zope.interface.interfaces import IInterface
+from zope.component.interfaces import IObjectEvent
 from zope.publisher.interfaces.http import IHTTPRequest
 from zope.app.container.interfaces import IContainer as IContainerBase
 
@@ -98,6 +99,11 @@
 
     IBeforeTraverseEvent = interface.Attribute("")
 
+    IApplicationInitializedEvent = interface.Attribute("")
+
+    ApplicationInitializedEvent = interface.Attribute("")
+
+
 class IGrokAPI(grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
                grokcore.security.interfaces.IGrokcoreSecurityAPI,
                grokcore.site.interfaces.IGrokcoreSiteAPI,
@@ -213,3 +219,11 @@
     `grok.Permission` and `grok.require` settings however, will be
     applied to such views.
     """
+
+class IApplicationInitializedEvent(IObjectEvent):
+    """A Grok Application has been created with success and is now ready
+    to be used.
+
+    This event can be used to trigger the creation of contents or other tasks
+    that require the application to be fully operational : utilities installed
+    and indexes created in the catalog."""



More information about the checkins mailing list