[Checkins] SVN: grok/trunk/src/grok/ Added a `create_application` function that creates an application, going through all the needed events.

Souheil CHELFOUH souheil at chelfouh.com
Fri Oct 9 11:28:31 EDT 2009


Log message for revision 104972:
  Added a `create_application` function that creates an application, going through all the needed events.
  Added a test for that new feature and corrected a bit the previous ones, to get a coherent naming and text.
  

Changed:
  D   grok/trunk/src/grok/ftests/lifecycle/application_init.py
  A   grok/trunk/src/grok/ftests/lifecycle/create_application.py
  A   grok/trunk/src/grok/ftests/lifecycle/lifecycle_events.py
  U   grok/trunk/src/grok/util.py

-=-
Deleted: grok/trunk/src/grok/ftests/lifecycle/application_init.py
===================================================================
--- grok/trunk/src/grok/ftests/lifecycle/application_init.py	2009-10-09 15:27:34 UTC (rev 104971)
+++ grok/trunk/src/grok/ftests/lifecycle/application_init.py	2009-10-09 15:28:31 UTC (rev 104972)
@@ -1,86 +0,0 @@
-"""
-==========================
-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

Added: grok/trunk/src/grok/ftests/lifecycle/create_application.py
===================================================================
--- grok/trunk/src/grok/ftests/lifecycle/create_application.py	                        (rev 0)
+++ grok/trunk/src/grok/ftests/lifecycle/create_application.py	2009-10-09 15:28:31 UTC (rev 104972)
@@ -0,0 +1,69 @@
+"""
+====================
+Application creation
+====================
+
+The application creation can be handled by Grok. In order to setup a
+functional application, the creation method will go through all the
+needed events : ObjectCreated, ObjectAdded, ApplicationInitialized.
+
+Let's create our environment. We are at the zope instance root folder.
+
+  >>> root = getRootFolder()
+
+In this folder, we want our Cave applicate. To create it, Grok
+provides a convenient function called `create_application`::
+
+  >>> import grok.util
+  >>> app = grok.util.create_application(Cave, root, 'mycave')
+  Cave <zope.app.event.objectevent.ObjectCreatedEvent object at ...>
+  Cave <zope.app.container.contained.ObjectAddedEvent object at ...>
+  Cave <grok.events.ApplicationInitializedEvent object at ...>
+
+As we can see, the events are effectively trigged, and in the right
+order. The function returns the persisted application method.
+
+  >>> print app
+  <grok.ftests.lifecycle.application_creation.Cave object at ...>
+  >>> print app.__parent__
+  <zope.app.folder.folder.Folder object at ...>
+
+However, if an error occur during the creation process, the exception
+is not caught by `create_application`.
+
+In the case we provide an id that already exists, the exception will
+be raised *BEFORE* the application instanciation. For this reason, and
+intentionally, no event will be trigged.
+
+  >>> app = grok.util.create_application(Cave, root, 'mycave')
+  Traceback (most recent call last):
+  ...
+  DuplicationError: mycave
+
+Please note that the `create_application` function will only accept
+factories implementing IApplication::
+
+  >>> james = grok.util.create_application(Mammoth, root, 'james')
+  Traceback (most recent call last):
+  ...
+  WrongType: <class 'grok.ftests.lifecycle.application_creation.Mammoth'>
+
+"""
+import grok
+
+
+class Mammoth(grok.Model):
+    """A furry creature with tusks.
+    """
+    pass
+
+class Cave(grok.Container, grok.Application):
+    """A shelter for the homeless cavemen.
+    """
+    pass
+
+ at grok.subscribe(Cave, grok.IObjectCreatedEvent)
+ at grok.subscribe(Cave, grok.IObjectAddedEvent)
+ at grok.subscribe(Cave, grok.IApplicationInitializedEvent)
+def EventPrinter(application, event):
+    print application.__class__.__name__, event

Copied: grok/trunk/src/grok/ftests/lifecycle/lifecycle_events.py (from rev 104967, grok/trunk/src/grok/ftests/lifecycle/application_init.py)
===================================================================
--- grok/trunk/src/grok/ftests/lifecycle/lifecycle_events.py	                        (rev 0)
+++ grok/trunk/src/grok/ftests/lifecycle/lifecycle_events.py	2009-10-09 15:28:31 UTC (rev 104972)
@@ -0,0 +1,86 @@
+"""
+==============================
+Application lifecycle overview
+==============================
+
+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


Property changes on: grok/trunk/src/grok/ftests/lifecycle/lifecycle_events.py
___________________________________________________________________
Added: svn:mergeinfo
   + 

Modified: grok/trunk/src/grok/util.py
===================================================================
--- grok/trunk/src/grok/util.py	2009-10-09 15:27:34 UTC (rev 104971)
+++ grok/trunk/src/grok/util.py	2009-10-09 15:28:31 UTC (rev 104972)
@@ -13,12 +13,17 @@
 ##############################################################################
 """Grok utility functions.
 """
+import grok
+import zope.event
 import zope.location.location
 from zope import interface
+from zope.schema.interfaces import WrongType
+from zope.exceptions.interfaces import DuplicationError
 from zope.security.checker import NamesChecker, defineChecker
 
 from grokcore.security.util import check_permission
 
+
 def make_checker(factory, view_factory, permission, method_names=None):
     """Make a checker for a view_factory associated with factory.
 
@@ -35,6 +40,7 @@
         checker = NamesChecker(method_names, permission)
     defineChecker(view_factory, checker)
 
+
 def safely_locate_maybe(obj, parent, name):
     """Set an object's __parent__ (and __name__) if the object's
     __parent__ attribute doesn't exist yet or is None.
@@ -47,6 +53,7 @@
     # This either sets __parent__ or wraps 'obj' in a LocationProxy
     return zope.location.location.located(obj, parent, name)
 
+
 def applySkin(request, skin, skin_type):
     """Change the presentation skin for this request.
     """
@@ -56,3 +63,31 @@
     # Add the new skin.
     ifaces.append(skin)
     interface.directlyProvides(request, *ifaces)
+
+
+def create_application(factory, container, name):
+    """Creates an application and triggers the events from
+    the application lifecycle.
+    """
+    # Check the factory.
+    if not grok.interfaces.IApplication.implementedBy(factory):
+        raise WrongType(factory)
+
+    # Check the availability of the name in the container.
+    if name in container:
+        raise DuplicationError(name)
+
+    # Instanciate the application
+    application = factory()
+
+    # Trigger the creation event.
+    grok.notify(grok.ObjectCreatedEvent(application))
+
+    # Persist the application.
+    # This may raise a DuplicationError.
+    container[name] = application
+
+    # Trigger the initialization event.
+    grok.notify(grok.ApplicationInitializedEvent(application))
+
+    return application



More information about the checkins mailing list