[Checkins] SVN: Sandbox/faassen/grokcore.site/trunk/src/grokcore/ Move everything into site subpackage.

Martijn Faassen faassen at infrae.com
Fri Oct 17 13:02:25 EDT 2008


Log message for revision 92328:
  Move everything into site subpackage.
  

Changed:
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftests/
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftests/
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/tests/
  A   Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/tests/
  D   Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py

-=-
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,87 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grok
-"""
-from zope.interface import implements
-from zope.component import adapts
-
-from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
-from martian import baseclass
-from martian.error import GrokError, GrokImportError
-
-from grokcore.component import Adapter, MultiAdapter, GlobalUtility, Context
-from grokcore.component.decorators import subscribe, adapter, implementer
-from grokcore.component.directive import (
-    context, name, title, description, provides, global_utility, direct)
-
-from grokcore.security import Permission
-from grokcore.security import Public
-from grokcore.security import require
-
-from grokcore.view import PageTemplate
-from grokcore.view import PageTemplateFile
-from grokcore.view import DirectoryResource
-from grokcore.view import layer
-from grokcore.view import template
-from grokcore.view import templatedir
-from grokcore.view import skin
-from grokcore.view import url
-from grokcore.view import path
-
-from grokcore.formlib import action
-from grokcore.formlib import AutoFields
-from grokcore.formlib import Fields
-
-from zope.event import notify
-from zope.app.component.hooks import getSite
-from zope.lifecycleevent import (
-    IObjectCreatedEvent, ObjectCreatedEvent,
-    IObjectModifiedEvent, ObjectModifiedEvent,
-    IObjectCopiedEvent, ObjectCopiedEvent)
-
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-
-from zope.app.container.contained import (
-    IObjectAddedEvent, ObjectAddedEvent,
-    IObjectMovedEvent, ObjectMovedEvent,
-    IObjectRemovedEvent, ObjectRemovedEvent,
-    IContainerModifiedEvent, ContainerModifiedEvent)
-
-from grok.components import Model, View
-from grok.components import XMLRPC, REST, JSON
-from grok.components import Traverser
-from grok.components import Container, OrderedContainer
-from grok.components import Site, LocalUtility, Annotation
-from grok.components import Application, Form, AddForm, EditForm, DisplayForm
-from grok.components import Indexes
-from grok.components import Role
-from grok.components import RESTProtocol, IRESTLayer
-from grok.interfaces import IRESTSkinType
-from grok.components import ViewletManager, Viewlet
-
-from grok.directive import (local_utility, permissions, site,
-                            viewletmanager, view, traversable, order)
-
-
-
-# BBB These two functions are meant for test fixtures and should be
-# imported from grok.testing, not from grok.
-from grok.testing import grok, grok_component
-
-# Our __init__ provides the grok API directly so using 'import grok' is enough.
-from grok.interfaces import IGrokAPI
-from zope.interface import moduleProvides
-moduleProvides(IGrokAPI)
-__all__ = list(IGrokAPI)

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,402 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grok components"""
-
-import persistent
-import simplejson
-
-import zope.location
-from zope import component
-from zope import interface
-from zope.securitypolicy.role import Role
-from zope.publisher.browser import BrowserPage
-from zope.publisher.interfaces import NotFound
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.publisher.publish import mapply
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-from zope.app.publisher.browser import getDefaultViewName
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-from zope.app.container.interfaces import IReadContainer, IObjectAddedEvent
-from zope.app.container.interfaces import IOrderedContainer
-from zope.app.container.contained import notifyContainerModified
-from persistent.list import PersistentList
-from zope.app.component.site import SiteManagerContainer
-from zope.app.component.site import LocalSiteManager
-
-from zope.viewlet.manager import ViewletManagerBase
-from zope.viewlet.viewlet import ViewletBase
-
-import grok
-import z3c.flashmessage.interfaces
-import martian.util
-
-import grokcore.view
-import grokcore.formlib
-from grok import interfaces, util
-
-
-class Model(Contained, persistent.Persistent):
-    # XXX Inheritance order is important here. If we reverse this,
-    # then containers can't be models anymore because no unambigous MRO
-    # can be established.
-    interface.implements(IAttributeAnnotatable, interfaces.IContext)
-
-
-class Container(BTreeContainer):
-    interface.implements(IAttributeAnnotatable, interfaces.IContainer)
-
-
-class OrderedContainer(Container):
-    interface.implements(IOrderedContainer)
-
-    def __init__(self):
-        super(OrderedContainer, self).__init__()
-        self._order = PersistentList()
-
-    def keys(self):
-        # Return a copy of the list to prevent accidental modifications.
-        return self._order[:]
-
-    def __iter__(self):
-        return iter(self.keys())
-
-    def values(self):
-        return (self[key] for key in self._order)
-
-    def items(self):
-        return ((key, self[key]) for key in self._order)
-
-    def __setitem__(self, key, object):
-        foo = self.has_key(key)
-        # Then do whatever containers normally do.
-        super(OrderedContainer, self).__setitem__(key, object)
-        if not foo:
-            self._order.append(key)
-
-    def __delitem__(self, key):
-        # First do whatever containers normally do.
-        super(OrderedContainer, self).__delitem__(key)
-        self._order.remove(key)
-
-    def updateOrder(self, order):
-        if set(order) != set(self._order):
-            raise ValueError("Incompatible key set.")
-
-        self._order = PersistentList()
-        self._order.extend(order)
-        notifyContainerModified(self)
-
-
-class Site(SiteManagerContainer):
-    pass
-
- at component.adapter(Site, IObjectAddedEvent)
-def addSiteHandler(site, event):
-    sitemanager = LocalSiteManager(site)
-    # LocalSiteManager creates the 'default' folder in its __init__.
-    # It's not needed anymore in new versions of Zope 3, therefore we
-    # remove it
-    del sitemanager['default']
-    site.setSiteManager(sitemanager)
-
-
-class Application(Site):
-    """A top-level application object."""
-    interface.implements(interfaces.IApplication)
-
-
-class LocalUtility(Model):
-    pass
-
-
-class Annotation(persistent.Persistent):
-    pass
-
-
-class View(grokcore.view.View):
-    interface.implements(interfaces.IGrokView)
-
-    def application_url(self, name=None):
-        obj = self.context
-        while obj is not None:
-            if isinstance(obj, Application):
-                return self.url(obj, name)
-            obj = obj.__parent__
-        raise ValueError("No application found.")
-
-    def flash(self, message, type='message'):
-        source = component.getUtility(
-            z3c.flashmessage.interfaces.IMessageSource, name='session')
-        source.send(message, type)
-
-
-class Form(grokcore.formlib.Form, View):
-    interface.implements(interfaces.IGrokForm)
-
-
-class AddForm(grokcore.formlib.AddForm, View):
-    interface.implements(interfaces.IGrokForm)
-
-
-class DisplayForm(grokcore.formlib.DisplayForm, View):
-    interface.implements(interfaces.IGrokForm)
-
-
-class EditForm(grokcore.formlib.EditForm, View):
-    interface.implements(interfaces.IGrokForm)
-
-
-class XMLRPC(object):
-    pass
-
-class REST(zope.location.Location):
-    interface.implements(interfaces.IREST)
-
-    def __init__(self, context, request):
-        self.context = self.__parent__ = context
-        self.request = request
-        self.body = request.bodyStream.getCacheStream().read()
-
-    @property
-    def response(self):
-        return self.request.response
-
-##     def GET(self):
-##         raise GrokMethodNotAllowed(self.context, self.request)
-
-##     def POST(self):
-##         raise GrokMethodNotAllowed(self.context, self.request)
-
-##     def PUT(self):
-##         raise GrokMethodNotAllowed(self.context, self.request)
-
-##     def DELETE(self):
-##         raise GrokMethodNotAllowed(self.context, self.request)
-
-class JSON(BrowserPage):
-
-    def __call__(self):
-        view_name = self.__view_name__
-        method = getattr(self, view_name)
-        method_result = mapply(method, (), self.request)
-        return simplejson.dumps(method_result)
-
-
-class Traverser(object):
-    interface.implements(IBrowserPublisher)
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-
-    def browserDefault(self, request):
-        # if we have a RESTful request, we will handle
-        # GET, POST and HEAD differently (PUT and DELETE are handled already
-        # but not on the BrowserRequest layer but the HTTPRequest layer)
-        if IRESTLayer.providedBy(request):
-            rest_view = component.getMultiAdapter(
-                (self.context, self.request),
-                name=request.method)
-            return rest_view, ()
-        view_name = getDefaultViewName(self.context, request)
-        view_uri = "@@%s" % view_name
-        return self.context, (view_uri,)
-
-    def publishTraverse(self, request, name):
-        subob = self.traverse(name)
-        if subob is not None:
-            return util.safely_locate_maybe(subob, self.context, name)
-
-        traversable_dict = grok.traversable.bind().get(self.context)
-        if traversable_dict:
-            if name in traversable_dict:
-                subob = getattr(self.context, traversable_dict[name])
-                if callable(subob):
-                    subob = subob()
-                return util.safely_locate_maybe(subob, self.context, name)
-
-        # XXX Special logic here to deal with containers.  It would be
-        # good if we wouldn't have to do this here. One solution is to
-        # rip this out and make you subclass ContainerTraverser if you
-        # wanted to override the traversal behaviour of containers.
-        if IReadContainer.providedBy(self.context):
-            item = self.context.get(name)
-            if item is not None:
-                return item
-
-        view = component.queryMultiAdapter((self.context, request), name=name)
-        if view is not None:
-            return view
-
-        raise NotFound(self.context, name, request)
-
-    def traverse(self, name):
-        # this will be overridden by subclasses
-        pass
-
-
-class ContextTraverser(Traverser):
-    component.adapts(interfaces.IContext, IHTTPRequest)
-
-    def traverse(self, name):
-        traverse = getattr(self.context, 'traverse', None)
-        if traverse:
-            return traverse(name)
-
-
-class ContainerTraverser(Traverser):
-    component.adapts(interfaces.IContainer, IHTTPRequest)
-
-    def traverse(self, name):
-        traverse = getattr(self.context, 'traverse', None)
-        if traverse:
-            result = traverse(name)
-            if result is not None:
-                return result
-        # try to get the item from the container
-        return self.context.get(name)
-
-
-class IndexesClass(object):
-    def __init__(self, name, bases=(), attrs=None):
-        if attrs is None:
-            return
-        indexes = {}
-        for name, value in attrs.items():
-            # Ignore everything that's not an index definition object
-            # except for values set by directives
-            if '.' in name:
-                setattr(self, name, value)
-                continue
-            if not interfaces.IIndexDefinition.providedBy(value):
-                continue
-            indexes[name] = value
-        self.__grok_indexes__ = indexes
-        # __grok_module__ is needed to make defined_locally() return True for
-        # inline templates
-        self.__grok_module__ = martian.util.caller_module()
-
-Indexes = IndexesClass('Indexes')
-
-
-class Role(Role):
-    pass
-
-class IRESTLayer(IBrowserRequest):
-    pass
-
-class RESTProtocol(object):
-    pass
-
-class ViewletManager(ViewletManagerBase):
-    interface.implements(interfaces.IViewletManager)
-
-    template = None
-
-    def __init__(self, context, request, view):
-        super(ViewletManager, self).__init__(context, request, view)
-        self.context = context
-        self.request = request
-        self.view = view
-        self.__name__ = self.__view_name__
-        self.static = component.queryAdapter(
-            self.request,
-            interface.Interface,
-            name=self.module_info.package_dotted_name
-            )
-
-    def sort(self, viewlets):
-        """Sort the viewlets.
-
-        ``viewlets`` is a list of tuples of the form (name, viewlet).
-        """
-        # In Grok, the default order of the viewlets is determined by
-        # util.sort_components. util.sort_components() however expects
-        # a list of just components, but sort() is supposed to deal
-        # with a list of (name, viewlet) tuples.
-        # To handle this situation we first store the name part on the
-        # viewlet, then use util.sort_components() and then "unpack"
-        # the name from the viewlet and recreate the list of (name,
-        # viewlet) tuples, now in the correct order.
-        s_viewlets = []
-        for name, viewlet in viewlets:
-             # Stuff away viewlet name so we can later retrieve it.
-             # XXX We loose name information in case the same viewlet
-             # is in the viewlets list twice, but with a different
-             # name. Most probably this situation doesn't occur.
-             viewlet.__viewlet_name__ = name
-             s_viewlets.append(viewlet)
-        s_viewlets = util.sort_components(s_viewlets)
-        return [(viewlet.__viewlet_name__, viewlet) for viewlet in s_viewlets]
-
-    def default_namespace(self):
-        namespace = {}
-        namespace['context'] = self.context
-        namespace['request'] = self.request
-        namespace['static'] = self.static
-        namespace['view'] = self.view
-        namespace['viewletmanager'] = self
-        return namespace
-
-    def namespace(self):
-        return {}
-
-    def render(self):
-        """See zope.contentprovider.interfaces.IContentProvider"""
-        # Now render the view
-        if self.template:
-            return self.template.render(self)
-        else:
-            return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
-
-
-class Viewlet(ViewletBase):
-    """Batteries included viewlet.
-    """
-
-    def __init__(self, context, request, view, manager):
-        super(Viewlet, self).__init__(context, request, view, manager)
-        self.context = context
-        self.request = request
-        self.view = view
-        self.viewletmanager = manager
-        self.__name__ = self.__view_name__
-        self.static = component.queryAdapter(
-            self.request,
-            interface.Interface,
-            name=self.module_info.package_dotted_name
-            )
-
-    def default_namespace(self):
-        namespace = {}
-        namespace['context'] = self.context
-        namespace['request'] = self.request
-        namespace['static'] = self.static
-        namespace['view'] = self.view
-        namespace['viewlet'] = self
-        namespace['viewletmanager'] = self.manager
-        return namespace
-
-    def namespace(self):
-        return {}
-
-    def update(self):
-        pass
-
-    def render(self):
-        return self.template.render(self)

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,84 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser"
-    xmlns:grok="http://namespaces.zope.org/grok">
-
-  <include package="zope.security" file="meta.zcml" />
-  <include package="zope.i18n" file="meta.zcml" />
-  <include package="zope.securitypolicy" file="meta.zcml" />
-  <include package="zope.app.zcmlfiles" file="meta.zcml" />
-  <include package="grok" file="meta.zcml" />
-
-  <include package="zope.annotation" />
-  <include package="zope.copypastemove" />
-  <include package="zope.contentprovider" />
-  <include package="zope.formlib" />
-  <include package="zope.i18n.locales" />
-  <include package="zope.publisher" />
-  <include package="zope.securitypolicy" />
-  <include package="zope.size" />
-  <include package="zope.traversing" />
-  <include package="zope.traversing.browser" />
-  <include package="zope.app.zcmlfiles" />
-  <include package="zope.app.authentication" />
-  <include package="zope.app.intid" />
-  <include package="zope.app.keyreference" />
-  <include package="zope.app.catalog" />
-  <include package="zope.app.renderer" />
-  <include package="zope.app.session" />
-
-  <include package="grokcore.view" />
-  <include package="grokcore.formlib" />
-
-  <securityPolicy
-      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
-
-  <adapter factory=".components.ContextTraverser" />
-  <adapter factory=".components.ContainerTraverser" />
-
-  <browser:defaultView
-      for=".interfaces.IContext"
-      name="index"
-      />
-
-  <subscriber handler=".components.addSiteHandler" />
-
-  <!-- we register a ++rest++ traversal namespace -->
-  <adapter
-      factory=".rest.rest_skin"
-      for="* zope.publisher.interfaces.browser.IHTTPRequest"
-      provides="zope.traversing.interfaces.ITraversable"
-      name="rest"
-      />
-
-  <!-- this overrides Zope 3's publication factories because they have
-       the same name; we also need to change the priority because of
-       the ZCML discriminator -->
-  <publisher
-      name="XMLRPC"
-      factory=".publication.GrokXMLRPCFactory"
-      methods="POST"
-      mimetypes="text/xml"
-      priority="21"
-      />
-
-  <publisher
-      name="BROWSER"
-      factory=".publication.GrokBrowserFactory"
-      methods="GET POST HEAD"
-      mimetypes="*"
-      priority="11"
-      />
-
-  <publisher
-      name="HTTP"
-      factory=".publication.GrokHTTPFactory"
-      methods="*"
-      mimetypes="*"
-      priority="1"
-      />
-
-  <!-- need to grok this for some basic REST support -->
-  <grok:grok package=".rest" />
-
-</configure>

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,143 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grok directives.
-"""
-
-import sys
-import grok
-from zope import interface
-from zope.interface.interfaces import IInterface
-from zope.interface.interface import TAGGED_DATA
-
-from zope.publisher.interfaces.browser import IBrowserView
-
-import martian
-from martian import util
-from martian.error import GrokImportError, GrokError
-from martian.directive import StoreOnce, StoreMultipleTimes
-from grokcore.component.scan import UnambiguousComponentScope
-from grok import components
-
-class local_utility(martian.Directive):
-    scope = martian.CLASS
-    store = martian.DICT
-
-    def factory(self, factory, provides=None, name=u'',
-                setup=None, public=False, name_in_container=None):
-        if provides is not None and not IInterface.providedBy(provides):
-            raise GrokImportError("You can only pass an interface to the "
-                                  "provides argument of %s." % self.name)
-
-        if provides is None:
-            provides = grok.provides.bind().get(factory)
-
-        if provides is None:
-            if util.check_subclass(factory, grok.LocalUtility):
-                baseInterfaces = interface.implementedBy(grok.LocalUtility)
-                utilityInterfaces = interface.implementedBy(factory)
-                provides = list(utilityInterfaces - baseInterfaces)
-
-                if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
-                    raise GrokImportError(
-                        "Cannot determine which interface to use "
-                        "for utility registration of %r. "
-                        "It implements an interface that is a specialization "
-                        "of an interface implemented by grok.LocalUtility. "
-                        "Specify the interface by either using grok.provides "
-                        "on the utility or passing 'provides' to "
-                        "grok.local_utility." % factory, factory)
-            else:
-                provides = list(interface.implementedBy(factory))
-
-            util.check_implements_one_from_list(provides, factory)
-            provides = provides[0]
-
-        if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
-            raise GrokImportError(
-                "Conflicting local utility registration %r. "
-                "Local utilities are registered multiple "
-                "times for interface %r and name %r." %
-                (factory, provides, name), factory)
-
-        info = LocalUtilityInfo(factory, provides, name, setup, public,
-                                name_in_container)
-        return (provides, name), info
-
-
-class LocalUtilityInfo(object):
-
-    _order = 0
-
-    def __init__(self, factory, provides, name=u'',
-                 setup=None, public=False, name_in_container=None):
-        self.factory = factory
-        self.provides = provides
-        self.name = name
-        self.setup = setup
-        self.public = public
-        self.name_in_container = name_in_container
-
-        self.order = LocalUtilityInfo._order
-        LocalUtilityInfo._order += 1
-
-    def __cmp__(self, other):
-        # LocalUtilityInfos have an inherit sort order by which the
-        # registrations take place.
-        return cmp(self.order, other.order)
-
-
-class site(martian.Directive):
-    scope = martian.CLASS
-    store = martian.ONCE
-    validate = martian.validateInterfaceOrClass
-
-class permissions(martian.Directive):
-    scope = martian.CLASS
-    store = martian.ONCE
-    default = []
-
-    def factory(*args):
-        return args
-
-class OneInterfaceOrClassOnClassOrModule(martian.Directive):
-    """Convenience base class.  Not for public use."""
-    scope = martian.CLASS_OR_MODULE
-    store = martian.ONCE
-    validate = martian.validateInterfaceOrClass
-
-class viewletmanager(OneInterfaceOrClassOnClassOrModule):
-    scope = UnambiguousComponentScope('viewletmanager')
-
-class view(OneInterfaceOrClassOnClassOrModule):
-    default = IBrowserView
-
-class traversable(martian.Directive):
-    scope = martian.CLASS
-    store = martian.DICT
-
-    def factory(self, attr, name=None):
-        if name is None:
-            name = attr
-        return (name, attr)
-
-class order(martian.Directive):
-    scope = martian.CLASS
-    store = martian.ONCE
-    default = 0, 0
-
-    _order = 0
-
-    def factory(self, value=0):
-        order._order += 1
-        return value, order._order

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,35 +0,0 @@
-<configure
-   xmlns="http://namespaces.zope.org/zope"
-   xmlns:grok="http://namespaces.zope.org/grok"
-   i18n_domain="grok"
-   package="grok"
-   >
-
-  <include package="grok" />
-  <grok:grok package="grok.ftests" />
-
-  <securityPolicy
-      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
-      />
-
-  <unauthenticatedPrincipal
-      id="zope.anybody"
-      title="Unauthenticated User"
-      />
-  <grant
-      permission="zope.View"
-      principal="zope.anybody"
-      />
-
-  <principal
-      id="zope.mgr"
-      title="Manager"
-      login="mgr"
-      password="mgrpw"
-      />
-
-  <role id="zope.Manager" title="Site Manager" />
-  <grantAll role="zope.Manager" />
-  <grant role="zope.Manager" principal="zope.mgr" />
-
-</configure>

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,75 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2007-2008 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.
-#
-##############################################################################
-"""Grok index definitions
-"""
-import sys
-
-from zope.interface import implements
-from zope.interface.interfaces import IMethod, IInterface
-
-from zope.app.catalog.field import FieldIndex
-from zope.app.catalog.text import TextIndex
-from zc.catalog.catalogindex import SetIndex
-
-from martian.error import GrokError, GrokImportError
-from martian.util import frame_is_class
-
-from grok.interfaces import IIndexDefinition
-
-class IndexDefinition(object):
-    implements(IIndexDefinition)
-
-    index_class = None
-
-    def __init__(self, *args, **kw):
-        frame = sys._getframe(1)
-        if not frame_is_class(frame):
-            raise GrokImportError(
-                "%r can only be instantiated on class level." % self.__class__)
-        # store any extra parameters to pass to index later
-        self._args = args
-        self._attribute = kw.pop('attribute', None)
-        self._kw = kw
-
-    def setup(self, catalog, name, context, module_info):
-        if self._attribute is not None:
-            field_name = self._attribute
-        else:
-            field_name = name
-
-        if IInterface.providedBy(context):
-            try:
-                method = context[field_name]
-            except KeyError:
-                raise GrokError("grok.Indexes in %r refers to an attribute or "
-                                "method %r on interface %r, but this does not "
-                                "exist." % (module_info.getModule(),
-                                            field_name, context), None)
-            call = IMethod.providedBy(method)
-        else:
-            call = callable(getattr(context, field_name, None))
-            context = None # no interface lookup
-        catalog[name] = self.index_class(field_name=field_name,
-                                         interface=context,
-                                         field_callable=call,
-                                         *self._args, **self._kw)
-
-class Field(IndexDefinition):
-    index_class = FieldIndex
-
-class Text(IndexDefinition):
-    index_class = TextIndex
-
-class Set(IndexDefinition):
-    index_class = SetIndex

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,234 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grok interfaces
-"""
-from zope import interface, schema
-from zope.formlib.interfaces import reConstraint
-from zope.interface.interfaces import IInterface
-from zope.viewlet.interfaces import IViewletManager as IViewletManagerBase
-from zope.app.container.interfaces import IContainer as IContainerBase
-
-import grokcore.component.interfaces
-import grokcore.formlib.interfaces
-import grokcore.security.interfaces
-import grokcore.view.interfaces
-
-# Expose interfaces from grokcore.* packages as well:
-from grokcore.component.interfaces import IContext
-from grokcore.component.interfaces import IGrokErrors
-from grokcore.view.interfaces import ITemplateFileFactory
-from grokcore.view.interfaces import ITemplate
-
-
-class IGrokBaseClasses(grokcore.component.interfaces.IBaseClasses,
-                       grokcore.security.interfaces.IBaseClasses,
-                       grokcore.view.interfaces.IBaseClasses):
-    Model = interface.Attribute("Base class for persistent content objects "
-                                "(models).")
-    Container = interface.Attribute("Base class for containers.")
-    OrderedContainer = interface.Attribute("Base class for ordered containers.")
-    Site = interface.Attribute("Mixin class for sites.")
-    Application = interface.Attribute("Base class for applications.")
-    Annotation = interface.Attribute("Base class for persistent annotations.")
-    LocalUtility = interface.Attribute("Base class for local utilities.")
-    XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
-    JSON = interface.Attribute("Base class for JSON methods.")
-    REST = interface.Attribute("Base class for REST views.")
-    Traverser = interface.Attribute("Base class for custom traversers.")
-    Indexes = interface.Attribute("Base class for catalog index definitions.")
-    ViewletManager = interface.Attribute("Base class for viewletmanager.")
-    Viewlet = interface.Attribute("Base class for viewlet.")
-    Role = interface.Attribute("Base class for roles.")
-
-
-class IGrokDirectives(grokcore.component.interfaces.IDirectives,
-                      grokcore.security.interfaces.IDirectives,
-                      grokcore.view.interfaces.IDirectives):
-
-    def local_utility(factory, provides=None, name=u'',
-                      setup=None, public=False, name_in_container=None):
-        """Register a local utility.
-
-        factory - the factory that creates the local utility
-        provides - the interface the utility should be looked up with
-        name - the name of the utility
-        setup - a callable that receives the utility as its single argument,
-                it is called after the utility has been created and stored
-        public - if False, the utility will be stored below ++etc++site
-                 if True, the utility will be stored directly in the site.
-                 The site should in this case be a container.
-        name_in_container - the name to use for storing the utility
-        """
-
-    def permissions(permissions):
-        """Specify the permissions that comprise a role.
-        """
-
-    def site(class_or_interface):
-        """Specifies the site that an indexes definition is for.
-
-        It can only be used inside grok.Indexes subclasses.
-        """
-
-    def order(value=None):
-        """Control the ordering of components.
-
-        If the value is specified, the order will be determined by sorting on
-        it.
-        If no value is specified, the order will be determined by definition
-        order within the module.
-        If the directive is absent, the order will be determined by class name.
-        (unfortunately our preferred default behavior on absence which would
-        be like grok.order() without argument is hard to implement in Python)
-
-        Inter-module order is by dotted name of the module the
-        components are in; unless an explicit argument is specified to
-        ``grok.order()``, components are grouped by module.
-
-        The function grok.util.sort_components can be used to sort
-        components according to these rules.
-        """
-
-
-class IGrokEvents(interface.Interface):
-
-    IObjectCreatedEvent = interface.Attribute("")
-
-    ObjectCreatedEvent = interface.Attribute("")
-
-    IObjectModifiedEvent = interface.Attribute("")
-
-    ObjectModifiedEvent = interface.Attribute("")
-
-    IObjectCopiedEvent = interface.Attribute("")
-
-    ObjectCopiedEvent = interface.Attribute("")
-
-    IObjectAddedEvent = interface.Attribute("")
-
-    ObjectAddedEvent = interface.Attribute("")
-
-    IObjectMovedEvent = interface.Attribute("")
-
-    ObjectMovedEvent = interface.Attribute("")
-
-    IObjectRemovedEvent = interface.Attribute("")
-
-    ObjectRemovedEvent = interface.Attribute("")
-
-    IContainerModifiedEvent = interface.Attribute("")
-
-    ContainerModifiedEvent = interface.Attribute("")
-
-
-class IGrokAPI(grokcore.security.interfaces.IGrokcoreSecurityAPI,
-               grokcore.view.interfaces.IGrokcoreViewAPI,
-               grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
-               IGrokBaseClasses, IGrokDirectives, 
-               IGrokEvents, IGrokErrors):
-
-    # BBB this is deprecated
-    def grok(dotted_name):
-        """Grok a module or package specified by ``dotted_name``.
-
-        NOTE: This function will be removed from the public Grok
-        public API.  For tests and interpreter sessions, use
-        grok.testing.grok().
-        """
-
-    # BBB this is deprecated
-    def grok_component(name, component, context=None, module_info=None,
-                       templates=None):
-        """Grok an arbitrary object. Can be useful during testing.
-
-        name - the name of the component (class name, or global instance name
-               as it would appear in a module).
-        component - the object (class, etc) to grok.
-        context - the context object (optional).
-        module_info - the module being grokked (optional).
-        templates - the templates registry (optional).
-
-        Note that context, module_info and templates might be required
-        for some grokkers which rely on them.
-
-        NOTE: This function will be removed from the public Grok
-        public API.  For tests and interpreter sessions, use
-        grok.testing.grok_component().
-        """
-
-    def notify(event):
-        """Send ``event`` to event subscribers."""
-
-    def getSite():
-        """Get the current site."""
-
-
-    IRESTSkinType = interface.Attribute('The REST skin type')
-
-
-class IGrokView(grokcore.view.interfaces.IGrokView):
-    """Grok views all provide this interface."""
-
-    def application_url(name=None):
-        """Return the URL of the closest application object in the
-        hierarchy or the URL of a named object (``name`` parameter)
-        relative to the closest application object.
-        """
-
-    def flash(message, type='message'):
-        """Send a short message to the user."""
-
-
-class IGrokForm(grokcore.formlib.interfaces.IGrokForm, IGrokView):
-    """All Grok forms provides this interface."""
-
-
-class IREST(interface.Interface):
-    context = interface.Attribute("Object that the REST handler presents.")
-
-    request = interface.Attribute("Request that REST handler was looked"
-                                  "up with.")
-
-    body = interface.Attribute(
-        """The text of the request body.""")
-
-class IApplication(interface.Interface):
-    """Marker-interface for grok application factories.
-
-    Used to register applications as utilities to look them up and
-    provide a list of grokked applications.
-    """
-
-class IIndexDefinition(interface.Interface):
-    """Define an index for grok.Indexes.
-    """
-
-    def setup(catalog, name, context):
-        """Set up index called name in given catalog.
-
-        Use name for index name and attribute to index. Set up
-        index for interface or class context.
-        """
-
-class IRESTSkinType(IInterface):
-    """Skin type for REST requests.
-    """
-
-class IContainer(IContext, IContainerBase):
-    """A Grok container.
-    """
-
-class IViewletManager(IViewletManagerBase):
-    """The Grok viewlet manager.
-    """

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,537 +0,0 @@
-#############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grokkers for the various components."""
-
-import zope.component.interface
-from zope import interface, component
-from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
-                                               IBrowserRequest,
-                                               IBrowserPublisher)
-from zope.publisher.interfaces.http import IHTTPRequest
-
-from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
-from zope.viewlet.interfaces import IViewletManager, IViewlet
-from zope.securitypolicy.interfaces import IRole
-from zope.securitypolicy.rolepermission import rolePermissionManager
-
-from zope.annotation.interfaces import IAnnotations
-
-from zope.app.publisher.xmlrpc import MethodPublisher
-from zope.app.container.interfaces import IContainer
-from zope.app.container.interfaces import INameChooser
-from zope.app.container.contained import contained
-
-from zope.app.intid import IntIds
-from zope.app.intid.interfaces import IIntIds
-from zope.app.catalog.catalog import Catalog
-from zope.app.catalog.interfaces import ICatalog
-
-from zope.exceptions.interfaces import DuplicationError
-
-import martian
-from martian.error import GrokError
-from martian import util
-
-import grok
-from grok import components
-from grok.util import make_checker
-from grok.interfaces import IRESTSkinType
-from grok.interfaces import IViewletManager as IGrokViewletManager
-
-from grokcore.component.scan import determine_module_component
-from grokcore.security.meta import PermissionGrokker
-
-from grokcore.view.meta.views import (
-    default_view_name, default_fallback_to_name)
-
-
-def default_annotation_provides(factory, module, **data):
-    base_interfaces = interface.implementedBy(grok.Annotation)
-    factory_interfaces = interface.implementedBy(factory)
-    real_interfaces = list(factory_interfaces - base_interfaces)
-    util.check_implements_one_from_list(real_interfaces, factory)
-    return real_interfaces[0]
-
-def default_annotation_name(factory, module, **data):
-    return factory.__module__ + '.' + factory.__name__
-
-
-class ViewletManagerContextGrokker(martian.GlobalGrokker):
-
-    martian.priority(1001)
-
-    def grok(self, name, module, module_info, config, **kw):
-        viewletmanager = determine_module_component(module_info,
-                                                    grok.viewletmanager,
-                                                    IGrokViewletManager)
-        grok.viewletmanager.set(module, viewletmanager)
-        return True
-
-
-class XMLRPCGrokker(martian.MethodGrokker):
-    martian.component(grok.XMLRPC)
-    martian.directive(grok.context)
-    martian.directive(grok.require, name='permission')
-
-    def execute(self, factory, method, config, context, permission, **kw):
-        name = method.__name__
-
-        # Make sure that the class inherits MethodPublisher, so that the
-        # views have a location
-        method_view = type(
-            factory.__name__, (factory, MethodPublisher),
-            {'__call__': method}
-            )
-
-        adapts = (context, IXMLRPCRequest)
-        config.action(
-            discriminator=('adapter', adapts, interface.Interface, name),
-            callable=component.provideAdapter,
-            args=(method_view, adapts, interface.Interface, name),
-            )
-        config.action(
-            discriminator=('protectName', method_view, '__call__'),
-            callable=make_checker,
-            args=(factory, method_view, permission),
-            )
-        return True
-
-
-class RESTGrokker(martian.MethodGrokker):
-    martian.component(grok.REST)
-    martian.directive(grok.context)
-    martian.directive(grok.layer, default=grok.IRESTLayer)
-    martian.directive(grok.require, name='permission')
-
-    def execute(self, factory, method, config, permission, context, layer, **kw):
-        name = method.__name__
-
-        method_view = type(
-            factory.__name__, (factory,),
-            {'__call__': method }
-            )
-
-        adapts = (context, layer)
-        config.action(
-            discriminator=('adapter', adapts, interface.Interface, name),
-            callable=component.provideAdapter,
-            args=(method_view, adapts, interface.Interface, name),
-            )
-        config.action(
-            discriminator=('protectName', method_view, '__call__'),
-            callable=make_checker,
-            args=(factory, method_view, permission),
-            )
-        return True
-
-
-class JSONGrokker(martian.MethodGrokker):
-    martian.component(grok.JSON)
-    martian.directive(grok.context)
-    martian.directive(grok.require, name='permission')
-
-    # TODO: this grokker doesn't support layers yet
-
-    def execute(self, factory, method, config, context, permission, **kw):
-        # Create a new class with a __view_name__ attribute so the
-        # JSON class knows what method to call.
-        method_view = type(
-            factory.__name__, (factory,),
-            {'__view_name__': method.__name__}
-            )
-        adapts = (context, IDefaultBrowserLayer)
-        name = method.__name__
-
-        config.action(
-            discriminator=('adapter', adapts, interface.Interface, name),
-            callable=component.provideAdapter,
-            args=(method_view, adapts, interface.Interface, name),
-            )
-        config.action(
-            discriminator=('protectName', method_view, '__call__'),
-            callable=make_checker,
-            args=(factory, method_view, permission),
-            )
-        return True
-
-
-class TraverserGrokker(martian.ClassGrokker):
-    martian.component(grok.Traverser)
-    martian.directive(grok.context)
-
-    def execute(self, factory, config, context, **kw):
-        adapts = (context, IHTTPRequest)
-        config.action(
-            discriminator=('adapter', adapts, IBrowserPublisher, ''),
-            callable=component.provideAdapter,
-            args=(factory, adapts, IBrowserPublisher),
-            )
-        return True
-
-
-class SiteGrokker(martian.ClassGrokker):
-    martian.component(grok.Site)
-    martian.priority(500)
-    martian.directive(grok.local_utility, name='infos')
-
-    def execute(self, factory, config, infos, **kw):
-        if not infos:
-            return False
-
-        infos = infos.values()
-        for info in infos:
-            if info.public and not IContainer.implementedBy(factory):
-                raise GrokError(
-                    "Cannot set public to True with grok.local_utility as "
-                    "the site (%r) is not a container." %
-                    factory, factory)
-
-        # Store the list of info objects in their "natural" order on the
-        # site class. They will be picked up by a subscriber doing the
-        # actual registrations in definition order.
-        factory.__grok_utilities_to_install__ = sorted(infos)
-        adapts = (factory, grok.IObjectAddedEvent)
-
-        config.action(
-            discriminator=None,
-            callable=component.provideHandler,
-            args=(localUtilityRegistrationSubscriber, adapts),
-            )
-        return True
-
-
-def localUtilityRegistrationSubscriber(site, event):
-    """A subscriber that fires to set up local utilities.
-    """
-    installed = getattr(site, '__grok_utilities_installed__', False)
-    if installed:
-        return
-
-    for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
-        setupUtility(site, info.factory(), info.provides, name=info.name,
-                     name_in_container=info.name_in_container,
-                     public=info.public, setup=info.setup)
-
-    # we are done. If this subscriber gets fired again, we therefore
-    # do not register utilities anymore
-    site.__grok_utilities_installed__ = True
-
-
-def setupUtility(site, utility, provides, name=u'',
-                 name_in_container=None, public=False, setup=None):
-    """Set up a utility in a site.
-
-    site - the site to set up the utility in
-    utility - the utility to set up
-    provides - the interface the utility should be registered with
-    name - the name the utility should be registered under, default
-      the empty string (no name)
-    name_in_container - if given it will be used to add the utility
-      object to its container. Otherwise a name will be made up
-    public - if False, the utility will be stored in the site manager. If
-      True, the utility will be storedin the site (it is assumed the
-      site is a container)
-    setup - if not None, it will be called with the utility as its first
-       argument. This function can then be used to further set up the
-       utility.
-    """
-    site_manager = site.getSiteManager()
-
-    if not public:
-        container = site_manager
-    else:
-        container = site
-
-    if name_in_container is None:
-        name_in_container = INameChooser(container).chooseName(
-            utility.__class__.__name__, utility)
-    container[name_in_container] = utility
-
-    if setup is not None:
-        setup(utility)
-
-    site_manager.registerUtility(utility, provided=provides,
-                                 name=name)
-
-
-class RoleGrokker(martian.ClassGrokker):
-    martian.component(grok.Role)
-    martian.priority(martian.priority.bind().get(PermissionGrokker()) - 1)
-    martian.directive(grok.name)
-    martian.directive(grok.title, get_default=default_fallback_to_name)
-    martian.directive(grok.description)
-    martian.directive(grok.permissions)
-
-    def execute(self, factory, config, name, title, description,
-                permissions, **kw):
-        if not name:
-            raise GrokError(
-                "A role needs to have a dotted name for its id. Use "
-                "grok.name to specify one.", factory)
-        # We can safely convert to unicode, since the directives makes sure
-        # it is either unicode already or ASCII.
-        role = factory(unicode(name), unicode(title), unicode(description))
-
-        config.action(
-            discriminator=('utility', IRole, name),
-            callable=component.provideUtility,
-            args=(role, IRole, name),
-            )
-
-        for permission in permissions:
-            config.action(
-                discriminator=('grantPermissionToRole', permission, name),
-                callable=rolePermissionManager.grantPermissionToRole,
-                args=(permission, name),
-                )
-        return True
-
-
-class AnnotationGrokker(martian.ClassGrokker):
-    martian.component(grok.Annotation)
-    martian.directive(grok.context, name='adapter_context')
-    martian.directive(grok.provides, get_default=default_annotation_provides)
-    martian.directive(grok.name, get_default=default_annotation_name)
-
-    def execute(self, factory, config, adapter_context, provides, name, **kw):
-        @component.adapter(adapter_context)
-        @interface.implementer(provides)
-        def getAnnotation(context):
-            annotations = IAnnotations(context)
-            try:
-                result = annotations[name]
-            except KeyError:
-                result = factory()
-                annotations[name] = result
-
-            # Containment has to be set up late to allow containment
-            # proxies to be applied, if needed. This does not trigger
-            # an event and is idempotent if containment is set up
-            # already.
-            contained_result = contained(result, context, name)
-            return contained_result
-
-        config.action(
-            discriminator=('adapter', adapter_context, provides, ''),
-            callable=component.provideAdapter,
-            args=(getAnnotation,),
-            )
-        return True
-
-
-class ApplicationGrokker(martian.ClassGrokker):
-    martian.component(grok.Application)
-    martian.priority(500)
-
-    def grok(self, name, factory, module_info, config, **kw):
-        # XXX fail loudly if the same application name is used twice.
-        provides = grok.interfaces.IApplication
-        name = '%s.%s' % (module_info.dotted_name, name)
-        config.action(
-            discriminator=('utility', provides, name),
-            callable=component.provideUtility,
-            args=(factory, provides, name),
-            )
-        return True
-
-
-class IndexesGrokker(martian.InstanceGrokker):
-    martian.component(components.IndexesClass)
-
-    def grok(self, name, factory, module_info, config, **kw):
-        site = grok.site.bind().get(factory)
-        context = grok.context.bind().get(factory, module_info.getModule())
-        catalog_name = grok.name.bind().get(factory)
-
-        if site is None:
-            raise GrokError("No site specified for grok.Indexes "
-                            "subclass in module %r. "
-                            "Use grok.site() to specify."
-                            % module_info.getModule(),
-                            factory)
-        indexes = getattr(factory, '__grok_indexes__', None)
-        if indexes is None:
-            return False
-
-        subscriber = IndexesSetupSubscriber(catalog_name, indexes,
-                                            context, module_info)
-        subscribed = (site, grok.IObjectAddedEvent)
-        config.action(
-            discriminator=None,
-            callable=component.provideHandler,
-            args=(subscriber, subscribed),
-            )
-        return True
-
-
-class IndexesSetupSubscriber(object):
-
-    def __init__(self, catalog_name, indexes, context, module_info):
-        self.catalog_name = catalog_name
-        self.indexes = indexes
-        self.context = context
-        self.module_info = module_info
-
-    def __call__(self, site, event):
-        # make sure we have an intids
-        self._createIntIds(site)
-        # get the catalog
-        catalog = self._createCatalog(site)
-        # now install indexes
-        for name, index in self.indexes.items():
-            try:
-                index.setup(catalog, name, self.context, self.module_info)
-            except DuplicationError:
-                raise GrokError(
-                    "grok.Indexes in module %r causes "
-                    "creation of catalog index %r in catalog %r, "
-                    "but an index with that name is already present." %
-                    (self.module_info.getModule(), name, self.catalog_name),
-                    None)
-
-    def _createCatalog(self, site):
-        """Create the catalog if needed and return it.
-
-        If the catalog already exists, return that.
-
-        """
-        catalog = zope.component.queryUtility(
-            ICatalog, name=self.catalog_name, context=site, default=None)
-        if catalog is not None:
-            return catalog
-        catalog = Catalog()
-        setupUtility(site, catalog, ICatalog, name=self.catalog_name)
-        return catalog
-
-    def _createIntIds(self, site):
-        """Create intids if needed, and return it.
-        """
-        intids = zope.component.queryUtility(
-            IIntIds, context=site, default=None)
-        if intids is not None:
-            return intids
-        intids = IntIds()
-        setupUtility(site, intids, IIntIds)
-        return intids
-
-
-class RESTProtocolGrokker(martian.ClassGrokker):
-    martian.component(grok.RESTProtocol)
-    martian.directive(grok.layer, default=IBrowserRequest)
-    martian.directive(grok.name, get_default=default_view_name)
-
-    def execute(self, factory, config, name, layer, **kw):
-        config.action(
-            discriminator=('restprotocol', name),
-            callable=zope.component.interface.provideInterface,
-            args=(name, layer, IRESTSkinType)
-            )
-        return True
-
-class ViewletManagerGrokker(martian.ClassGrokker):
-    martian.component(grok.ViewletManager)
-    martian.directive(grok.context)
-    martian.directive(grok.layer, default=IDefaultBrowserLayer)
-    martian.directive(grok.view)
-    martian.directive(grok.name)
-
-    def grok(self, name, factory, module_info, **kw):
-        # Need to store the module info object on the view class so that it
-        # can look up the 'static' resource directory.
-        factory.module_info = module_info
-        return super(ViewletManagerGrokker, self).grok(
-            name, factory, module_info, **kw)
-
-    def execute(self, factory, config, context, layer, view, name, **kw):
-        # This will be used to support __name__ on the viewlet manager
-        factory.__view_name__ = name
-
-        # find templates
-        templates = factory.module_info.getAnnotation('grok.templates', None)
-        if templates is not None:
-            config.action(
-                discriminator=None,
-                callable=self.checkTemplates,
-                args=(templates, factory.module_info, factory)
-                )
-
-        config.action(
-            discriminator = ('viewletManager', context, layer, view, name),
-            callable = component.provideAdapter,
-            args = (factory, (context, layer, view), IViewletManager, name)
-            )
-        return True
-
-    def checkTemplates(self, templates, module_info, factory):
-        def has_render(factory):
-            return factory.render != grok.components.ViewletManager.render
-        def has_no_render(factory):
-            # always has a render method
-            return False
-        templates.checkTemplates(module_info, factory, 'viewlet manager',
-                                 has_render, has_no_render)
-
-class ViewletGrokker(martian.ClassGrokker):
-    martian.component(grok.Viewlet)
-    martian.directive(grok.context)
-    martian.directive(grok.layer, default=IDefaultBrowserLayer)
-    martian.directive(grok.view)
-    martian.directive(grok.viewletmanager)
-    martian.directive(grok.name, get_default=default_view_name)
-    martian.directive(grok.require, name='permission')
-
-    def grok(self, name, factory, module_info, **kw):
-        # Need to store the module info object on the view class so that it
-        # can look up the 'static' resource directory.
-        factory.module_info = module_info
-        return super(ViewletGrokker, self).grok(
-            name, factory, module_info, **kw)
-
-    def execute(self, factory, config,
-                context, layer, view, viewletmanager, name, permission, **kw):
-        # This will be used to support __name__ on the viewlet
-        factory.__view_name__ = name
-
-        # find templates
-        templates = factory.module_info.getAnnotation('grok.templates', None)
-        if templates is not None:
-            config.action(
-                discriminator=None,
-                callable=self.checkTemplates,
-                args=(templates, factory.module_info, factory)
-                )
-
-        config.action(
-            discriminator = ('viewlet', context, layer,
-                             view, viewletmanager, name),
-            callable = component.provideAdapter,
-            args = (factory, (context, layer, view, viewletmanager),
-                    IViewlet, name)
-            )
-
-        config.action(
-            discriminator=('protectName', factory, '__call__'),
-            callable=make_checker,
-            args=(factory, factory, permission, ['update', 'render']),
-            )
-
-        return True
-
-    def checkTemplates(self, templates, module_info, factory):
-        def has_render(factory):
-            return factory.render != grok.components.Viewlet.render
-        def has_no_render(factory):
-            return not has_render(factory)
-        templates.checkTemplates(module_info, factory, 'viewlet',
-                                 has_render, has_no_render)

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,15 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:meta="http://namespaces.zope.org/meta"
-    xmlns:grok="http://namespaces.zope.org/grok">
-
-  <include package="z3c.autoinclude" file="meta.zcml" />
-
-  <!-- Load the grokkers -->
-  <include package="grokcore.component" file="meta.zcml" />
-  <include package="grokcore.formlib" file="meta.zcml" />
-  <include package="grokcore.security" file="meta.zcml" />
-  <include package="grokcore.view" file="meta.zcml" />
-  <grok:grok package=".meta" />
-
-</configure>

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,90 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 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.
-#
-##############################################################################
-"""Grok publication objects
-"""
-
-from grok.rest import GrokMethodNotAllowed
-
-from zope import component
-from zope.security.proxy import removeSecurityProxy
-from zope.security.checker import selectChecker
-from zope.publisher.publish import mapply
-
-from zope.app.publication.http import BaseHTTPPublication, HTTPPublication
-from zope.app.publication.browser import BrowserPublication
-from zope.app.publication.requestpublicationfactories import \
-     BrowserFactory, XMLRPCFactory, HTTPFactory
-from zope.app.http.interfaces import IHTTPException
-
-class ZopePublicationSansProxy(object):
-
-    def getApplication(self, request):
-        result = super(ZopePublicationSansProxy, self).getApplication(request)
-        return removeSecurityProxy(result)
-
-    def traverseName(self, request, ob, name):
-        result = super(ZopePublicationSansProxy, self).traverseName(
-            request, ob, name)
-        return removeSecurityProxy(result)
-
-    def callObject(self, request, ob):
-        checker = selectChecker(ob)
-        if checker is not None:
-            checker.check(ob, '__call__')
-        return super(ZopePublicationSansProxy, self).callObject(request, ob)
-
-
-class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
-
-    def getDefaultTraversal(self, request, ob):
-        obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
-            request, ob)
-        return removeSecurityProxy(obj), path
-
-
-class GrokBrowserFactory(BrowserFactory):
-
-    def __call__(self):
-        request, publication = super(GrokBrowserFactory, self).__call__()
-        return request, GrokBrowserPublication
-
-
-class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
-    pass
-
-class GrokXMLRPCFactory(XMLRPCFactory):
-
-    def __call__(self):
-        request, publication = super(GrokXMLRPCFactory, self).__call__()
-        return request, GrokXMLRPCPublication
-
-
-class GrokHTTPPublication(ZopePublicationSansProxy, HTTPPublication):
-   def callObject(self, request, ob):
-       orig = ob
-       if not IHTTPException.providedBy(ob):
-           ob = component.queryMultiAdapter((ob, request),
-                                            name=request.method)
-           checker = selectChecker(ob)
-           if checker is not None:
-               checker.check(ob, '__call__')
-           ob = getattr(ob, request.method, None)
-           if ob is None:
-               raise GrokMethodNotAllowed(orig, request)
-       return mapply(ob, request.getPositionalArguments(), request)
-
-class GrokHTTPFactory(HTTPFactory):
-    def __call__(self):
-        request, publication = super(GrokHTTPFactory, self).__call__()
-        return request, GrokHTTPPublication

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,86 +0,0 @@
-import grok
-
-from zope import component
-from zope.component.interfaces import ComponentLookupError
-
-from zope.traversing.interfaces import TraversalError
-from zope.traversing.namespace import view
-from zope.interface import Interface
-from zope.interface.interfaces import IInterface
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.app.publication.http import MethodNotAllowed
-
-from grok.interfaces import IRESTSkinType
-from zope.publisher.browser import applySkin
-
-class GrokMethodNotAllowed(MethodNotAllowed):
-    pass
-
-class MethodNotAllowedView(grok.MultiAdapter):
-    grok.adapts(GrokMethodNotAllowed, IHTTPRequest)
-    grok.name('index.html')
-    grok.implements(Interface)
-    
-    def __init__(self, error, request):
-        self.error = error
-        self.request = request
-        self.allow = self._getAllow()
-        
-    def _getAllow(self):
-        allow = []
-        for method in ['GET', 'PUT', 'POST', 'DELETE']:
-            view = component.queryMultiAdapter(
-                (self.error.object, self.error.request),
-                name=method)
-            if view is not None:
-                is_not_allowed = getattr(view, 'is_not_allowed', False)
-                if not is_not_allowed:
-                    allow.append(method)
-        allow.sort()
-        return allow
-    
-    def __call__(self):
-        self.request.response.setHeader('Allow', ', '.join(self.allow))
-        self.request.response.setStatus(405)
-        return 'Method Not Allowed'
-
-class rest_skin(view):
-    """A rest skin.
-    
-    This used to be supported by zope.traversing but the change was backed out.
-    We need it for our REST support.
-    """
-    def traverse(self, name, ignored):
-        self.request.shiftNameToApplication()
-        try:
-            skin = component.getUtility(IRESTSkinType, name)
-        except ComponentLookupError:
-            raise TraversalError("++rest++%s" % name)
-        applySkin(self.request, skin)
-        return self.context
-
-
-class NotAllowedREST(grok.REST):
-    """These are registered for everything by default to cause the correct
-    errors.
-
-    Any more specific REST view overrides this.
-    """
-    grok.layer(grok.IRESTLayer)
-    grok.context(Interface)
-
-    is_not_allowed = True
-    
-    def GET(self):
-        raise GrokMethodNotAllowed(self.context, self.request)
-            
-    def POST(self):
-        raise GrokMethodNotAllowed(self.context, self.request)
-            
-    def PUT(self):
-        raise GrokMethodNotAllowed(self.context, self.request)
-    
-    def DELETE(self):
-        raise GrokMethodNotAllowed(self.context, self.request)
-            

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok
+"""
+from zope.interface import implements
+from zope.component import adapts
+
+from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
+from martian import baseclass
+from martian.error import GrokError, GrokImportError
+
+from grokcore.component import Adapter, MultiAdapter, GlobalUtility, Context
+from grokcore.component.decorators import subscribe, adapter, implementer
+from grokcore.component.directive import (
+    context, name, title, description, provides, global_utility, direct)
+
+from grokcore.security import Permission
+from grokcore.security import Public
+from grokcore.security import require
+
+from grokcore.view import PageTemplate
+from grokcore.view import PageTemplateFile
+from grokcore.view import DirectoryResource
+from grokcore.view import layer
+from grokcore.view import template
+from grokcore.view import templatedir
+from grokcore.view import skin
+from grokcore.view import url
+from grokcore.view import path
+
+from grokcore.formlib import action
+from grokcore.formlib import AutoFields
+from grokcore.formlib import Fields
+
+from zope.event import notify
+from zope.app.component.hooks import getSite
+from zope.lifecycleevent import (
+    IObjectCreatedEvent, ObjectCreatedEvent,
+    IObjectModifiedEvent, ObjectModifiedEvent,
+    IObjectCopiedEvent, ObjectCopiedEvent)
+
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+from zope.app.container.contained import (
+    IObjectAddedEvent, ObjectAddedEvent,
+    IObjectMovedEvent, ObjectMovedEvent,
+    IObjectRemovedEvent, ObjectRemovedEvent,
+    IContainerModifiedEvent, ContainerModifiedEvent)
+
+from grok.components import Model, View
+from grok.components import XMLRPC, REST, JSON
+from grok.components import Traverser
+from grok.components import Container, OrderedContainer
+from grok.components import Site, LocalUtility, Annotation
+from grok.components import Application, Form, AddForm, EditForm, DisplayForm
+from grok.components import Indexes
+from grok.components import Role
+from grok.components import RESTProtocol, IRESTLayer
+from grok.interfaces import IRESTSkinType
+from grok.components import ViewletManager, Viewlet
+
+from grok.directive import (local_utility, permissions, site,
+                            viewletmanager, view, traversable, order)
+
+
+
+# BBB These two functions are meant for test fixtures and should be
+# imported from grok.testing, not from grok.
+from grok.testing import grok, grok_component
+
+# Our __init__ provides the grok API directly so using 'import grok' is enough.
+from grok.interfaces import IGrokAPI
+from zope.interface import moduleProvides
+moduleProvides(IGrokAPI)
+__all__ = list(IGrokAPI)

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,402 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok components"""
+
+import persistent
+import simplejson
+
+import zope.location
+from zope import component
+from zope import interface
+from zope.securitypolicy.role import Role
+from zope.publisher.browser import BrowserPage
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.publisher.publish import mapply
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+from zope.app.publisher.browser import getDefaultViewName
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.contained import Contained
+from zope.app.container.interfaces import IReadContainer, IObjectAddedEvent
+from zope.app.container.interfaces import IOrderedContainer
+from zope.app.container.contained import notifyContainerModified
+from persistent.list import PersistentList
+from zope.app.component.site import SiteManagerContainer
+from zope.app.component.site import LocalSiteManager
+
+from zope.viewlet.manager import ViewletManagerBase
+from zope.viewlet.viewlet import ViewletBase
+
+import grok
+import z3c.flashmessage.interfaces
+import martian.util
+
+import grokcore.view
+import grokcore.formlib
+from grok import interfaces, util
+
+
+class Model(Contained, persistent.Persistent):
+    # XXX Inheritance order is important here. If we reverse this,
+    # then containers can't be models anymore because no unambigous MRO
+    # can be established.
+    interface.implements(IAttributeAnnotatable, interfaces.IContext)
+
+
+class Container(BTreeContainer):
+    interface.implements(IAttributeAnnotatable, interfaces.IContainer)
+
+
+class OrderedContainer(Container):
+    interface.implements(IOrderedContainer)
+
+    def __init__(self):
+        super(OrderedContainer, self).__init__()
+        self._order = PersistentList()
+
+    def keys(self):
+        # Return a copy of the list to prevent accidental modifications.
+        return self._order[:]
+
+    def __iter__(self):
+        return iter(self.keys())
+
+    def values(self):
+        return (self[key] for key in self._order)
+
+    def items(self):
+        return ((key, self[key]) for key in self._order)
+
+    def __setitem__(self, key, object):
+        foo = self.has_key(key)
+        # Then do whatever containers normally do.
+        super(OrderedContainer, self).__setitem__(key, object)
+        if not foo:
+            self._order.append(key)
+
+    def __delitem__(self, key):
+        # First do whatever containers normally do.
+        super(OrderedContainer, self).__delitem__(key)
+        self._order.remove(key)
+
+    def updateOrder(self, order):
+        if set(order) != set(self._order):
+            raise ValueError("Incompatible key set.")
+
+        self._order = PersistentList()
+        self._order.extend(order)
+        notifyContainerModified(self)
+
+
+class Site(SiteManagerContainer):
+    pass
+
+ at component.adapter(Site, IObjectAddedEvent)
+def addSiteHandler(site, event):
+    sitemanager = LocalSiteManager(site)
+    # LocalSiteManager creates the 'default' folder in its __init__.
+    # It's not needed anymore in new versions of Zope 3, therefore we
+    # remove it
+    del sitemanager['default']
+    site.setSiteManager(sitemanager)
+
+
+class Application(Site):
+    """A top-level application object."""
+    interface.implements(interfaces.IApplication)
+
+
+class LocalUtility(Model):
+    pass
+
+
+class Annotation(persistent.Persistent):
+    pass
+
+
+class View(grokcore.view.View):
+    interface.implements(interfaces.IGrokView)
+
+    def application_url(self, name=None):
+        obj = self.context
+        while obj is not None:
+            if isinstance(obj, Application):
+                return self.url(obj, name)
+            obj = obj.__parent__
+        raise ValueError("No application found.")
+
+    def flash(self, message, type='message'):
+        source = component.getUtility(
+            z3c.flashmessage.interfaces.IMessageSource, name='session')
+        source.send(message, type)
+
+
+class Form(grokcore.formlib.Form, View):
+    interface.implements(interfaces.IGrokForm)
+
+
+class AddForm(grokcore.formlib.AddForm, View):
+    interface.implements(interfaces.IGrokForm)
+
+
+class DisplayForm(grokcore.formlib.DisplayForm, View):
+    interface.implements(interfaces.IGrokForm)
+
+
+class EditForm(grokcore.formlib.EditForm, View):
+    interface.implements(interfaces.IGrokForm)
+
+
+class XMLRPC(object):
+    pass
+
+class REST(zope.location.Location):
+    interface.implements(interfaces.IREST)
+
+    def __init__(self, context, request):
+        self.context = self.__parent__ = context
+        self.request = request
+        self.body = request.bodyStream.getCacheStream().read()
+
+    @property
+    def response(self):
+        return self.request.response
+
+##     def GET(self):
+##         raise GrokMethodNotAllowed(self.context, self.request)
+
+##     def POST(self):
+##         raise GrokMethodNotAllowed(self.context, self.request)
+
+##     def PUT(self):
+##         raise GrokMethodNotAllowed(self.context, self.request)
+
+##     def DELETE(self):
+##         raise GrokMethodNotAllowed(self.context, self.request)
+
+class JSON(BrowserPage):
+
+    def __call__(self):
+        view_name = self.__view_name__
+        method = getattr(self, view_name)
+        method_result = mapply(method, (), self.request)
+        return simplejson.dumps(method_result)
+
+
+class Traverser(object):
+    interface.implements(IBrowserPublisher)
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def browserDefault(self, request):
+        # if we have a RESTful request, we will handle
+        # GET, POST and HEAD differently (PUT and DELETE are handled already
+        # but not on the BrowserRequest layer but the HTTPRequest layer)
+        if IRESTLayer.providedBy(request):
+            rest_view = component.getMultiAdapter(
+                (self.context, self.request),
+                name=request.method)
+            return rest_view, ()
+        view_name = getDefaultViewName(self.context, request)
+        view_uri = "@@%s" % view_name
+        return self.context, (view_uri,)
+
+    def publishTraverse(self, request, name):
+        subob = self.traverse(name)
+        if subob is not None:
+            return util.safely_locate_maybe(subob, self.context, name)
+
+        traversable_dict = grok.traversable.bind().get(self.context)
+        if traversable_dict:
+            if name in traversable_dict:
+                subob = getattr(self.context, traversable_dict[name])
+                if callable(subob):
+                    subob = subob()
+                return util.safely_locate_maybe(subob, self.context, name)
+
+        # XXX Special logic here to deal with containers.  It would be
+        # good if we wouldn't have to do this here. One solution is to
+        # rip this out and make you subclass ContainerTraverser if you
+        # wanted to override the traversal behaviour of containers.
+        if IReadContainer.providedBy(self.context):
+            item = self.context.get(name)
+            if item is not None:
+                return item
+
+        view = component.queryMultiAdapter((self.context, request), name=name)
+        if view is not None:
+            return view
+
+        raise NotFound(self.context, name, request)
+
+    def traverse(self, name):
+        # this will be overridden by subclasses
+        pass
+
+
+class ContextTraverser(Traverser):
+    component.adapts(interfaces.IContext, IHTTPRequest)
+
+    def traverse(self, name):
+        traverse = getattr(self.context, 'traverse', None)
+        if traverse:
+            return traverse(name)
+
+
+class ContainerTraverser(Traverser):
+    component.adapts(interfaces.IContainer, IHTTPRequest)
+
+    def traverse(self, name):
+        traverse = getattr(self.context, 'traverse', None)
+        if traverse:
+            result = traverse(name)
+            if result is not None:
+                return result
+        # try to get the item from the container
+        return self.context.get(name)
+
+
+class IndexesClass(object):
+    def __init__(self, name, bases=(), attrs=None):
+        if attrs is None:
+            return
+        indexes = {}
+        for name, value in attrs.items():
+            # Ignore everything that's not an index definition object
+            # except for values set by directives
+            if '.' in name:
+                setattr(self, name, value)
+                continue
+            if not interfaces.IIndexDefinition.providedBy(value):
+                continue
+            indexes[name] = value
+        self.__grok_indexes__ = indexes
+        # __grok_module__ is needed to make defined_locally() return True for
+        # inline templates
+        self.__grok_module__ = martian.util.caller_module()
+
+Indexes = IndexesClass('Indexes')
+
+
+class Role(Role):
+    pass
+
+class IRESTLayer(IBrowserRequest):
+    pass
+
+class RESTProtocol(object):
+    pass
+
+class ViewletManager(ViewletManagerBase):
+    interface.implements(interfaces.IViewletManager)
+
+    template = None
+
+    def __init__(self, context, request, view):
+        super(ViewletManager, self).__init__(context, request, view)
+        self.context = context
+        self.request = request
+        self.view = view
+        self.__name__ = self.__view_name__
+        self.static = component.queryAdapter(
+            self.request,
+            interface.Interface,
+            name=self.module_info.package_dotted_name
+            )
+
+    def sort(self, viewlets):
+        """Sort the viewlets.
+
+        ``viewlets`` is a list of tuples of the form (name, viewlet).
+        """
+        # In Grok, the default order of the viewlets is determined by
+        # util.sort_components. util.sort_components() however expects
+        # a list of just components, but sort() is supposed to deal
+        # with a list of (name, viewlet) tuples.
+        # To handle this situation we first store the name part on the
+        # viewlet, then use util.sort_components() and then "unpack"
+        # the name from the viewlet and recreate the list of (name,
+        # viewlet) tuples, now in the correct order.
+        s_viewlets = []
+        for name, viewlet in viewlets:
+             # Stuff away viewlet name so we can later retrieve it.
+             # XXX We loose name information in case the same viewlet
+             # is in the viewlets list twice, but with a different
+             # name. Most probably this situation doesn't occur.
+             viewlet.__viewlet_name__ = name
+             s_viewlets.append(viewlet)
+        s_viewlets = util.sort_components(s_viewlets)
+        return [(viewlet.__viewlet_name__, viewlet) for viewlet in s_viewlets]
+
+    def default_namespace(self):
+        namespace = {}
+        namespace['context'] = self.context
+        namespace['request'] = self.request
+        namespace['static'] = self.static
+        namespace['view'] = self.view
+        namespace['viewletmanager'] = self
+        return namespace
+
+    def namespace(self):
+        return {}
+
+    def render(self):
+        """See zope.contentprovider.interfaces.IContentProvider"""
+        # Now render the view
+        if self.template:
+            return self.template.render(self)
+        else:
+            return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
+
+
+class Viewlet(ViewletBase):
+    """Batteries included viewlet.
+    """
+
+    def __init__(self, context, request, view, manager):
+        super(Viewlet, self).__init__(context, request, view, manager)
+        self.context = context
+        self.request = request
+        self.view = view
+        self.viewletmanager = manager
+        self.__name__ = self.__view_name__
+        self.static = component.queryAdapter(
+            self.request,
+            interface.Interface,
+            name=self.module_info.package_dotted_name
+            )
+
+    def default_namespace(self):
+        namespace = {}
+        namespace['context'] = self.context
+        namespace['request'] = self.request
+        namespace['static'] = self.static
+        namespace['view'] = self.view
+        namespace['viewlet'] = self
+        namespace['viewletmanager'] = self.manager
+        return namespace
+
+    def namespace(self):
+        return {}
+
+    def update(self):
+        pass
+
+    def render(self):
+        return self.template.render(self)

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,84 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:grok="http://namespaces.zope.org/grok">
+
+  <include package="zope.security" file="meta.zcml" />
+  <include package="zope.i18n" file="meta.zcml" />
+  <include package="zope.securitypolicy" file="meta.zcml" />
+  <include package="zope.app.zcmlfiles" file="meta.zcml" />
+  <include package="grok" file="meta.zcml" />
+
+  <include package="zope.annotation" />
+  <include package="zope.copypastemove" />
+  <include package="zope.contentprovider" />
+  <include package="zope.formlib" />
+  <include package="zope.i18n.locales" />
+  <include package="zope.publisher" />
+  <include package="zope.securitypolicy" />
+  <include package="zope.size" />
+  <include package="zope.traversing" />
+  <include package="zope.traversing.browser" />
+  <include package="zope.app.zcmlfiles" />
+  <include package="zope.app.authentication" />
+  <include package="zope.app.intid" />
+  <include package="zope.app.keyreference" />
+  <include package="zope.app.catalog" />
+  <include package="zope.app.renderer" />
+  <include package="zope.app.session" />
+
+  <include package="grokcore.view" />
+  <include package="grokcore.formlib" />
+
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+  <adapter factory=".components.ContextTraverser" />
+  <adapter factory=".components.ContainerTraverser" />
+
+  <browser:defaultView
+      for=".interfaces.IContext"
+      name="index"
+      />
+
+  <subscriber handler=".components.addSiteHandler" />
+
+  <!-- we register a ++rest++ traversal namespace -->
+  <adapter
+      factory=".rest.rest_skin"
+      for="* zope.publisher.interfaces.browser.IHTTPRequest"
+      provides="zope.traversing.interfaces.ITraversable"
+      name="rest"
+      />
+
+  <!-- this overrides Zope 3's publication factories because they have
+       the same name; we also need to change the priority because of
+       the ZCML discriminator -->
+  <publisher
+      name="XMLRPC"
+      factory=".publication.GrokXMLRPCFactory"
+      methods="POST"
+      mimetypes="text/xml"
+      priority="21"
+      />
+
+  <publisher
+      name="BROWSER"
+      factory=".publication.GrokBrowserFactory"
+      methods="GET POST HEAD"
+      mimetypes="*"
+      priority="11"
+      />
+
+  <publisher
+      name="HTTP"
+      factory=".publication.GrokHTTPFactory"
+      methods="*"
+      mimetypes="*"
+      priority="1"
+      />
+
+  <!-- need to grok this for some basic REST support -->
+  <grok:grok package=".rest" />
+
+</configure>

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,143 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok directives.
+"""
+
+import sys
+import grok
+from zope import interface
+from zope.interface.interfaces import IInterface
+from zope.interface.interface import TAGGED_DATA
+
+from zope.publisher.interfaces.browser import IBrowserView
+
+import martian
+from martian import util
+from martian.error import GrokImportError, GrokError
+from martian.directive import StoreOnce, StoreMultipleTimes
+from grokcore.component.scan import UnambiguousComponentScope
+from grok import components
+
+class local_utility(martian.Directive):
+    scope = martian.CLASS
+    store = martian.DICT
+
+    def factory(self, factory, provides=None, name=u'',
+                setup=None, public=False, name_in_container=None):
+        if provides is not None and not IInterface.providedBy(provides):
+            raise GrokImportError("You can only pass an interface to the "
+                                  "provides argument of %s." % self.name)
+
+        if provides is None:
+            provides = grok.provides.bind().get(factory)
+
+        if provides is None:
+            if util.check_subclass(factory, grok.LocalUtility):
+                baseInterfaces = interface.implementedBy(grok.LocalUtility)
+                utilityInterfaces = interface.implementedBy(factory)
+                provides = list(utilityInterfaces - baseInterfaces)
+
+                if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
+                    raise GrokImportError(
+                        "Cannot determine which interface to use "
+                        "for utility registration of %r. "
+                        "It implements an interface that is a specialization "
+                        "of an interface implemented by grok.LocalUtility. "
+                        "Specify the interface by either using grok.provides "
+                        "on the utility or passing 'provides' to "
+                        "grok.local_utility." % factory, factory)
+            else:
+                provides = list(interface.implementedBy(factory))
+
+            util.check_implements_one_from_list(provides, factory)
+            provides = provides[0]
+
+        if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
+            raise GrokImportError(
+                "Conflicting local utility registration %r. "
+                "Local utilities are registered multiple "
+                "times for interface %r and name %r." %
+                (factory, provides, name), factory)
+
+        info = LocalUtilityInfo(factory, provides, name, setup, public,
+                                name_in_container)
+        return (provides, name), info
+
+
+class LocalUtilityInfo(object):
+
+    _order = 0
+
+    def __init__(self, factory, provides, name=u'',
+                 setup=None, public=False, name_in_container=None):
+        self.factory = factory
+        self.provides = provides
+        self.name = name
+        self.setup = setup
+        self.public = public
+        self.name_in_container = name_in_container
+
+        self.order = LocalUtilityInfo._order
+        LocalUtilityInfo._order += 1
+
+    def __cmp__(self, other):
+        # LocalUtilityInfos have an inherit sort order by which the
+        # registrations take place.
+        return cmp(self.order, other.order)
+
+
+class site(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    validate = martian.validateInterfaceOrClass
+
+class permissions(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    default = []
+
+    def factory(*args):
+        return args
+
+class OneInterfaceOrClassOnClassOrModule(martian.Directive):
+    """Convenience base class.  Not for public use."""
+    scope = martian.CLASS_OR_MODULE
+    store = martian.ONCE
+    validate = martian.validateInterfaceOrClass
+
+class viewletmanager(OneInterfaceOrClassOnClassOrModule):
+    scope = UnambiguousComponentScope('viewletmanager')
+
+class view(OneInterfaceOrClassOnClassOrModule):
+    default = IBrowserView
+
+class traversable(martian.Directive):
+    scope = martian.CLASS
+    store = martian.DICT
+
+    def factory(self, attr, name=None):
+        if name is None:
+            name = attr
+        return (name, attr)
+
+class order(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    default = 0, 0
+
+    _order = 0
+
+    def factory(self, value=0):
+        order._order += 1
+        return value, order._order

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,35 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:grok="http://namespaces.zope.org/grok"
+   i18n_domain="grok"
+   package="grok"
+   >
+
+  <include package="grok" />
+  <grok:grok package="grok.ftests" />
+
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftests (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftests)

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,75 @@
+#############################################################################
+#
+# Copyright (c) 2007-2008 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.
+#
+##############################################################################
+"""Grok index definitions
+"""
+import sys
+
+from zope.interface import implements
+from zope.interface.interfaces import IMethod, IInterface
+
+from zope.app.catalog.field import FieldIndex
+from zope.app.catalog.text import TextIndex
+from zc.catalog.catalogindex import SetIndex
+
+from martian.error import GrokError, GrokImportError
+from martian.util import frame_is_class
+
+from grok.interfaces import IIndexDefinition
+
+class IndexDefinition(object):
+    implements(IIndexDefinition)
+
+    index_class = None
+
+    def __init__(self, *args, **kw):
+        frame = sys._getframe(1)
+        if not frame_is_class(frame):
+            raise GrokImportError(
+                "%r can only be instantiated on class level." % self.__class__)
+        # store any extra parameters to pass to index later
+        self._args = args
+        self._attribute = kw.pop('attribute', None)
+        self._kw = kw
+
+    def setup(self, catalog, name, context, module_info):
+        if self._attribute is not None:
+            field_name = self._attribute
+        else:
+            field_name = name
+
+        if IInterface.providedBy(context):
+            try:
+                method = context[field_name]
+            except KeyError:
+                raise GrokError("grok.Indexes in %r refers to an attribute or "
+                                "method %r on interface %r, but this does not "
+                                "exist." % (module_info.getModule(),
+                                            field_name, context), None)
+            call = IMethod.providedBy(method)
+        else:
+            call = callable(getattr(context, field_name, None))
+            context = None # no interface lookup
+        catalog[name] = self.index_class(field_name=field_name,
+                                         interface=context,
+                                         field_callable=call,
+                                         *self._args, **self._kw)
+
+class Field(IndexDefinition):
+    index_class = FieldIndex
+
+class Text(IndexDefinition):
+    index_class = TextIndex
+
+class Set(IndexDefinition):
+    index_class = SetIndex

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,234 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok interfaces
+"""
+from zope import interface, schema
+from zope.formlib.interfaces import reConstraint
+from zope.interface.interfaces import IInterface
+from zope.viewlet.interfaces import IViewletManager as IViewletManagerBase
+from zope.app.container.interfaces import IContainer as IContainerBase
+
+import grokcore.component.interfaces
+import grokcore.formlib.interfaces
+import grokcore.security.interfaces
+import grokcore.view.interfaces
+
+# Expose interfaces from grokcore.* packages as well:
+from grokcore.component.interfaces import IContext
+from grokcore.component.interfaces import IGrokErrors
+from grokcore.view.interfaces import ITemplateFileFactory
+from grokcore.view.interfaces import ITemplate
+
+
+class IGrokBaseClasses(grokcore.component.interfaces.IBaseClasses,
+                       grokcore.security.interfaces.IBaseClasses,
+                       grokcore.view.interfaces.IBaseClasses):
+    Model = interface.Attribute("Base class for persistent content objects "
+                                "(models).")
+    Container = interface.Attribute("Base class for containers.")
+    OrderedContainer = interface.Attribute("Base class for ordered containers.")
+    Site = interface.Attribute("Mixin class for sites.")
+    Application = interface.Attribute("Base class for applications.")
+    Annotation = interface.Attribute("Base class for persistent annotations.")
+    LocalUtility = interface.Attribute("Base class for local utilities.")
+    XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
+    JSON = interface.Attribute("Base class for JSON methods.")
+    REST = interface.Attribute("Base class for REST views.")
+    Traverser = interface.Attribute("Base class for custom traversers.")
+    Indexes = interface.Attribute("Base class for catalog index definitions.")
+    ViewletManager = interface.Attribute("Base class for viewletmanager.")
+    Viewlet = interface.Attribute("Base class for viewlet.")
+    Role = interface.Attribute("Base class for roles.")
+
+
+class IGrokDirectives(grokcore.component.interfaces.IDirectives,
+                      grokcore.security.interfaces.IDirectives,
+                      grokcore.view.interfaces.IDirectives):
+
+    def local_utility(factory, provides=None, name=u'',
+                      setup=None, public=False, name_in_container=None):
+        """Register a local utility.
+
+        factory - the factory that creates the local utility
+        provides - the interface the utility should be looked up with
+        name - the name of the utility
+        setup - a callable that receives the utility as its single argument,
+                it is called after the utility has been created and stored
+        public - if False, the utility will be stored below ++etc++site
+                 if True, the utility will be stored directly in the site.
+                 The site should in this case be a container.
+        name_in_container - the name to use for storing the utility
+        """
+
+    def permissions(permissions):
+        """Specify the permissions that comprise a role.
+        """
+
+    def site(class_or_interface):
+        """Specifies the site that an indexes definition is for.
+
+        It can only be used inside grok.Indexes subclasses.
+        """
+
+    def order(value=None):
+        """Control the ordering of components.
+
+        If the value is specified, the order will be determined by sorting on
+        it.
+        If no value is specified, the order will be determined by definition
+        order within the module.
+        If the directive is absent, the order will be determined by class name.
+        (unfortunately our preferred default behavior on absence which would
+        be like grok.order() without argument is hard to implement in Python)
+
+        Inter-module order is by dotted name of the module the
+        components are in; unless an explicit argument is specified to
+        ``grok.order()``, components are grouped by module.
+
+        The function grok.util.sort_components can be used to sort
+        components according to these rules.
+        """
+
+
+class IGrokEvents(interface.Interface):
+
+    IObjectCreatedEvent = interface.Attribute("")
+
+    ObjectCreatedEvent = interface.Attribute("")
+
+    IObjectModifiedEvent = interface.Attribute("")
+
+    ObjectModifiedEvent = interface.Attribute("")
+
+    IObjectCopiedEvent = interface.Attribute("")
+
+    ObjectCopiedEvent = interface.Attribute("")
+
+    IObjectAddedEvent = interface.Attribute("")
+
+    ObjectAddedEvent = interface.Attribute("")
+
+    IObjectMovedEvent = interface.Attribute("")
+
+    ObjectMovedEvent = interface.Attribute("")
+
+    IObjectRemovedEvent = interface.Attribute("")
+
+    ObjectRemovedEvent = interface.Attribute("")
+
+    IContainerModifiedEvent = interface.Attribute("")
+
+    ContainerModifiedEvent = interface.Attribute("")
+
+
+class IGrokAPI(grokcore.security.interfaces.IGrokcoreSecurityAPI,
+               grokcore.view.interfaces.IGrokcoreViewAPI,
+               grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
+               IGrokBaseClasses, IGrokDirectives, 
+               IGrokEvents, IGrokErrors):
+
+    # BBB this is deprecated
+    def grok(dotted_name):
+        """Grok a module or package specified by ``dotted_name``.
+
+        NOTE: This function will be removed from the public Grok
+        public API.  For tests and interpreter sessions, use
+        grok.testing.grok().
+        """
+
+    # BBB this is deprecated
+    def grok_component(name, component, context=None, module_info=None,
+                       templates=None):
+        """Grok an arbitrary object. Can be useful during testing.
+
+        name - the name of the component (class name, or global instance name
+               as it would appear in a module).
+        component - the object (class, etc) to grok.
+        context - the context object (optional).
+        module_info - the module being grokked (optional).
+        templates - the templates registry (optional).
+
+        Note that context, module_info and templates might be required
+        for some grokkers which rely on them.
+
+        NOTE: This function will be removed from the public Grok
+        public API.  For tests and interpreter sessions, use
+        grok.testing.grok_component().
+        """
+
+    def notify(event):
+        """Send ``event`` to event subscribers."""
+
+    def getSite():
+        """Get the current site."""
+
+
+    IRESTSkinType = interface.Attribute('The REST skin type')
+
+
+class IGrokView(grokcore.view.interfaces.IGrokView):
+    """Grok views all provide this interface."""
+
+    def application_url(name=None):
+        """Return the URL of the closest application object in the
+        hierarchy or the URL of a named object (``name`` parameter)
+        relative to the closest application object.
+        """
+
+    def flash(message, type='message'):
+        """Send a short message to the user."""
+
+
+class IGrokForm(grokcore.formlib.interfaces.IGrokForm, IGrokView):
+    """All Grok forms provides this interface."""
+
+
+class IREST(interface.Interface):
+    context = interface.Attribute("Object that the REST handler presents.")
+
+    request = interface.Attribute("Request that REST handler was looked"
+                                  "up with.")
+
+    body = interface.Attribute(
+        """The text of the request body.""")
+
+class IApplication(interface.Interface):
+    """Marker-interface for grok application factories.
+
+    Used to register applications as utilities to look them up and
+    provide a list of grokked applications.
+    """
+
+class IIndexDefinition(interface.Interface):
+    """Define an index for grok.Indexes.
+    """
+
+    def setup(catalog, name, context):
+        """Set up index called name in given catalog.
+
+        Use name for index name and attribute to index. Set up
+        index for interface or class context.
+        """
+
+class IRESTSkinType(IInterface):
+    """Skin type for REST requests.
+    """
+
+class IContainer(IContext, IContainerBase):
+    """A Grok container.
+    """
+
+class IViewletManager(IViewletManagerBase):
+    """The Grok viewlet manager.
+    """

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,537 @@
+#############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grokkers for the various components."""
+
+import zope.component.interface
+from zope import interface, component
+from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
+                                               IBrowserRequest,
+                                               IBrowserPublisher)
+from zope.publisher.interfaces.http import IHTTPRequest
+
+from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
+from zope.viewlet.interfaces import IViewletManager, IViewlet
+from zope.securitypolicy.interfaces import IRole
+from zope.securitypolicy.rolepermission import rolePermissionManager
+
+from zope.annotation.interfaces import IAnnotations
+
+from zope.app.publisher.xmlrpc import MethodPublisher
+from zope.app.container.interfaces import IContainer
+from zope.app.container.interfaces import INameChooser
+from zope.app.container.contained import contained
+
+from zope.app.intid import IntIds
+from zope.app.intid.interfaces import IIntIds
+from zope.app.catalog.catalog import Catalog
+from zope.app.catalog.interfaces import ICatalog
+
+from zope.exceptions.interfaces import DuplicationError
+
+import martian
+from martian.error import GrokError
+from martian import util
+
+import grok
+from grok import components
+from grok.util import make_checker
+from grok.interfaces import IRESTSkinType
+from grok.interfaces import IViewletManager as IGrokViewletManager
+
+from grokcore.component.scan import determine_module_component
+from grokcore.security.meta import PermissionGrokker
+
+from grokcore.view.meta.views import (
+    default_view_name, default_fallback_to_name)
+
+
+def default_annotation_provides(factory, module, **data):
+    base_interfaces = interface.implementedBy(grok.Annotation)
+    factory_interfaces = interface.implementedBy(factory)
+    real_interfaces = list(factory_interfaces - base_interfaces)
+    util.check_implements_one_from_list(real_interfaces, factory)
+    return real_interfaces[0]
+
+def default_annotation_name(factory, module, **data):
+    return factory.__module__ + '.' + factory.__name__
+
+
+class ViewletManagerContextGrokker(martian.GlobalGrokker):
+
+    martian.priority(1001)
+
+    def grok(self, name, module, module_info, config, **kw):
+        viewletmanager = determine_module_component(module_info,
+                                                    grok.viewletmanager,
+                                                    IGrokViewletManager)
+        grok.viewletmanager.set(module, viewletmanager)
+        return True
+
+
+class XMLRPCGrokker(martian.MethodGrokker):
+    martian.component(grok.XMLRPC)
+    martian.directive(grok.context)
+    martian.directive(grok.require, name='permission')
+
+    def execute(self, factory, method, config, context, permission, **kw):
+        name = method.__name__
+
+        # Make sure that the class inherits MethodPublisher, so that the
+        # views have a location
+        method_view = type(
+            factory.__name__, (factory, MethodPublisher),
+            {'__call__': method}
+            )
+
+        adapts = (context, IXMLRPCRequest)
+        config.action(
+            discriminator=('adapter', adapts, interface.Interface, name),
+            callable=component.provideAdapter,
+            args=(method_view, adapts, interface.Interface, name),
+            )
+        config.action(
+            discriminator=('protectName', method_view, '__call__'),
+            callable=make_checker,
+            args=(factory, method_view, permission),
+            )
+        return True
+
+
+class RESTGrokker(martian.MethodGrokker):
+    martian.component(grok.REST)
+    martian.directive(grok.context)
+    martian.directive(grok.layer, default=grok.IRESTLayer)
+    martian.directive(grok.require, name='permission')
+
+    def execute(self, factory, method, config, permission, context, layer, **kw):
+        name = method.__name__
+
+        method_view = type(
+            factory.__name__, (factory,),
+            {'__call__': method }
+            )
+
+        adapts = (context, layer)
+        config.action(
+            discriminator=('adapter', adapts, interface.Interface, name),
+            callable=component.provideAdapter,
+            args=(method_view, adapts, interface.Interface, name),
+            )
+        config.action(
+            discriminator=('protectName', method_view, '__call__'),
+            callable=make_checker,
+            args=(factory, method_view, permission),
+            )
+        return True
+
+
+class JSONGrokker(martian.MethodGrokker):
+    martian.component(grok.JSON)
+    martian.directive(grok.context)
+    martian.directive(grok.require, name='permission')
+
+    # TODO: this grokker doesn't support layers yet
+
+    def execute(self, factory, method, config, context, permission, **kw):
+        # Create a new class with a __view_name__ attribute so the
+        # JSON class knows what method to call.
+        method_view = type(
+            factory.__name__, (factory,),
+            {'__view_name__': method.__name__}
+            )
+        adapts = (context, IDefaultBrowserLayer)
+        name = method.__name__
+
+        config.action(
+            discriminator=('adapter', adapts, interface.Interface, name),
+            callable=component.provideAdapter,
+            args=(method_view, adapts, interface.Interface, name),
+            )
+        config.action(
+            discriminator=('protectName', method_view, '__call__'),
+            callable=make_checker,
+            args=(factory, method_view, permission),
+            )
+        return True
+
+
+class TraverserGrokker(martian.ClassGrokker):
+    martian.component(grok.Traverser)
+    martian.directive(grok.context)
+
+    def execute(self, factory, config, context, **kw):
+        adapts = (context, IHTTPRequest)
+        config.action(
+            discriminator=('adapter', adapts, IBrowserPublisher, ''),
+            callable=component.provideAdapter,
+            args=(factory, adapts, IBrowserPublisher),
+            )
+        return True
+
+
+class SiteGrokker(martian.ClassGrokker):
+    martian.component(grok.Site)
+    martian.priority(500)
+    martian.directive(grok.local_utility, name='infos')
+
+    def execute(self, factory, config, infos, **kw):
+        if not infos:
+            return False
+
+        infos = infos.values()
+        for info in infos:
+            if info.public and not IContainer.implementedBy(factory):
+                raise GrokError(
+                    "Cannot set public to True with grok.local_utility as "
+                    "the site (%r) is not a container." %
+                    factory, factory)
+
+        # Store the list of info objects in their "natural" order on the
+        # site class. They will be picked up by a subscriber doing the
+        # actual registrations in definition order.
+        factory.__grok_utilities_to_install__ = sorted(infos)
+        adapts = (factory, grok.IObjectAddedEvent)
+
+        config.action(
+            discriminator=None,
+            callable=component.provideHandler,
+            args=(localUtilityRegistrationSubscriber, adapts),
+            )
+        return True
+
+
+def localUtilityRegistrationSubscriber(site, event):
+    """A subscriber that fires to set up local utilities.
+    """
+    installed = getattr(site, '__grok_utilities_installed__', False)
+    if installed:
+        return
+
+    for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
+        setupUtility(site, info.factory(), info.provides, name=info.name,
+                     name_in_container=info.name_in_container,
+                     public=info.public, setup=info.setup)
+
+    # we are done. If this subscriber gets fired again, we therefore
+    # do not register utilities anymore
+    site.__grok_utilities_installed__ = True
+
+
+def setupUtility(site, utility, provides, name=u'',
+                 name_in_container=None, public=False, setup=None):
+    """Set up a utility in a site.
+
+    site - the site to set up the utility in
+    utility - the utility to set up
+    provides - the interface the utility should be registered with
+    name - the name the utility should be registered under, default
+      the empty string (no name)
+    name_in_container - if given it will be used to add the utility
+      object to its container. Otherwise a name will be made up
+    public - if False, the utility will be stored in the site manager. If
+      True, the utility will be storedin the site (it is assumed the
+      site is a container)
+    setup - if not None, it will be called with the utility as its first
+       argument. This function can then be used to further set up the
+       utility.
+    """
+    site_manager = site.getSiteManager()
+
+    if not public:
+        container = site_manager
+    else:
+        container = site
+
+    if name_in_container is None:
+        name_in_container = INameChooser(container).chooseName(
+            utility.__class__.__name__, utility)
+    container[name_in_container] = utility
+
+    if setup is not None:
+        setup(utility)
+
+    site_manager.registerUtility(utility, provided=provides,
+                                 name=name)
+
+
+class RoleGrokker(martian.ClassGrokker):
+    martian.component(grok.Role)
+    martian.priority(martian.priority.bind().get(PermissionGrokker()) - 1)
+    martian.directive(grok.name)
+    martian.directive(grok.title, get_default=default_fallback_to_name)
+    martian.directive(grok.description)
+    martian.directive(grok.permissions)
+
+    def execute(self, factory, config, name, title, description,
+                permissions, **kw):
+        if not name:
+            raise GrokError(
+                "A role needs to have a dotted name for its id. Use "
+                "grok.name to specify one.", factory)
+        # We can safely convert to unicode, since the directives makes sure
+        # it is either unicode already or ASCII.
+        role = factory(unicode(name), unicode(title), unicode(description))
+
+        config.action(
+            discriminator=('utility', IRole, name),
+            callable=component.provideUtility,
+            args=(role, IRole, name),
+            )
+
+        for permission in permissions:
+            config.action(
+                discriminator=('grantPermissionToRole', permission, name),
+                callable=rolePermissionManager.grantPermissionToRole,
+                args=(permission, name),
+                )
+        return True
+
+
+class AnnotationGrokker(martian.ClassGrokker):
+    martian.component(grok.Annotation)
+    martian.directive(grok.context, name='adapter_context')
+    martian.directive(grok.provides, get_default=default_annotation_provides)
+    martian.directive(grok.name, get_default=default_annotation_name)
+
+    def execute(self, factory, config, adapter_context, provides, name, **kw):
+        @component.adapter(adapter_context)
+        @interface.implementer(provides)
+        def getAnnotation(context):
+            annotations = IAnnotations(context)
+            try:
+                result = annotations[name]
+            except KeyError:
+                result = factory()
+                annotations[name] = result
+
+            # Containment has to be set up late to allow containment
+            # proxies to be applied, if needed. This does not trigger
+            # an event and is idempotent if containment is set up
+            # already.
+            contained_result = contained(result, context, name)
+            return contained_result
+
+        config.action(
+            discriminator=('adapter', adapter_context, provides, ''),
+            callable=component.provideAdapter,
+            args=(getAnnotation,),
+            )
+        return True
+
+
+class ApplicationGrokker(martian.ClassGrokker):
+    martian.component(grok.Application)
+    martian.priority(500)
+
+    def grok(self, name, factory, module_info, config, **kw):
+        # XXX fail loudly if the same application name is used twice.
+        provides = grok.interfaces.IApplication
+        name = '%s.%s' % (module_info.dotted_name, name)
+        config.action(
+            discriminator=('utility', provides, name),
+            callable=component.provideUtility,
+            args=(factory, provides, name),
+            )
+        return True
+
+
+class IndexesGrokker(martian.InstanceGrokker):
+    martian.component(components.IndexesClass)
+
+    def grok(self, name, factory, module_info, config, **kw):
+        site = grok.site.bind().get(factory)
+        context = grok.context.bind().get(factory, module_info.getModule())
+        catalog_name = grok.name.bind().get(factory)
+
+        if site is None:
+            raise GrokError("No site specified for grok.Indexes "
+                            "subclass in module %r. "
+                            "Use grok.site() to specify."
+                            % module_info.getModule(),
+                            factory)
+        indexes = getattr(factory, '__grok_indexes__', None)
+        if indexes is None:
+            return False
+
+        subscriber = IndexesSetupSubscriber(catalog_name, indexes,
+                                            context, module_info)
+        subscribed = (site, grok.IObjectAddedEvent)
+        config.action(
+            discriminator=None,
+            callable=component.provideHandler,
+            args=(subscriber, subscribed),
+            )
+        return True
+
+
+class IndexesSetupSubscriber(object):
+
+    def __init__(self, catalog_name, indexes, context, module_info):
+        self.catalog_name = catalog_name
+        self.indexes = indexes
+        self.context = context
+        self.module_info = module_info
+
+    def __call__(self, site, event):
+        # make sure we have an intids
+        self._createIntIds(site)
+        # get the catalog
+        catalog = self._createCatalog(site)
+        # now install indexes
+        for name, index in self.indexes.items():
+            try:
+                index.setup(catalog, name, self.context, self.module_info)
+            except DuplicationError:
+                raise GrokError(
+                    "grok.Indexes in module %r causes "
+                    "creation of catalog index %r in catalog %r, "
+                    "but an index with that name is already present." %
+                    (self.module_info.getModule(), name, self.catalog_name),
+                    None)
+
+    def _createCatalog(self, site):
+        """Create the catalog if needed and return it.
+
+        If the catalog already exists, return that.
+
+        """
+        catalog = zope.component.queryUtility(
+            ICatalog, name=self.catalog_name, context=site, default=None)
+        if catalog is not None:
+            return catalog
+        catalog = Catalog()
+        setupUtility(site, catalog, ICatalog, name=self.catalog_name)
+        return catalog
+
+    def _createIntIds(self, site):
+        """Create intids if needed, and return it.
+        """
+        intids = zope.component.queryUtility(
+            IIntIds, context=site, default=None)
+        if intids is not None:
+            return intids
+        intids = IntIds()
+        setupUtility(site, intids, IIntIds)
+        return intids
+
+
+class RESTProtocolGrokker(martian.ClassGrokker):
+    martian.component(grok.RESTProtocol)
+    martian.directive(grok.layer, default=IBrowserRequest)
+    martian.directive(grok.name, get_default=default_view_name)
+
+    def execute(self, factory, config, name, layer, **kw):
+        config.action(
+            discriminator=('restprotocol', name),
+            callable=zope.component.interface.provideInterface,
+            args=(name, layer, IRESTSkinType)
+            )
+        return True
+
+class ViewletManagerGrokker(martian.ClassGrokker):
+    martian.component(grok.ViewletManager)
+    martian.directive(grok.context)
+    martian.directive(grok.layer, default=IDefaultBrowserLayer)
+    martian.directive(grok.view)
+    martian.directive(grok.name)
+
+    def grok(self, name, factory, module_info, **kw):
+        # Need to store the module info object on the view class so that it
+        # can look up the 'static' resource directory.
+        factory.module_info = module_info
+        return super(ViewletManagerGrokker, self).grok(
+            name, factory, module_info, **kw)
+
+    def execute(self, factory, config, context, layer, view, name, **kw):
+        # This will be used to support __name__ on the viewlet manager
+        factory.__view_name__ = name
+
+        # find templates
+        templates = factory.module_info.getAnnotation('grok.templates', None)
+        if templates is not None:
+            config.action(
+                discriminator=None,
+                callable=self.checkTemplates,
+                args=(templates, factory.module_info, factory)
+                )
+
+        config.action(
+            discriminator = ('viewletManager', context, layer, view, name),
+            callable = component.provideAdapter,
+            args = (factory, (context, layer, view), IViewletManager, name)
+            )
+        return True
+
+    def checkTemplates(self, templates, module_info, factory):
+        def has_render(factory):
+            return factory.render != grok.components.ViewletManager.render
+        def has_no_render(factory):
+            # always has a render method
+            return False
+        templates.checkTemplates(module_info, factory, 'viewlet manager',
+                                 has_render, has_no_render)
+
+class ViewletGrokker(martian.ClassGrokker):
+    martian.component(grok.Viewlet)
+    martian.directive(grok.context)
+    martian.directive(grok.layer, default=IDefaultBrowserLayer)
+    martian.directive(grok.view)
+    martian.directive(grok.viewletmanager)
+    martian.directive(grok.name, get_default=default_view_name)
+    martian.directive(grok.require, name='permission')
+
+    def grok(self, name, factory, module_info, **kw):
+        # Need to store the module info object on the view class so that it
+        # can look up the 'static' resource directory.
+        factory.module_info = module_info
+        return super(ViewletGrokker, self).grok(
+            name, factory, module_info, **kw)
+
+    def execute(self, factory, config,
+                context, layer, view, viewletmanager, name, permission, **kw):
+        # This will be used to support __name__ on the viewlet
+        factory.__view_name__ = name
+
+        # find templates
+        templates = factory.module_info.getAnnotation('grok.templates', None)
+        if templates is not None:
+            config.action(
+                discriminator=None,
+                callable=self.checkTemplates,
+                args=(templates, factory.module_info, factory)
+                )
+
+        config.action(
+            discriminator = ('viewlet', context, layer,
+                             view, viewletmanager, name),
+            callable = component.provideAdapter,
+            args = (factory, (context, layer, view, viewletmanager),
+                    IViewlet, name)
+            )
+
+        config.action(
+            discriminator=('protectName', factory, '__call__'),
+            callable=make_checker,
+            args=(factory, factory, permission, ['update', 'render']),
+            )
+
+        return True
+
+    def checkTemplates(self, templates, module_info, factory):
+        def has_render(factory):
+            return factory.render != grok.components.Viewlet.render
+        def has_no_render(factory):
+            return not has_render(factory)
+        templates.checkTemplates(module_info, factory, 'viewlet',
+                                 has_render, has_no_render)

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,15 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta"
+    xmlns:grok="http://namespaces.zope.org/grok">
+
+  <include package="z3c.autoinclude" file="meta.zcml" />
+
+  <!-- Load the grokkers -->
+  <include package="grokcore.component" file="meta.zcml" />
+  <include package="grokcore.formlib" file="meta.zcml" />
+  <include package="grokcore.security" file="meta.zcml" />
+  <include package="grokcore.view" file="meta.zcml" />
+  <grok:grok package=".meta" />
+
+</configure>

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,90 @@
+##############################################################################
+#
+# Copyright (c) 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.
+#
+##############################################################################
+"""Grok publication objects
+"""
+
+from grok.rest import GrokMethodNotAllowed
+
+from zope import component
+from zope.security.proxy import removeSecurityProxy
+from zope.security.checker import selectChecker
+from zope.publisher.publish import mapply
+
+from zope.app.publication.http import BaseHTTPPublication, HTTPPublication
+from zope.app.publication.browser import BrowserPublication
+from zope.app.publication.requestpublicationfactories import \
+     BrowserFactory, XMLRPCFactory, HTTPFactory
+from zope.app.http.interfaces import IHTTPException
+
+class ZopePublicationSansProxy(object):
+
+    def getApplication(self, request):
+        result = super(ZopePublicationSansProxy, self).getApplication(request)
+        return removeSecurityProxy(result)
+
+    def traverseName(self, request, ob, name):
+        result = super(ZopePublicationSansProxy, self).traverseName(
+            request, ob, name)
+        return removeSecurityProxy(result)
+
+    def callObject(self, request, ob):
+        checker = selectChecker(ob)
+        if checker is not None:
+            checker.check(ob, '__call__')
+        return super(ZopePublicationSansProxy, self).callObject(request, ob)
+
+
+class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
+
+    def getDefaultTraversal(self, request, ob):
+        obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
+            request, ob)
+        return removeSecurityProxy(obj), path
+
+
+class GrokBrowserFactory(BrowserFactory):
+
+    def __call__(self):
+        request, publication = super(GrokBrowserFactory, self).__call__()
+        return request, GrokBrowserPublication
+
+
+class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
+    pass
+
+class GrokXMLRPCFactory(XMLRPCFactory):
+
+    def __call__(self):
+        request, publication = super(GrokXMLRPCFactory, self).__call__()
+        return request, GrokXMLRPCPublication
+
+
+class GrokHTTPPublication(ZopePublicationSansProxy, HTTPPublication):
+   def callObject(self, request, ob):
+       orig = ob
+       if not IHTTPException.providedBy(ob):
+           ob = component.queryMultiAdapter((ob, request),
+                                            name=request.method)
+           checker = selectChecker(ob)
+           if checker is not None:
+               checker.check(ob, '__call__')
+           ob = getattr(ob, request.method, None)
+           if ob is None:
+               raise GrokMethodNotAllowed(orig, request)
+       return mapply(ob, request.getPositionalArguments(), request)
+
+class GrokHTTPFactory(HTTPFactory):
+    def __call__(self):
+        request, publication = super(GrokHTTPFactory, self).__call__()
+        return request, GrokHTTPPublication

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,86 @@
+import grok
+
+from zope import component
+from zope.component.interfaces import ComponentLookupError
+
+from zope.traversing.interfaces import TraversalError
+from zope.traversing.namespace import view
+from zope.interface import Interface
+from zope.interface.interfaces import IInterface
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.app.publication.http import MethodNotAllowed
+
+from grok.interfaces import IRESTSkinType
+from zope.publisher.browser import applySkin
+
+class GrokMethodNotAllowed(MethodNotAllowed):
+    pass
+
+class MethodNotAllowedView(grok.MultiAdapter):
+    grok.adapts(GrokMethodNotAllowed, IHTTPRequest)
+    grok.name('index.html')
+    grok.implements(Interface)
+    
+    def __init__(self, error, request):
+        self.error = error
+        self.request = request
+        self.allow = self._getAllow()
+        
+    def _getAllow(self):
+        allow = []
+        for method in ['GET', 'PUT', 'POST', 'DELETE']:
+            view = component.queryMultiAdapter(
+                (self.error.object, self.error.request),
+                name=method)
+            if view is not None:
+                is_not_allowed = getattr(view, 'is_not_allowed', False)
+                if not is_not_allowed:
+                    allow.append(method)
+        allow.sort()
+        return allow
+    
+    def __call__(self):
+        self.request.response.setHeader('Allow', ', '.join(self.allow))
+        self.request.response.setStatus(405)
+        return 'Method Not Allowed'
+
+class rest_skin(view):
+    """A rest skin.
+    
+    This used to be supported by zope.traversing but the change was backed out.
+    We need it for our REST support.
+    """
+    def traverse(self, name, ignored):
+        self.request.shiftNameToApplication()
+        try:
+            skin = component.getUtility(IRESTSkinType, name)
+        except ComponentLookupError:
+            raise TraversalError("++rest++%s" % name)
+        applySkin(self.request, skin)
+        return self.context
+
+
+class NotAllowedREST(grok.REST):
+    """These are registered for everything by default to cause the correct
+    errors.
+
+    Any more specific REST view overrides this.
+    """
+    grok.layer(grok.IRESTLayer)
+    grok.context(Interface)
+
+    is_not_allowed = True
+    
+    def GET(self):
+        raise GrokMethodNotAllowed(self.context, self.request)
+            
+    def POST(self):
+        raise GrokMethodNotAllowed(self.context, self.request)
+            
+    def PUT(self):
+        raise GrokMethodNotAllowed(self.context, self.request)
+    
+    def DELETE(self):
+        raise GrokMethodNotAllowed(self.context, self.request)
+            

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,81 @@
+##############################################################################
+#
+# Copyright (c) 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.
+#
+##############################################################################
+"""Grok test helpers
+"""
+import sys
+import os.path
+import z3c.testsetup
+from zope.configuration.config import ConfigurationMachine
+from grokcore.component import zcml
+# Provide this import here for BBB reasons:
+from grokcore.component.testing import grok_component
+
+class GrokTestCollector(z3c.testsetup.TestCollector):
+
+    def initialize(self):
+        # inject the grok ftesting ZCML as fallback...
+        if 'zcml_config' in self.settings.keys():
+            return
+        pkg_path = os.path.dirname(self.package.__file__)
+        if os.path.isfile(os.path.join(pkg_path, 'ftesting.zcml')):
+            return
+        self.settings['zcml_config'] = os.path.join(
+            os.path.dirname(__file__), 'ftesting.zcml')
+        if 'layer_name' in self.settings.keys():
+            return
+        self.settings['layer_name'] = 'GrokFunctionalLayer'
+
+def register_all_tests(pkg, *args, **kw):
+    return GrokTestCollector(pkg, *args, **kw)
+
+def grok(module_name):
+    config = ConfigurationMachine()
+    zcml.do_grok('grokcore.component.meta', config)
+    zcml.do_grok('grokcore.security.meta', config)
+    zcml.do_grok('grokcore.view.meta', config)
+    zcml.do_grok('grokcore.view.templatereg', config)
+    zcml.do_grok('grokcore.formlib.meta', config)
+    zcml.do_grok('grok.meta', config)
+    zcml.do_grok(module_name, config)
+    config.execute_actions()
+
+def warn(message, category=None, stacklevel=1):
+    """Intended to replace warnings.warn in tests.
+
+    Modified copy from zope.deprecation.tests to:
+
+      * make the signature identical to warnings.warn
+      * to check for *.pyc and *.pyo files.
+
+    When zope.deprecation is fixed, this warn function can be removed again.
+    """
+    print "From grok.testing's warn():"
+
+    frame = sys._getframe(stacklevel)
+    path = frame.f_globals['__file__']
+    if path.endswith('.pyc') or path.endswith('.pyo'):
+        path = path[:-1]
+
+    file = open(path)
+    lineno = frame.f_lineno
+    for i in range(lineno):
+        line = file.readline()
+
+    print "%s:%s: %s: %s\n  %s" % (
+        path,
+        frame.f_lineno,
+        category.__name__,
+        message,
+        line.strip(),
+        )

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/tests (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/tests)

Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py	                        (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok utility functions.
+"""
+import grok
+import zope.location.location
+from zope import interface
+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.
+
+    These could be one and the same for normal views, or different
+    in case we make method-based views such as for JSON and XMLRPC.
+    """
+    if method_names is None:
+        method_names = ['__call__']
+    if permission is not None:
+        check_permission(factory, permission)
+    if permission is None or permission == 'zope.Public':
+        checker = NamesChecker(method_names)
+    else:
+        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.
+
+    If the object provides ILocation, __parent__ and __name__ will be
+    set directly.  A location proxy will be returned otherwise.
+    """
+    if getattr(obj, '__parent__', None) is not None:
+        return obj
+    # 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.
+    """
+    # Remove all existing skin declarations (commonly the default skin).
+    ifaces = [iface for iface in interface.directlyProvidedBy(request)
+              if not skin_type.providedBy(iface)]
+    # Add the new skin.
+    ifaces.append(skin)
+    interface.directlyProvides(request, *ifaces)
+
+def _sort_key(component):
+    # If components have a grok.order directive, sort by that.
+    explicit_order, implicit_order = grok.order.bind().get(component)
+    return (explicit_order,
+            component.__module__,
+            implicit_order,
+            component.__class__.__name__)
+
+def sort_components(components):
+    return sorted(components, key=_sort_key)

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,81 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 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.
-#
-##############################################################################
-"""Grok test helpers
-"""
-import sys
-import os.path
-import z3c.testsetup
-from zope.configuration.config import ConfigurationMachine
-from grokcore.component import zcml
-# Provide this import here for BBB reasons:
-from grokcore.component.testing import grok_component
-
-class GrokTestCollector(z3c.testsetup.TestCollector):
-
-    def initialize(self):
-        # inject the grok ftesting ZCML as fallback...
-        if 'zcml_config' in self.settings.keys():
-            return
-        pkg_path = os.path.dirname(self.package.__file__)
-        if os.path.isfile(os.path.join(pkg_path, 'ftesting.zcml')):
-            return
-        self.settings['zcml_config'] = os.path.join(
-            os.path.dirname(__file__), 'ftesting.zcml')
-        if 'layer_name' in self.settings.keys():
-            return
-        self.settings['layer_name'] = 'GrokFunctionalLayer'
-
-def register_all_tests(pkg, *args, **kw):
-    return GrokTestCollector(pkg, *args, **kw)
-
-def grok(module_name):
-    config = ConfigurationMachine()
-    zcml.do_grok('grokcore.component.meta', config)
-    zcml.do_grok('grokcore.security.meta', config)
-    zcml.do_grok('grokcore.view.meta', config)
-    zcml.do_grok('grokcore.view.templatereg', config)
-    zcml.do_grok('grokcore.formlib.meta', config)
-    zcml.do_grok('grok.meta', config)
-    zcml.do_grok(module_name, config)
-    config.execute_actions()
-
-def warn(message, category=None, stacklevel=1):
-    """Intended to replace warnings.warn in tests.
-
-    Modified copy from zope.deprecation.tests to:
-
-      * make the signature identical to warnings.warn
-      * to check for *.pyc and *.pyo files.
-
-    When zope.deprecation is fixed, this warn function can be removed again.
-    """
-    print "From grok.testing's warn():"
-
-    frame = sys._getframe(stacklevel)
-    path = frame.f_globals['__file__']
-    if path.endswith('.pyc') or path.endswith('.pyo'):
-        path = path[:-1]
-
-    file = open(path)
-    lineno = frame.f_lineno
-    for i in range(lineno):
-        line = file.readline()
-
-    print "%s:%s: %s: %s\n  %s" % (
-        path,
-        frame.f_lineno,
-        category.__name__,
-        message,
-        line.strip(),
-        )

Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py	2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py	2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Grok utility functions.
-"""
-import grok
-import zope.location.location
-from zope import interface
-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.
-
-    These could be one and the same for normal views, or different
-    in case we make method-based views such as for JSON and XMLRPC.
-    """
-    if method_names is None:
-        method_names = ['__call__']
-    if permission is not None:
-        check_permission(factory, permission)
-    if permission is None or permission == 'zope.Public':
-        checker = NamesChecker(method_names)
-    else:
-        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.
-
-    If the object provides ILocation, __parent__ and __name__ will be
-    set directly.  A location proxy will be returned otherwise.
-    """
-    if getattr(obj, '__parent__', None) is not None:
-        return obj
-    # 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.
-    """
-    # Remove all existing skin declarations (commonly the default skin).
-    ifaces = [iface for iface in interface.directlyProvidedBy(request)
-              if not skin_type.providedBy(iface)]
-    # Add the new skin.
-    ifaces.append(skin)
-    interface.directlyProvides(request, *ifaces)
-
-def _sort_key(component):
-    # If components have a grok.order directive, sort by that.
-    explicit_order, implicit_order = grok.order.bind().get(component)
-    return (explicit_order,
-            component.__module__,
-            implicit_order,
-            component.__class__.__name__)
-
-def sort_components(components):
-    return sorted(components, key=_sort_key)



More information about the Checkins mailing list