[Zope-Checkins] SVN: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/ Integrate Five 1.3b.

Philipp von Weitershausen philikon at philikon.de
Wed Nov 2 12:17:43 EST 2005


Log message for revision 39847:
  Integrate Five 1.3b.
  

Changed:
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CHANGES.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CREDITS.txt
  D   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/adding.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/TrustedExpression.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/__init__.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/absoluteurl.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/adding.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/configure.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/menu.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/meta.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/metaconfigure.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/resource.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/adding.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/defaultview.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/overrides.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages_ftest.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pts_test_languages.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource_ftest.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_absoluteurl.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_defaultview.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_i18n.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_menu.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_pages.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_recurse.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_resource.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_traversable.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/configure.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/deprecated.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/directives.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/features.txt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/five14goals.txt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/localsite.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/main.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/addDemoContent.pt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/browser.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/configure.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/democontent.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/green5.png
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/event.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/eventconfigure.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fiveconfigure.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fivedirectives.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/__init__.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/metaconfigure.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.pt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/configure.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/forms.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/schemacontent.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/test_forms.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/i18n.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.py
  D   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/meta.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/metaconfigure.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/permissions.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/security.py
  D   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/services.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/browser.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/configure.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/interfaces.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/localsite.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/managesite.pt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/meta.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metaconfigure.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metadirectives.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/dummy.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/framework.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/functional.txt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/sitemanager.txt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_functional.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_localsite.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_sitemanager.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_utility.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/utility.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/standardmacros.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/tests/test_standardmacros.py
  D   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/testing/
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/README.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/boilerplate.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/directives.zcml
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/event.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_directives.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_event.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_i18n.py
  D   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_import_conflicts.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_registerclass.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_security.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_size.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_viewable.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/fancycontent.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/folder.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/restricted.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/simplecontent.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/traversable.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/configure.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/edit_markers.pt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/manage_interfaces.pt
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/marker.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/__init__.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/framework.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/test_marker.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/configure.zcml
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/interfaces.py
  A   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/marker.py
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/version.txt
  U   Zope/branches/philikon-zope32-integration/lib/python/Products/Five/viewable.py

-=-
Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CHANGES.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CHANGES.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CHANGES.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -2,6 +2,95 @@
 Five Changes
 ============
 
+Five 1.3b (2005-11-02)
+======================
+
+This version is also included in Zope 2.9b1.
+
+Restructuring
+-------------
+
+* Support for Zope 3.2 was added. Five now requires Zope 2.9 (which
+  ships with Zope 3.2).
+
+* As scheduled, the temporary fork of the new test runner
+  (``zope.testing``) at ``Five.testing`` was removed.  So was the
+  ``runtests.py`` script.  Use the regular Zope test runner
+  (``test.py`` or ``bin/zopectl test``) to run tests.
+
+* To reflect the Component Architecture simplification in Zope 3 since
+  the X3 3.0 release, ``IFiveUtilityService`` was renamed to
+  ``IFiveUtilityRegistry`` and ``SimpleLocalUtilityService`` was
+  renamed to ``SimpleLocalUtilityRegistry``.  The old names are still
+  available for a short period of time.
+
+* Event support: ``<five:containerEvents/>`` is the default.
+
+* Due to an incompatability with Zope 3.2's ObjectWidget and Zope 2's
+  Page Templates, Five now ships with its own ObjectWidget
+  implementation (which is just a thin wrapper around Zope's one to
+  make it work in Zope 2).  If you use the ObjectWidget, please change
+  your imports to ``Products.Five.form.objectwidget.ObjectWidget``.
+
+* Backwards compatability for Zope 3-style interfaces of Zope 2
+  components has been removed as that functionality is now in the Zope
+  2 core as of Zope 2.9.
+
+Five 1.2b (2005-11-02)
+======================
+
+Features
+--------
+
+* Added IMarkerInterfaces adapter: This adapter provides methods for
+  inspecting and assigning marker interfaces. 'edit-markers.html' (or
+  'manage_interfaces' in the ZMI) allows to change the behavior of specific
+  objects by adding or removing marker interfaces TTW.
+
+* Added the five:registerClass directive: This does the necessary Zope 2
+  registration for Five-based content. It is no longer necessary to add an
+  ``initialize()`` function to the product's __init__ in order to register
+  a meta type to be addable through the ZMI. See doc/products/ViewsTutorial
+  for an example how to use the directive.
+
+* Local site support: Five has now support for creating local sites
+  and thereby local utilities. This is mostly needed for allowing CMF
+  to convert it's portal tools into local utilities.  See
+  doc/localsite.txt for more information
+
+* Event support: When ``<five:containerEvents/>`` is specified, Five
+  makes the standard Zope 2 containers send events instead of using
+  manage_afterAdd, manage_beforeDelete and manage_afterClone. These
+  methods are still called for a class declared
+  ``<five:deprecatedManageAddDelete class=.../>``, and are called in
+  compatibility mode with a deprecation warning for classes that don't
+  use this directive.
+
+Restructuring
+-------------
+
+* Removed backwards compatibility for Five 1.0 Zope core interfaces.
+
+* Removed backwards compatibility for Zope 2.7 and 2.8.0.
+
+* Added a (temporarily) forked copy of the "new-and-improved" test
+  runner and supporting 'zope.testing' package, lifted from
+  http://svn.zope.org/zope.testing.  This code should be removed for
+  Five 1.3, which will use the updated version of 'zope.testing' in
+  the Zope 2.9 / Zope 3.2 tree.
+
+  There is a test runner invoking script in the ``Five`` package.  For
+  example, to run the Five tests with the new test runner, simply
+  execute the following command line from your instance home::
+
+    $ bin/zopectl run Products/Five/runtests.py -v -s Products.Five
+
+* Moved the 'Five.testing' package down to 'Five.tests.testing', in
+  order to make room for the 'zope.testing' code.
+
+* Removed backwards compatibility for some moved classes (AddForm,
+  EditForm, ContentAdding)
+
 Five 1.1 (2005-10-04)
 =====================
 
@@ -100,7 +189,7 @@
 * The former test product, ``FiveTest``, was converted into separate
   modules that provide the mock objects for the corresponding tests
   and are located right next to them.  Common test helpers have been
-  moved to the Five.testing package.  Overall, the testing framework
+  moved to the Five.tests.testing package.  Overall, the testing framework
   was much simplified and the individual tests clean up after
   themselves much like they do in Zope 3.
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CREDITS.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CREDITS.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/CREDITS.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -9,7 +9,7 @@
 
 - Lennart Regebro (regebro at nuxeo.com)
 
-- Tres Seaver (tres at zope.com)
+- Tres Seaver (tseaver at palladion.com)
 
 - Jan-Wijbrand Kolman (jw at infrae.com)
 
@@ -33,6 +33,9 @@
 
 - Tarek Ziadé (tziade at nuxeo.com)
 
+- Whit Morriss (whit at longnow.org)
+
+
 Thank you
 ---------
 

Deleted: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/adding.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/adding.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/adding.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,26 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, 2005 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.
-#
-##############################################################################
-""" Z2 -> Z3 bridge utilities.
-
-$Id: adding.py 15515 2005-08-02 17:42:08Z yuppie $
-"""
-
-# BBB: This file will be removed in future versions of Five.
-from browser.adding import ContentAdding
-
-import warnings
-warnings.warn("\nThe Products.Five.adding module has been renamed to "
-              "Products.Five.browser.adding \n"
-              "and will be disabled starting in Five 1.2.\n",
-              DeprecationWarning, stacklevel=2)

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/TrustedExpression.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/TrustedExpression.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/TrustedExpression.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -70,7 +70,7 @@
       o = get(object, name, M)
       if o is M:
         try: o = object[name]
-        except AttributeError: # better exception
+        except (AttributeError, TypeError): # better exception
           raise AttributeError(name)
     object = o
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,20 +13,13 @@
 ##############################################################################
 """Provide basic browser functionality
 
-$Id: __init__.py 18841 2005-10-23 09:57:38Z philikon $
+$Id: __init__.py 19283 2005-10-31 17:43:51Z philikon $
 """
 import Acquisition
-from AccessControl import ClassSecurityInfo
-from Globals import InitializeClass
+import zope.app.publisher.browser
 
-class BrowserView(Acquisition.Explicit):
-    security = ClassSecurityInfo()
+class BrowserView(Acquisition.Explicit, zope.app.publisher.browser.BrowserView):
+    """Five browser view
 
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-    
-    # XXX do not create any methods on the subclass called index_html,
-    # as this makes Zope 2 traverse into that first!
-
-InitializeClass(BrowserView)
+    Mixes in explicit acquisition so that security can be acquired for
+    views"""

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/absoluteurl.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/absoluteurl.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/absoluteurl.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -52,7 +52,7 @@
             return (
                 {'name': name, 'url': context.absolute_url()},)
 
-        view = zapi.getViewProviding(container, IAbsoluteURL, request)
+        view = zapi.getMultiAdapter((container, request), IAbsoluteURL)
         base = tuple(view.breadcrumbs())
         base += (
             {'name': name, 'url': ("%s/%s" % (base[-1]['url'], name))},)

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/adding.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/adding.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/adding.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -28,6 +28,8 @@
 from zope.app.container.interfaces import IContainerNamesContainer
 from zope.app.container.constraints import checkFactory, checkObject
 
+from zope.app.publisher.browser.menu import getMenu
+
 from zope.app import zapi
 from zope.app.event.objectevent import ObjectCreatedEvent
 from zope.event import notify
@@ -84,8 +86,8 @@
         # XXX this is definitely not right for all or even most uses
         # of Five, but can be overridden by an AddView subclass, using
         # the class attribute of a zcml:addform directive
-        return (str(zapi.getView(self.context, "absolute_url", self.request))
-                + '/manage_main')
+        return str(zapi.getMultiAdapter((self.context, self.request),
+                                        name=u"absolute_url")) + '/manage_main'
 
     # set in BrowserView.__init__
     request = None 
@@ -104,7 +106,7 @@
 
             if view_name.startswith('@@'):
                 view_name = view_name[2:]
-            return zapi.getView(self, view_name, request)
+            return zapi.getMultiAdapter((self, request), name=view_name)
 
         if name.startswith('@@'):
             view_name = name[2:]
@@ -135,7 +137,7 @@
 
         if zapi.queryView(self, view_name, self.request) is not None:
             url = "%s/%s=%s" % (
-                zapi.getView(self, "absolute_url", self.request),
+                zapi.getMultiAdapter((self, self.request), name=u"absolute_url"),
                 type_name, id)
             self.request.response.redirect(url)
             return
@@ -169,12 +171,11 @@
         This is sorted by title.
         """
         container = self.context
-        menu_service = zapi.getService("BrowserMenu")
         result = []
         for menu_id in (self.menu_id, 'zope.app.container.add'):
             if not menu_id:
                 continue
-            for item in menu_service.getMenu(menu_id, self, self.request):
+            for item in getMenu(menu_id, self, self.request):
                 extra = item.get('extra')
                 if extra:
                     factory = extra.get('factory')

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,17 +1,6 @@
 <configure xmlns="http://namespaces.zope.org/zope"
            xmlns:browser="http://namespaces.zope.org/browser">
 
-  <serviceType
-      id="BrowserMenu"
-      interface="zope.app.publisher.interfaces.browser.IBrowserMenuService"
-      />
-
-  <service
-      serviceType="BrowserMenu"
-      permission="zope.Public"
-      component="zope.app.publisher.browser.globalbrowsermenuservice.globalBrowserMenuService"
-      />
-
   <browser:defaultView name="index.html" />
 
   <browser:page

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/menu.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/menu.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/menu.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,17 +13,15 @@
 ##############################################################################
 """Some menu code
 
-$Id: menu.py 14512 2005-07-11 18:40:51Z philikon $
+$Id: menu.py 19283 2005-10-31 17:43:51Z philikon $
 """
 from zope.interface import implements
-from zope.app import zapi
 from zope.app.publisher.interfaces.browser import IMenuAccessView
-from zope.app.servicenames import BrowserMenu
+from zope.app.publisher.browser.menu import getMenu
 from Products.Five import BrowserView
 
 class MenuAccessView(BrowserView):
     implements(IMenuAccessView)
 
     def __getitem__(self, menu_id):
-        browser_menu_service = zapi.getService(BrowserMenu)
-        return browser_menu_service.getMenu(menu_id, self.context, self.request)
+        return getMenu(menu_id, self.context, self.request)

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/meta.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/meta.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/meta.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -25,7 +25,7 @@
     <meta:directive
         name="defaultView"
         schema="zope.app.publisher.browser.metadirectives.IDefaultViewDirective"
-        handler=".metaconfigure.defaultView"
+        handler="zope.app.publisher.browser.metaconfigure.defaultView"
         />
 
     <meta:directive
@@ -62,19 +62,19 @@
     <meta:directive
         name="menu"
         schema="zope.app.publisher.browser.metadirectives.IMenuDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuDirective"
+        handler="zope.app.publisher.browser.menumeta.menuDirective"
         />
 
     <meta:directive
         name="menuItem"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemDirective"
+        handler="zope.app.publisher.browser.menumeta.menuItemDirective"
         />
 
     <meta:complexDirective
         name="menuItems"
         schema="zope.app.publisher.browser.metadirectives.IMenuItemsDirective"
-        handler="zope.app.publisher.browser.globalbrowsermenuservice.menuItemsDirective"
+        handler="zope.app.publisher.browser.menumeta.menuItemsDirective"
         >
 
       <meta:subdirective

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/metaconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/metaconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/metaconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -21,18 +21,16 @@
 import os
 
 from zope.interface import Interface
-from zope.component import getGlobalService, ComponentLookupError
 from zope.configuration.exceptions import ConfigurationError
-from zope.component.servicenames import Presentation
-from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserRequest, \
+     IDefaultBrowserLayer
+
 from zope.app.publisher.browser.viewmeta import pages as zope_app_pages
 from zope.app.publisher.browser.viewmeta import view as zope_app_view
-from zope.app.publisher.browser.viewmeta import providesCallable
-from zope.app.publisher.browser.globalbrowsermenuservice import\
-     menuItemDirective
+from zope.app.publisher.browser.viewmeta import providesCallable, \
+     _handle_menu, _handle_for
 from zope.app.component.metaconfigure import handler
 from zope.app.component.interface import provideInterface
-from zope.app.container.interfaces import IAdding
 
 from Products.Five.browser import BrowserView
 from Products.Five.browser.resource import FileResourceFactory, ImageResourceFactory
@@ -40,22 +38,16 @@
 from Products.Five.browser.resource import DirectoryResourceFactory
 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
 from Products.Five.metaclass import makeClass
-from Products.Five.security import getSecurityInfo, protectClass, \
-    protectName, initializeClass
+from Products.Five.security import getSecurityInfo, protectClass, protectName
 
-import ExtensionClass
+from Globals import InitializeClass as initializeClass
 
 def page(_context, name, permission, for_,
-         layer='default', template=None, class_=None,
+         layer=IDefaultBrowserLayer, template=None, class_=None,
          allowed_interface=None, allowed_attributes=None,
          attribute='__call__', menu=None, title=None,
          ):
 
-    try:
-        s = getGlobalService(Presentation)
-    except ComponentLookupError, err:
-        pass
-
     _handle_menu(_context, menu, title, [for_], name, permission)
 
     if not (class_ or template):
@@ -64,8 +56,7 @@
         allowed_attributes = []
     if allowed_interface is not None:
         for interface in allowed_interface:
-            attrs = [n for n, d in interface.namesAndDescriptions(1)]
-            allowed_attributes.extend(attrs)
+            allowed_attributes.extend(interface.names())
 
     if attribute != '__call__':
         if template:
@@ -92,9 +83,10 @@
                     "The provided class doesn't have the specified attribute "
                     )
         cdict = getSecurityInfo(class_)
+        cdict['__name__'] = name
         if template:
             new_class = makeClassForTemplate(template, bases=(class_, ),
-                                             cdict=cdict)
+                                             cdict=cdict, name=name)
         elif attribute != "__call__":
             # we're supposed to make a page for an attribute (read:
             # method) and it's not __call__.  We thus need to create a
@@ -125,16 +117,15 @@
 
     else:
         # template
-        new_class = makeClassForTemplate(template)
+        new_class = makeClassForTemplate(template, name=name)
 
     _handle_for(_context, for_)
 
     _context.action(
         discriminator = ('view', for_, name, IBrowserRequest, layer),
         callable = handler,
-        args = (Presentation, 'provideAdapter',
-                IBrowserRequest, new_class, name, [for_], Interface, layer,
-                _context.info),
+        args = ('provideAdapter',
+                (for_, layer), Interface, name, new_class, _context.info),
         )
     _context.action(
         discriminator = ('five:protectClass', new_class),
@@ -165,19 +156,6 @@
                     menu=menu, title=title,
                     **(self.opts))
 
-def defaultView(_context, name, for_=None):
-
-    type = IBrowserRequest
-
-    _context.action(
-        discriminator = ('defaultViewName', for_, type, name),
-        callable = handler,
-        args = (Presentation,
-                'setDefaultViewName', for_, type, name),
-        )
-
-    _handle_for(_context, for_)
-
 # view (named view with pages)
 
 class view(zope_app_view):
@@ -192,11 +170,6 @@
         pages = {}
 
         for pname, attribute, template in self.pages:
-            try:
-                s = getGlobalService(Presentation)
-            except ComponentLookupError, err:
-                pass
-
             if template:
                 cdict[pname] = ZopeTwoPageTemplateFile(template)
                 if attribute and attribute != name:
@@ -255,7 +228,7 @@
         if class_ is not None:
             bases = (class_, ViewMixinForTemplates)
         else:
-            bases = (ViewMixinForTemplates)
+            bases = (ViewMixinForTemplates,)
 
         try:
             cname = str(name)
@@ -277,37 +250,11 @@
             discriminator = ('view', for_, name, IBrowserRequest, layer,
                              self.provides),
             callable = handler,
-            args = (Presentation, 'provideAdapter',
-                    IBrowserRequest, newclass, name, [for_],  self.provides,
-                    layer, _context.info),
+            args = ('provideAdapter',
+                    (for_, layer), self.provides, name, newclass,
+                    _context.info),
             )
 
-def _handle_for(_context, for_):
-    if for_ is not None:
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = ('', for_)
-            )
-
-def _handle_menu(_context, menu, title, for_, name, permission):
-    if menu or title:
-        if not (menu and title):
-            raise ConfigurationError(
-                "If either menu or title are specified, they must "
-                "both be specified.")
-
-        if len(for_) != 1:
-            raise ConfigurationError(
-                "Menus can be specified only for single-view, not for "
-                "multi-views.")
-
-        return menuItemDirective(
-            _context, menu, for_[0], '@@' + str(name), title,
-            permission=permission)
-
-    return []
-
 _factory_map = {'image':{'prefix':'ImageResource',
                          'count':0,
                          'factory':ImageResourceFactory},
@@ -319,7 +266,7 @@
                             'factory':PageTemplateResourceFactory}
                 }
 
-def resource(_context, name, layer='default', permission='zope.Public',
+def resource(_context, name, layer=IDefaultBrowserLayer, permission='zope.Public',
              file=None, image=None, template=None):
 
     if ((file and image) or (file and template) or
@@ -343,8 +290,8 @@
     _context.action(
         discriminator = ('resource', name, IBrowserRequest, layer),
         callable = handler,
-        args = (Presentation, 'provideResource',
-                name, IBrowserRequest, factory, layer),
+        args = ('provideAdapter',
+                (layer,), Interface, name, factory, _context.info),
         )
     _context.action(
         discriminator = ('five:protectClass', new_class),
@@ -367,7 +314,7 @@
                                      'count':0}
            }
 
-def resourceDirectory(_context, name, directory, layer='default',
+def resourceDirectory(_context, name, directory, layer=IDefaultBrowserLayer,
                       permission='zope.Public'):
 
     if not os.path.isdir(directory):
@@ -410,8 +357,8 @@
     _context.action(
         discriminator = ('resource', name, IBrowserRequest, layer),
         callable = handler,
-        args = (Presentation, 'provideResource',
-                name, IBrowserRequest, factory, layer),
+        args = ('provideAdapter',
+                (layer,), Interface, name, factory, _context.info),
         )
     for new_class in new_classes:
         _context.action(
@@ -456,11 +403,12 @@
         return self.index(self, *args, **kw)
 
 def makeClassForTemplate(filename, globals=None, used_for=None,
-                         bases=(), cdict=None):
+                         bases=(), cdict=None, name=u''):
     # XXX needs to deal with security from the bases?
     if cdict is None:
         cdict = {}
-    cdict.update({'index': ZopeTwoPageTemplateFile(filename, globals)})
+    cdict.update({'index': ZopeTwoPageTemplateFile(filename, globals),
+                  '__name__': name})
     bases += (ViewMixinForTemplates,)
     class_ = makeClass("SimpleViewClass from %s" % filename, bases, cdict)
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/resource.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/resource.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/resource.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -18,15 +18,15 @@
 import os
 import urllib
 
-from Acquisition import Explicit
+import Acquisition
 from ComputedAttribute import ComputedAttribute
 from OFS.Traversable import Traversable as OFSTraversable
 
-from zope.exceptions import NotFoundError
 from zope.interface import implements
 from zope.component.interfaces import IResource
-from zope.component import getViewProviding
 from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.app import zapi
 from zope.app.traversing.browser.interfaces import IAbsoluteURL
 from zope.app.datetimeutils import time as timeFromDateTimeString
 from zope.app.publisher.fileresource import File, Image
@@ -37,7 +37,7 @@
 
 _marker = []
 
-class Resource(Explicit):
+class Resource(Acquisition.Explicit):
     """A publishable resource
     """
     implements(IResource)
@@ -49,7 +49,9 @@
         name = self.__name__
         container = self.__parent__
 
-        url = str(getViewProviding(container, IAbsoluteURL, self.request))
+        # TODO Zope 3 uses site = getSite() instead of container here
+        # and the @@ resource access view
+        url = str(zapi.getMultiAdapter((container, self.request), IAbsoluteURL))
         url = urllib.unquote(url)
         if not isinstance(container, DirectoryResource):
             name = '++resource++%s' % name
@@ -213,7 +215,7 @@
         filename = os.path.join(path, name)
         if not os.path.isfile(filename):
             if default is _marker:
-                raise NotFoundError(name)
+                raise KeyError(name)
             return default
         ext = name.split('.')[-1]
         factory = self.resource_factories.get(ext, self.default_factory)

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/adding.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/adding.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/adding.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -7,7 +7,7 @@
 
 First we need to import and setup some prerequisites:
 
-  >>> from Products.Five.testing import manage_addFiveTraversableFolder
+  >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
   >>> from Products.Five.browser.adding import ObjectManagerNameChooser
 
   >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/defaultview.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/defaultview.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/defaultview.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -3,15 +3,15 @@
            xmlns:five="http://namespaces.zope.org/five">
 
   <five:defaultViewable
-      class="Products.Five.testing.simplecontent.SimpleContent" />
+      class="Products.Five.tests.testing.simplecontent.SimpleContent" />
 
   <browser:defaultView
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       name="eagledefaultview.txt"
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       name="eagledefaultview.txt"
       class=".pages.SimpleView"
       attribute="eagle"
@@ -22,16 +22,16 @@
        already provides __call__, such as our CallableSimpleContent -->
 
   <five:defaultViewable
-      class="Products.Five.testing.simplecontent.CallableSimpleContent" />
+      class="Products.Five.tests.testing.simplecontent.CallableSimpleContent" />
 
   <!-- this tests whether five:defaultViewable can be called on a class that
        already provides index_html, such as our IndexSimpleContent -->
 
   <five:defaultViewable
-      class="Products.Five.testing.simplecontent.IndexSimpleContent" />
+      class="Products.Five.tests.testing.simplecontent.IndexSimpleContent" />
 
   <browser:defaultView
-      for="Products.Five.testing.simplecontent.IIndexSimpleContent"
+      for="Products.Five.tests.testing.simplecontent.IIndexSimpleContent"
       name="index_html"
       />
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/overrides.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/overrides.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/overrides.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -3,11 +3,11 @@
 
   <!-- mouse instead of eagle -->
   <browser:page
-    for="Products.Five.testing.simplecontent.ISimpleContent"
+    for="Products.Five.tests.testing.simplecontent.ISimpleContent"
     class=".pages.SimpleView"
     attribute="mouse"
     name="overridden_view"
     permission="zope2.Public"
     />
 
-</configure>
\ No newline at end of file
+</configure>

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -34,6 +34,11 @@
     def view(self):
         return "Fancy, fancy"
 
+class CallView(BrowserView):
+
+    def __call__(self):
+        return "I was __call__()'ed"
+
 class CallableNoDocstring:
 
     def __call__(self):

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -10,7 +10,7 @@
 
 Let's add a test object that we view most of the pages off of:
 
-  >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
+  >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
   >>> manage_addSimpleContent(self.folder, 'testoid', 'Testoid')
 
 We also need to create a stub user account and login; otherwise we
@@ -29,7 +29,7 @@
 A browser page that is a view class's attribute (method):
 
   >>> view = self.folder.unrestrictedTraverse('testoid/eagle.txt')
-  >>> view != None
+  >>> view is not None
   True
   >>> from Products.Five.browser.tests.pages import SimpleView
   >>> isinstance(view, SimpleView)
@@ -196,8 +196,10 @@
 
   >>> from Products.Five.traversable import FakeRequest
   >>> from zope.app import zapi
+  >>> from zope.app.publication.browser import setDefaultSkin
   >>> request = FakeRequest()
-  >>> view = zapi.getView(self.folder.testoid, 'eagle.txt', request)
+  >>> setDefaultSkin(request)
+  >>> view = zapi.getMultiAdapter((self.folder.testoid, request), name=u'eagle.txt')
 
 It's protecting the object with the permission, and not the attribute,
 so we get ('',) instead of ('eagle',):
@@ -213,7 +215,7 @@
   >>> view_roles
   ('Manager',)
 
-Check to see if view's context properly acquires it's true
+Check to see if view's context properly acquires its true
 parent
 
   >>> from Acquisition import aq_parent, aq_base, aq_inner
@@ -255,8 +257,8 @@
   ...     'nodoc-method', 'nodoc-function', 'nodoc-object',
   ...     'dirpage1', 'dirpage2']
 
-  >>> from Products.Five.testing.restricted import checkRestricted
-  >>> from Products.Five.testing.restricted import checkUnauthorized
+  >>> from Products.Five.tests.testing.restricted import checkRestricted
+  >>> from Products.Five.tests.testing.restricted import checkUnauthorized
 
 As long as we're not authenticated, we should get Unauthorized for
 protected views, but we should be able to view the public ones:
@@ -312,5 +314,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -8,7 +8,7 @@
 
   <!-- attribute page -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       attribute="eagle"
       name="eagle.txt"
@@ -16,7 +16,7 @@
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       name="eagle.method"
       permission="zope2.ViewManagementScreens"
@@ -25,7 +25,7 @@
 
   <!-- attribute page -->
   <browser:pages
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       permission="zope2.ViewManagementScreens"
       >
@@ -41,7 +41,7 @@
 
   <!-- template/class page -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       template="falcon.pt"
       name="falcon.html"
@@ -50,7 +50,7 @@
 
   <!-- template page (with simple python expression) -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="owl.pt"
       name="owl.html"
       permission="zope2.ViewManagementScreens"
@@ -59,7 +59,7 @@
   <!-- template page which calls on context using python and path
        expressions -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="flamingo.pt"
       name="flamingo.html"
       permission="zope2.ViewManagementScreens"
@@ -67,7 +67,7 @@
 
   <!-- template/class page which calls on context, view, views -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       template="condor.pt"
       name="condor.html"
@@ -76,7 +76,7 @@
 
   <!-- template page that defines a macro page -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="birdmacro.pt"
       name="bird.html"
       permission="zope2.ViewManagementScreens"
@@ -84,7 +84,7 @@
 
   <!-- template page that uses macro page -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="seagull.pt"
       name="seagull.html"
       permission="zope2.ViewManagementScreens"
@@ -92,21 +92,21 @@
 
   <!-- test TALES -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="ostrich.pt"
       name="ostrich.html"
       permission="zope2.ViewManagementScreens"
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="tales_traversal.pt"
       name="tales_traversal.html"
       permission="zope2.ViewManagementScreens"
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="template_variables.pt"
       name="template_variables.html"
       permission="zope2.ViewManagementScreens"
@@ -115,7 +115,7 @@
   <!-- template security -->
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="security.pt"
       name="security.html"
       permission="zope2.View"
@@ -124,7 +124,7 @@
   <!-- a publicly accessible page, attribute, template, template/class -->
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       attribute="eagle"
       name="public_attribute_page"
@@ -132,14 +132,14 @@
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       template="owl.pt"
       name="public_template_page"
       permission="zope2.Public"
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       template="falcon.pt"
       name="public_template_class_page"
@@ -147,16 +147,23 @@
       />
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       template="parakeet.pt"
       name="parakeet.html"
       permission="zope2.ViewManagementScreens"
       />
 
+  <browser:page
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
+      class=".pages.CallView"
+      name="callview.html"
+      permission="zope2.Public"
+      />
+
   <!-- pages from methods/functions/callables that don't have docstrings -->
   <browser:pages
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class="Products.Five.browser.tests.pages.NoDocstringView"
       permission="zope2.Public">
     <browser:page
@@ -177,7 +184,7 @@
        This is mainly used to load Zope2 skin templates so they can be used
        in five skins and layers. -->
   <five:pagesFromDirectory
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       module="Products.Five.browser.tests"
       directory="pages"
       permission="zope2.Public"
@@ -186,7 +193,7 @@
   <!-- browser:page directives with new style classes are ignored -->
 
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.NewStyleClass"
       name="new_style_class"
       attribute="method"
@@ -198,7 +205,7 @@
 
   <browser:view
       name=""
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       permission="zope2.Public"
       />
@@ -207,18 +214,18 @@
 
   <!-- protected edit form for permission check -->
   <browser:editform
-      schema="Products.Five.testing.simplecontent.ISimpleContent"
+      schema="Products.Five.tests.testing.simplecontent.ISimpleContent"
       name="protectededitform.html"
       permission="zope2.ViewManagementScreens"
       />
 
   <!-- stuff that we'll override in overrides.zcml -->
   <browser:page
-      for="Products.Five.testing.simplecontent.ISimpleContent"
+      for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       class=".pages.SimpleView"
       attribute="eagle"
       name="overridden_view"
       permission="zope2.Public"
       />
 
-</configure>
\ No newline at end of file
+</configure>

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages_ftest.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages_ftest.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pages_ftest.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -11,7 +11,7 @@
 
 Let's also add one of our stub objects to play with:
 
-  >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
+  >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
   >>> manage_addSimpleContent(self.folder, 'testoid', 'Testoid')
 
 
@@ -122,8 +122,23 @@
   ...     self.failUnless(status == 200, (status, 200, view_name))
 
 
+Miscellaneous
+-------------
+
+Zope 2 always wants objects in the traversal graph to have a __name__.
+That is also true for views, e.g. a view constructed from a simple
+class bearing only a __call__ method:
+
+  >>> print http(r'''
+  ... GET /test_folder_1_/testoid/callview.html HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 OK
+  ...
+  I was __call__()'ed
+
+
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pts_test_languages.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pts_test_languages.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/pts_test_languages.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -42,7 +42,7 @@
 Finally, we need a traversable folder so that the test page we
 registered is found:
 
-  >>> from Products.Five.testing import manage_addFiveTraversableFolder
+  >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
   >>> manage_addFiveTraversableFolder(self.folder, 'ftf')
 
 Now for some actual testing... Our test page is a simple ZPT

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -8,7 +8,7 @@
   >>> zcml.load_config("configure.zcml", Products.Five)
   >>> zcml.load_config('resource.zcml', package=Products.Five.browser.tests)
 
-  >>> from Products.Five.testing import manage_addFiveTraversableFolder
+  >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
   >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
 
   >>> import os, glob
@@ -73,8 +73,8 @@
 Security
 --------
 
-  >>> from Products.Five.testing.restricted import checkRestricted
-  >>> from Products.Five.testing.restricted import checkUnauthorized
+  >>> from Products.Five.tests.testing.restricted import checkRestricted
+  >>> from Products.Five.tests.testing.restricted import checkUnauthorized
 
   >>> resource_names = ['cockatiel.html', 'style.css', 'pattern.png']
 
@@ -112,5 +112,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource_ftest.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource_ftest.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/resource_ftest.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -8,7 +8,7 @@
   >>> zcml.load_config("configure.zcml", Products.Five)
   >>> zcml.load_config('resource.zcml', package=Products.Five.browser.tests)
 
-  >>> from Products.Five.testing import manage_addFiveTraversableFolder
+  >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
   >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
 
   >>> import os, glob
@@ -69,5 +69,5 @@
 Clean up
 --------
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_absoluteurl.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_absoluteurl.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_absoluteurl.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -29,7 +29,7 @@
       >>> from Products.Five import zcml
       >>> zcml.load_config("configure.zcml", Products.Five)
 
-      >>> from Products.Five.testing import manage_addFiveTraversableFolder
+      >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
       >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
 
     A simple traversal will yield us the @@absolute_url view:
@@ -86,7 +86,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_defaultview.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_defaultview.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_defaultview.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -33,9 +33,9 @@
 
     Now let's add a couple of stub objects:
 
-      >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
-      >>> from Products.Five.testing.simplecontent import manage_addCallableSimpleContent
-      >>> from Products.Five.testing.simplecontent import manage_addIndexSimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addCallableSimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addIndexSimpleContent
 
       >>> manage_addSimpleContent(self.folder, 'testoid', 'Testoid')
       >>> manage_addCallableSimpleContent(self.folder, 'testcall', 'TestCall')
@@ -79,7 +79,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_i18n.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_i18n.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_i18n.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -33,7 +33,7 @@
       ...   </configure>
       ...   <configure package="Products.Five.browser.tests">
       ...     <browser:page
-      ...         for="Products.Five.interfaces.IFolder"
+      ...         for="OFS.interfaces.IFolder"
       ...         template="i18n.pt"
       ...         name="i18n.html"
       ...         permission="zope2.View"
@@ -49,7 +49,7 @@
     In order to be able to traverse to the PageTemplate view, we need
     a traversable object:
 
-      >>> from Products.Five.testing import manage_addFiveTraversableFolder
+      >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
       >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
 
     We tell Zope to translate the messages by passing the
@@ -80,7 +80,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_menu.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_menu.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_menu.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -28,7 +28,8 @@
 
       >>> import Products.Five.browser.tests
       >>> from Products.Five import zcml
-      >>> zcml.load_config("configure.zcml", Products.Five)
+      >>> zcml.load_config("meta.zcml", Products.Five)
+      >>> zcml.load_config("permissions.zcml", Products.Five)
       >>> zcml.load_config('menu.zcml', package=Products.Five.browser.tests)
 
       >>> from Products.Five.security import newInteraction
@@ -37,12 +38,12 @@
     Now for some actual testing... Let's look up the menu we registered:
 
       >>> from Products.Five.traversable import FakeRequest
-      >>> from zope.app.publisher.browser.globalbrowsermenuservice import \\
-      ...     globalBrowserMenuService
+      >>> from zope.app.publication.browser import setDefaultSkin
+      >>> from zope.app.publisher.browser.menu import getMenu
 
       >>> request = FakeRequest()
-      >>> menu = globalBrowserMenuService.getMenu(
-      ...     'testmenu', self.folder, request)
+      >>> setDefaultSkin(request)
+      >>> menu = getMenu('testmenu', self.folder, request)
 
     It should have 
 
@@ -53,28 +54,42 @@
 
       >>> menu.sort(lambda x, y: cmp(x['title'], y['title']))
       >>> from pprint import pprint
-      >>> pprint(menu)
-      [{'action': '@@cockatiel_menu_public.html',
-        'description': '',
-        'extra': None,
-        'selected': '',
-        'title': u'Page in a menu (public)'},
-       {'action': u'seagull.html',
-        'description': u'This is a test menu item',
-        'extra': None,
-        'selected': '',
-        'title': u'Test Menu Item'},
-       {'action': u'parakeet.html',
-        'description': u'This is a test menu item',
-        'extra': None,
-        'selected': '',
-        'title': u'Test Menu Item 2'},
-       {'action': u'falcon.html',
-        'description': u'This is a test menu item',
-        'extra': None,
-        'selected': '',
-        'title': u'Test Menu Item 3'}]
+      >>> pprint(menu[0])
+      {'action': u'@@cockatiel_menu_public.html',
+       'description': u'',
+       'extra': None,
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Page in a menu (public)'}
 
+      >>> pprint(menu[1])
+      {'action': u'seagull.html',
+       'description': u'This is a test menu item',
+       'extra': None,
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Test Menu Item'}
+
+      >>> pprint(menu[2])
+      {'action': u'parakeet.html',
+       'description': u'This is a test menu item',
+       'extra': None,
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Test Menu Item 2'}
+
+      >>> pprint(menu[3])
+      {'action': u'falcon.html',
+       'description': u'This is a test menu item',
+       'extra': None,
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Test Menu Item 3'}
+
     Let's create a manager user account and log in.
 
       >>> uf = self.folder.acl_users
@@ -82,8 +97,7 @@
       >>> self.login('manager')
       >>> newInteraction()
 
-      >>> menu = globalBrowserMenuService.getMenu(
-      ...     'testmenu', self.folder, request)
+      >>> menu = getMenu('testmenu', self.folder, request)
 
     We should get the protected menu items now:
 
@@ -91,47 +105,73 @@
       7
 
       >>> menu.sort(lambda x, y: cmp(x['title'], y['title']))
-      >>> pprint(menu)
-      [{'action': '@@cockatiel_menu_protected.html',
-        'description': '',
-        'extra': None,
-        'selected': '',
-        'title': u'Page in a menu (protected)'},
-       {'action': '@@cockatiel_menu_public.html',
-       'description': '',
+      >>> pprint(menu[0])
+      {'action': u'@@cockatiel_menu_protected.html',
+       'description': u'',
        'extra': None,
-       'selected': '',
-       'title': u'Page in a menu (public)'},
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Page in a menu (protected)'}
+
+      >>> pprint(menu[1])
+      {'action': u'@@cockatiel_menu_public.html',
+       'description': u'',
+       'extra': None,
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Page in a menu (public)'}
+
+      >>> pprint(menu[2])
       {'action': u'seagull.html',
        'description': u'This is a protected test menu item',
        'extra': None,
-       'selected': '',
-       'title': u'Protected Test Menu Item'},
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Protected Test Menu Item'}
+
+      >>> pprint(menu[3])
       {'action': u'falcon.html',
        'description': u'This is a protected test menu item',
        'extra': None,
-       'selected': '',
-       'title': u'Protected Test Menu Item 2'},
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Protected Test Menu Item 2'}
+
+      >>> pprint(menu[4])
       {'action': u'seagull.html',
        'description': u'This is a test menu item',
        'extra': None,
-       'selected': '',
-       'title': u'Test Menu Item'},
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Test Menu Item'}
+
+      >>> pprint(menu[5])
       {'action': u'parakeet.html',
        'description': u'This is a test menu item',
        'extra': None,
-       'selected': '',
-        'title': u'Test Menu Item 2'},
+       'icon': None,
+       'selected': u'', 
+       'submenu': None,
+       'title': u'Test Menu Item 2'}
+
+      >>> pprint(menu[6])
       {'action': u'falcon.html',
        'description': u'This is a test menu item',
        'extra': None,
-       'selected': '',
-       'title': u'Test Menu Item 3'}]
+       'icon': None,
+       'selected': u'',
+       'submenu': None,
+       'title': u'Test Menu Item 3'}
 
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_pages.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_pages.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_pages.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -26,7 +26,7 @@
       >>> zcml.load_config("configure.zcml", Products.Five)
       >>> zcml.load_config('pages.zcml', package=Products.Five.browser.tests)
 
-      >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
       >>> manage_addSimpleContent(self.folder, 'testoid', 'Testoid')
       >>> uf = self.folder.acl_users
       >>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
@@ -56,7 +56,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 
@@ -65,11 +65,10 @@
     from Testing.ZopeTestCase import installProduct, ZopeDocTestSuite
     from Testing.ZopeTestCase import ZopeDocFileSuite
     from Testing.ZopeTestCase import FunctionalDocFileSuite
-    installProduct('PythonScripts')  # for Five.testing.restricted
+    installProduct('PythonScripts')  # for Five.tests.testing.restricted
     return unittest.TestSuite((
         ZopeDocTestSuite(),
-        ZopeDocFileSuite('pages.txt',
-                         package='Products.Five.browser.tests'),
+        ZopeDocFileSuite('pages.txt', package='Products.Five.browser.tests'),
         FunctionalDocFileSuite('pages_ftest.txt',
                                package='Products.Five.browser.tests')
         ))

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_recurse.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_recurse.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_recurse.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -23,9 +23,6 @@
     """
     Test recursion
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
-      >>> setUp()
-
     This test makes sure that recursion is avoided for view lookup.
     First, we need to set up a stub interface...
 
@@ -51,10 +48,10 @@
       >>> from Products.Five.fiveconfigure import classDefaultViewable
       >>> classDefaultViewable(Recurse)
 
-      >>> from zope.app import zapi
+      >>> from zope.component import provideAdapter
       >>> from zope.publisher.interfaces.browser import IBrowserRequest
-      >>> pres = zapi.getGlobalService('Presentation')
-      >>> pres.setDefaultViewName(IRecurse, IBrowserRequest, 'view')
+      >>> from zope.component.interfaces import IDefaultViewName
+      >>> provideAdapter(u'view', (IRecurse, IBrowserRequest), IDefaultViewName)
 
     Here comes the actual test:
 
@@ -65,9 +62,10 @@
       'foo'
 
 
-    Clean up:
+    Clean up adapter registry and monkey patches to classes:
 
-      >>> tearDown()
+      >>> from zope.testing.cleanup import cleanUp
+      >>> cleanUp()
     """
 
 def test_suite():

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_resource.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_resource.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_resource.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -23,7 +23,7 @@
     import unittest
     from Testing.ZopeTestCase import installProduct, ZopeDocFileSuite
     from Testing.ZopeTestCase import FunctionalDocFileSuite
-    installProduct('PythonScripts')  # for Five.testing.restricted
+    installProduct('PythonScripts')  # for Five.tests.testing.restricted
     return unittest.TestSuite((
             ZopeDocFileSuite('resource.txt',
                              package='Products.Five.browser.tests'),

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_traversable.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_traversable.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/browser/tests/test_traversable.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -33,7 +33,7 @@
     the wrong reason: None doesn't have a docstring so BaseRequest
     raises NotFoundError.)
 
-      >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
       >>> manage_addSimpleContent(self.folder, 'testoid', 'Testoid')
       >>> print http(r'''
       ... GET /test_folder_1_/testoid/doesntexist HTTP/1.1
@@ -54,21 +54,21 @@
       ... <meta:redefinePermission from="zope2.Public" to="zope.Public" />
       ... 
       ... <five:traversable
-      ...     class="Products.Five.testing.fancycontent.FancyContent"
+      ...     class="Products.Five.tests.testing.fancycontent.FancyContent"
       ...     />
       ... 
       ... <browser:page
-      ...     for="Products.Five.testing.fancycontent.IFancyContent"
+      ...     for="Products.Five.tests.testing.fancycontent.IFancyContent"
       ...     class="Products.Five.browser.tests.pages.FancyView"
       ...     attribute="view"
-      ...     name="fancy"
+      ...     name="fancyview"
       ...     permission="zope2.Public"
       ...     />
       ... 
       ... </configure>'''
       >>> zcml.load_string(configure_zcml)
 
-      >>> from Products.Five.testing.fancycontent import manage_addFancyContent
+      >>> from Products.Five.tests.testing.fancycontent import manage_addFancyContent
       >>> info = manage_addFancyContent(self.folder, 'fancy', '')
 
     In the following test we let the original __bobo_traverse__ method
@@ -85,7 +85,7 @@
     actually works:
 
       >>> print http(r'''
-      ... GET /test_folder_1_/fancy/fancy HTTP/1.1
+      ... GET /test_folder_1_/fancy/fancyview HTTP/1.1
       ... ''')
       HTTP/1.1 200 OK
       ...
@@ -94,7 +94,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -2,13 +2,15 @@
            xmlns:five="http://namespaces.zope.org/five">
 
   <include file="meta.zcml" />
-  <include file="services.zcml" />
-  <include file="interfaces.zcml" />
   <include file="permissions.zcml" />
   <include file="i18n.zcml" />
+  <include file="event.zcml"/>
+  <include file="deprecated.zcml"/>
+  <include package=".site" />
   <include package=".browser" />
   <include package=".form" />
   <include package=".skin" />
+  <include package=".utilities" />
 
   <include package="zope.app.event" />
   <include package="zope.app.traversing" />

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/deprecated.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/deprecated.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/deprecated.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,51 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:five="http://namespaces.zope.org/five">
+
+  <!-- deprecated in core Zope, should be fixed there in Zope 2.9 -->
+
+  <five:deprecatedManageAddDelete
+      class="AccessControl.User.BasicUserFolder"/>
+
+  <five:deprecatedManageAddDelete
+      class="App.Factory.Factory"/>
+  <five:deprecatedManageAddDelete
+      class="App.Permission.Permission"/>
+
+  <five:deprecatedManageAddDelete
+      class="HelpSys.HelpTopic.HelpTopicBase"/>
+
+  <five:deprecatedManageAddDelete
+      class="OFS.Cache.CacheManager"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.OFSP.Draft.Draft"/>
+  <five:deprecatedManageAddDelete
+      class="Products.OFSP.Version.Version"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.PythonScripts.PythonScript.PythonScript"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.Sessions.BrowserIdManager.BrowserIdManager"/>
+  <five:deprecatedManageAddDelete
+      class="Products.Sessions.SessionDataManager.SessionDataManager"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.SiteAccess.VirtualHostMonster.VirtualHostMonster"/>
+  <five:deprecatedManageAddDelete
+      class="Products.SiteAccess.SiteRoot.Traverser"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.SiteErrorLog.SiteErrorLog.SiteErrorLog"/>
+
+  <five:deprecatedManageAddDelete
+      class="Products.ZCatalog.CatalogAwareness.CatalogAware"/>
+  <five:deprecatedManageAddDelete
+      class="Products.ZCatalog.CatalogPathAwareness.CatalogAware"/>
+
+  <five:deprecatedManageAddDelete
+      class="ZClasses.Property.ZCommonSheet"/>
+  <five:deprecatedManageAddDelete
+      class="ZClasses.ZClass.ZClass"/>
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/deprecated.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/directives.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/directives.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/directives.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -33,16 +33,6 @@
 
 Redefine a permission in included ZCML as another one.
 
-service
--------
-
-Declare a global service
-
-serviceType
------------
-
-Declare a type of service.
-
 skin
 ----
 
@@ -55,9 +45,25 @@
 
 interface
 ---------
+
 Register an interface in ZCML.
 
+factory
+-------
 
+Register an object factory.
+
+modulealias
+-----------
+
+Provide a module under an alias name, e.g. for persistent backward
+compatability.
+
+hook
+----
+
+Install a hook on a hookable object.
+
 browser ``http://namespaces.zope.org/browser``
 ==============================================
 
@@ -148,16 +154,34 @@
 Retrieve size information for a Zope 2 content class via a Zope 3
 style ``ISized`` adapter.
 
-sendEvents
-----------
+containerEvents
+---------------
 
-Lets a Zope 2 content class send out Zope 3 object events that
-correspond to the Zope 2 methods ``manage_afterAdd`` and
-``manage_beforeDelete``.
+Make events be sent for Zope 2 container objects, instead of calling old
+methods like ``manage_afterAdd``. These old methods will still be called
+for classes specified in a ``deprecatedManageAddDelete`` directive.
 
+deprecatedManageAddDelete
+-------------------------
+
+Specify a class that needs its old deprecated methods like
+``manage_afterAdd``, ``manage_beforeDelete`` and ``manage_afterClone``
+to be called. Modern classes should use event subscribers instead.
+
 pagesFromDirectory
 ------------------
 
-Load all *.pt files in a directory as pages. Useful when you want to
-share templates between Five and CMF, so you can declare pages like
-this is a similar way to setting up skin folders in portal_skins.
+Loads all files with .pt extension in a directory as pages.
+
+registerClass
+-------------
+
+Registers Five content with Zope 2.
+
+localsite
+---------
+
+Turns a class into an implementation of ``IPossibleSite`` so that its
+instances can be serve as local sites.  Unless otherwise specified, a
+default implementation's methods will be used to make the class comply
+with the ``IPossibleSite`` interface.

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/features.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/features.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/features.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -8,7 +8,7 @@
 Zope 3 interfaces
 =================
 
-Everything in the ``zope.interface`` package should work. Zope 3
+Everything from the ``zope.interface`` package works.  Zope 3
 interfaces are the foundation of the component architecture, and also
 the foundation of schemas.
 
@@ -84,3 +84,18 @@
 ignored by views anyway, as they are trusted -- it only serves to
 protect directly exposed methods on content classes (the python
 scripts and the ZPublisher).
+
+Local Sites
+===========
+
+Five supports the concept of a local sites and local site managers.
+See localsite.txt_ for more information.
+
+.. _localsite.txt: localsite.html
+
+Object events
+=============
+
+Five supports sending Zope 3 object events when objects are added,
+moved, renamed, copied and deleted. The use of ``manage_afterAdd`` & co
+methods is deprecated.

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/five14goals.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/five14goals.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/five14goals.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,107 @@
+===============================
+Porting Five to Zope 3.1+ notes
+===============================
+
+Introduction
+------------
+
+Five needs to work in Zope 2.9. Zope 2.9 will ship with Zope 3.2. This
+means Five will need to work with Zope 3.2. Since Zope 3.2 doesn't
+truly exist yet we'll target Zope 3.1 for now.
+
+A Five Roadmap
+--------------
+
+Here is a tentative Five roadmap:
+
+Five 1.1 is to be released shortly, and its main feature is a
+refactored directory structure and Zope 3 i18n for Zope 2. It's still
+targeting the Zope X3.0 that's in Zope 2.8.
+
+Five 1.2 is still targetting Zope 2.8, and its main expected feature
+is support for local utilities.
+
+Five 1.3 is targetting Zope 2.9 and thus Zope 3.2. We're talking about
+this release of Five in this document.
+
+Main problem
+------------
+
+Zope 3.1 has internal changes that Five needs to support. Five works
+by reimplementing ZCML statements it supplies in the context of Zope
+2. This reimplementation is hard to maintain, as for each Zope 3
+upgrade we need to review all these ZCML statements and port them into
+Five again.
+
+The straightforward way to start supporting Zope 3.1+ with Five would
+be to review all the ZCML statements in Five and update them to work
+with Zope 3.1+.
+
+A more ambitious but nicer solution would be if we could reuse the
+Zope 3 ZCML statements directly. If we could accomplish this,
+maintainability of Five would be improved by a lot. Far less review of
+Five would be necessary for each Zope 3 upgrade. In the rest of this
+document we'll be discussing this scenario.
+
+Reasons for Five's modified ZCML statements
+-------------------------------------------
+
+Five ships with modified implementations of Zope 3 ZCML statements for
+a number of reasons:
+
+* could not use new-style classes that are in Zope 3 due to
+  ExtensionClass.
+
+* Five views need to work with the Zope 2 publisher, and this expects 
+  different things than the Zope 3 publisher.
+
+* cannot use the Zope 3 security system, while the Zope 3 ZCML calls
+  into this to configure it.
+
+* Five views need to work with the Zope 2 security system. This means
+  Five needs to issue Zope 2 style security declarations for views.
+
+We'll go into more detail about each of these points below.
+
+New-style ExtensionClass
+========================
+
+Five needed to be compatible with Zope 2.7, which uses old-style
+ExtensionClass. This made life difficult for Five, as Zope 3 uses
+new-style Python classes in many places. It's not easy to mix the two.
+
+Zope 2.8 changed to allow new-style ExtensionClasses, which are
+compatible with new-style Python classes. This means Five can
+hopefully be simplified as we can forget about old-style
+ExtensionClasses.
+
+Five views need to work with the Zope 2 publisher
+=================================================
+
+The Zope 2 publisher expects something quite different than the Zope 3
+publisher. 
+
+* does what is returned to the publisher need to inherit from
+  Acquisition.Explicit? (security reasons?)
+
+* we may need something that calls the right methods on the Zope 3
+  view (such as browserDefault, __call__ and publishTraverse)
+
+Cannot use the Zope 3 security system
+=====================================
+
+Do the Zope 3 security calls get in the way? Five currently removes
+these calls, but perhaps doing the calls does not harm.
+
+If they do interface, we could perhaps still trick things into
+working harmlessly.
+
+Five must issue Zope 2 security declarations for views
+======================================================
+
+This cannot be done by the ZCML implementation of Zope 3. We could
+hopefully do this by following the following pattern::
+
+  def our_directive_implementation(...):
+      original_directive_implementation(...)
+      do_the_zope2_work(...)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/five14goals.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/localsite.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/localsite.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/localsite.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,126 @@
+Local sites in Five
+===================
+
+Intro
+-----
+
+Zope 3 has a concept of local sites and site managers.  They allow one
+to locally override component registrations and have components and
+their configuration be persisted in the ZODB as well as managed
+through the web interface.
+
+By default, Zope 3 has a global site which is configured through ZCML.
+It provides the fallback for all component look-up.  Local sites are
+typically set during traversal, when the traverser encounters an
+``ISite`` object.  The last encountered ``ISite`` wins.  Component
+look-up will cascade through all the sites in the hierarchy and fall
+back to the global site where it can finally fail.
+
+Five also supports local sites, however by default only local
+utilities.  Local adapters, such as ZODB-based views, could be
+supported with a custom implementation of the local site manager and
+local adapter registry.  This is not the focus of local sites in Five,
+though.
+
+
+Turning possible sites into sites
+---------------------------------
+
+Five uses the same technique as Zope 3 for determining local sites:
+sites are found during URL traversal.  However, since the Zope 2
+ZPublisher doesn't emit the necessary events by default, Five needs to
+set a ``BeforeTraverse`` hook on site objects.
+
+Setting this hook needs to be done an object-per-object basis and can
+be performed through the ``manage_site.html`` browser page.  This view
+operates on ``IPossibleSite`` objects (in other words, objects that
+*can* be sites but aren't yet).  It sets the traversal hook on the
+object and then marks it with the ``ISite`` interface to indicate that
+it is a real site now, not just a possible site.
+
+Note that unlike the Zope 3 equivalent of this view, it does not set
+the site manager to site; it is assumed that the site already knows
+how to get its site manager.
+
+Also note that in order for the view to work, the object's class needs
+to be Five-traversable, e.g. with the following ZCML statement:
+
+   <five:traversable class=".module.MyClass" />
+
+
+Custom site implementations
+---------------------------
+
+Anything can be a site, there are no restrictions (sites don't have to
+be folders, for examples).  Sites can also be nested.  For all the
+Component Architecture cares, every object in your URL graph could be
+a site.
+
+The only requirement are two interfaces:
+
+``IPossibleSite``
+
+    Objects that can potentially be turned into a site need to provide
+    this interface.  That requires them to have a ``setSiteManager()``
+    and ``getSiteManager()`` method for setting and getting the local
+    site manager of that site.  The site manager is the registry that
+    takes care of local component look-up.
+
+``IFiveSiteManager``
+
+    This interface is a slight extension of the ``IServiceService`` or
+    ``ISiteManager`` interface, respectively (the former in Zope X3
+    3.0, the latter in later versions).  It defines the API of a local
+    site manager that is to be used in a Five environment.  The site's
+    ``getSiteManager()`` method should return an object providing this
+    interface.
+
+
+Five's default site manager
+----------------------------
+
+If you want to instantly make your custom class an ``IPossibleSite``
+implementation, you can use a default mix-in class from Five, e.g.::
+
+  class MySite(OFS.Folder, Products.Five.site.localsite.FiveSite):
+      pass
+
+This default implementation of ``IPossibleSite`` features a site
+manager implementation that knows how to register and look-up local
+utilities.  It does so by adapting the site to
+``IFiveUtilityRegistry``.
+
+The default adapter for this local utility registry simply stores the
+utilities in a standard OFS Folder on called ``utilities`` on the site
+object.  You probably want to exchange that simple behaviour with
+something that works better in your application.  You can do so by
+plugging in your own utility registry adapter, e.g.::
+
+  <adapter for=".interfaces.IMySite"
+           provides="Products.Five.site.interfaces.IFiveUtilityRegistry"
+           fatory=".module.MyUtilityRegistry" />
+
+All this implementation needs to do is comply with the
+``IFiveUtilityRegistry`` interface, which essentially means the
+standard utility look-up methods like ``queryUtility()``,
+``getUtilitiesFor()``, etc.
+
+
+Turning existing classes into possible sites
+--------------------------------------------
+
+If you cannot or do not want to modify existing classes to mix in the
+``FiveSite`` class, you can also use a structured monkey patch via
+ZCML::
+
+   <five:localsite class=".module.MyClass" />
+
+This makes ``MyClass`` an ``IPossibleSite`` and sticks ``FiveSite``'s
+``getSiteManager()`` and ``setSiteManager()`` methods on the class as
+well.  You can also tell it to use a different site implementation's
+methods for the monkey patch::
+
+   <five:localsite class=".module.MyClass"
+                   site_class=".module.MySiteImpl" />
+
+Just make sure that this class implements ``IPossibleSite``.


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/localsite.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/main.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/main.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/main.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -5,33 +5,42 @@
 -------------
 
 Five is a Zope 2 product that allows you to integrate Zope 3
-technologies into Zope 2, today. Five right now allows you to use the
-following Zope 3 technologies in Zope 2:
+technologies into Zope 2, today.  Among others, it allows you to use
+Zope 3 interfaces, ZCML-based configuration, adapters, browser pages
+(including skins, layers, and resources), automated add and edit forms
+based on schemas, object events, as well as Zope 3-style i18n message
+catalogs.
 
-* Zope 3 interfaces
+We've tried to keep the Five experience as close to Zope 3 as
+possible, so this means that what you learn while using Five should
+also be applicable to Zope 3, and viceversa.
 
-* adapters
+Five 1.0 and 1.1 work on a straight Zope 2.7 installation, as long as
+Zope 3 has been installed.  Five 1.2 requires Zope 2.8 which already
+ships with Zope 3, Five 1.3 is included in Zope 2.9.
 
-* pages (views), including skins and layers, and edit and add forms
-
-* ZCML
-
-It is possible to add Zope 3 style views to your own Zope 2 objects,
-or to existing ones, even normal Folders!
-
-Five works with a straight Zope 2.7 installation, as long as Zope 3
-has been installed. See Five's INSTALL.txt for more information on how
-to set it up.
-
 We're in the process of evaluating lots more Zope 3 technologies for
-integration into Zope 2. This is the right moment for interested Zope
-2 and Zope 3 developers to jump in. We're looking for cooperation
+integration into Zope 2.  This is the right moment for interested Zope
+2 and Zope 3 developers to jump in.  We're looking for cooperation
 between different Zope 2 projects so that this can be a foundational
 system for us all.
 
 Download 
 --------
 
+2005-11-02 -- We have released Five 1.2b and 1.3b! Download Five 1.2b
+here:
+
+http://codespeak.net/z3/five/release/Five-1.2b.tgz
+
+2005-10-04 -- We have released Five 1.1! Download it here:
+
+http://codespeak.net/z3/five/release/Five-1.1.tgz
+
+2005-07-13 -- We have released Five 1.1b! Download it here:
+
+http://codespeak.net/z3/five/release/Five-1.1b.tgz
+
 2005-07-12 -- We have released Five 1.0.2! This is also the version
 that will be included in Zope 2.8.1. Download it here:
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,22 +1 @@
-##############################################################################
-#
-# Copyright (c) 2005 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.
-#
-##############################################################################
-
-import democontent
-
-def initialize(context):
-
-    context.registerClass(
-        democontent.DemoContent,
-        constructors = (democontent.manage_addDemoContentForm,
-                        democontent.manage_addDemoContent),
-        )
+# make this directory a package

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/addDemoContent.pt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/addDemoContent.pt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/addDemoContent.pt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,46 @@
+<h1 tal:replace="structure context/manage_page_header">Header</h1>
+
+<h2 tal:define="form_title string:Add Demo Content"
+    tal:replace="structure context/manage_form_title">Form Title</h2>
+
+<p class="form-help">
+Add Demo Content
+</p>
+
+<form action="." method="post"
+   tal:attributes="action request/ACTUAL_URL">
+<table cellspacing="0" cellpadding="2" border="0">
+  <tr>
+    <td align="left" valign="top">
+    <div class="form-label">
+    Id
+    </div>
+    </td>
+    <td align="left" valign="top">
+    <input type="text" name="add_input_name" size="40" />
+    </td>
+  </tr>
+  <tr>
+    <td align="left" valign="top">
+    <div class="form-label">
+    Title
+    </div>
+    </td>
+    <td align="left" valign="top">
+    <input type="text" name="title" size="40" />
+    </td>
+  </tr>
+  <tr>
+    <td align="left" valign="top">
+    </td>
+    <td align="left" valign="top">
+    <div class="form-element">
+    <input class="form-element" type="submit" name="submit_add"
+     value=" Add " />
+    </div>
+    </td>
+  </tr>
+</table>
+</form>
+
+<h1 tal:replace="structure context/manage_page_footer">Footer</h1>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/addDemoContent.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/browser.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/browser.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/browser.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,20 +1,12 @@
-##############################################################################
-#
-# Copyright (c) 2005 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.
-#
-##############################################################################
-
-from Products.Five import BrowserView
 import random
+from democontent import DemoContent
 
-class Overview(BrowserView):
+
+class Overview:
+
+    """View for overview.
+    """
+
     def reversedIds(self):
         result = []
         for id in self.context.objectIds():
@@ -27,9 +19,28 @@
     def directlyPublished(self):
         return "This is directly published"
 
-class NewExample(BrowserView):
+
+class NewExample:
+
+    """View for new example.
+    """
+
     def helpsWithOne(self):
         return random.randrange(10)
-    
+
     def two(self):
         return "Two got called"
+
+
+class DemoContentAddView:
+
+    """Add view for demo content.
+    """
+
+    def __call__(self, add_input_name='', title='', submit_add=''):
+        if submit_add:
+            obj = DemoContent(add_input_name, title)
+            self.context.add(obj)
+            self.request.response.redirect(self.context.nextURL())
+            return ''
+        return self.index()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,37 +1,39 @@
-<configure 
-  xmlns="http://namespaces.zope.org/zope"
-  xmlns:browser="http://namespaces.zope.org/browser"
-  xmlns:five="http://namespaces.zope.org/five">
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:five="http://namespaces.zope.org/five">
 
-  <five:traversable
-    class="OFS.Folder.Folder"
-    />
+  <five:traversable class="OFS.Application.Application"/>
 
+  <!-- OFS.Folder.Folder views -->
+
+  <five:traversable class="OFS.Folder.Folder"/>
+
   <browser:page
-    for="Products.Five.interfaces.IFolder"
-    name="overview.html"
-    template="overview.pt"
-    permission="zope2.ViewManagementScreens"
-    />
-     
+      for="OFS.interfaces.IFolder"
+      name="overview.html"
+      template="overview.pt"
+      permission="zope2.ViewManagementScreens"
+      />
+
   <browser:page
-    for="Products.Five.interfaces.IFolder"
-    name="overview2.html"
-    template="overview2.pt"
-    permission="zope2.ViewManagementScreens"
-    class=".browser.Overview"
-    />
+      for="OFS.interfaces.IFolder"
+      name="overview2.html"
+      template="overview2.pt"
+      class=".browser.Overview"
+      permission="zope2.ViewManagementScreens"
+      />
 
   <browser:page
-    for="Products.Five.interfaces.IFolder"
-    name="test.html"
-    class=".browser.Overview"
-    attribute="directlyPublished"
-    permission="zope2.ViewManagementScreens"
-    />
+      for="OFS.interfaces.IFolder"
+      name="test.html"
+      class=".browser.Overview"
+      attribute="directlyPublished"
+      permission="zope2.ViewManagementScreens"
+      />
 
   <browser:pages
-      for="Products.Five.interfaces.IFolder"
+      for="OFS.interfaces.IFolder"
       class=".browser.NewExample"
       permission="zope2.ViewManagementScreens"
       >
@@ -45,19 +47,43 @@
         />
   </browser:pages>
 
-  <five:traversable class=".democontent.DemoContent" />
+  <!-- .democontent.IDemoContent views -->
 
+  <five:traversable class=".democontent.DemoContent"/>
+
   <browser:page
-     for=".democontent.IDemoContent"
-     name="someview.html"
-     template="someview.pt"
-     permission="zope2.ViewManagementScreens"
-     />
+      for="zope.app.container.interfaces.IAdding"
+      name="addDemoContent.html"
+      template="addDemoContent.pt"
+      class=".browser.DemoContentAddView"
+      permission="zope2.ViewManagementScreens"
+      />
 
-  <five:defaultViewable class=".democontent.DemoContent" />
- 
+  <browser:resource
+      name="green5.png"
+      image="green5.png"
+      />
+
+  <five:registerClass
+      class=".democontent.DemoContent"
+      meta_type="Five Demo Content"
+      addview="addDemoContent.html"
+      icon="green5.png"
+      permission="zope2.ViewManagementScreens"
+      />
+
+  <browser:page
+      for=".democontent.IDemoContent"
+      name="someview.html"
+      template="someview.pt"
+      permission="zope2.ViewManagementScreens"
+      />
+
+  <five:defaultViewable class=".democontent.DemoContent"/>
+
   <browser:defaultView
-     for=".democontent.IDemoContent"
-     name="someview.html" />
+      for=".democontent.IDemoContent"
+      name="someview.html"
+      />
 
 </configure>

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/democontent.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/democontent.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/democontent.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,44 +1,21 @@
-##############################################################################
-#
-# Copyright (c) 2005 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.
-#
-##############################################################################
-
 from zope.interface import Interface, implements
 from OFS.SimpleItem import SimpleItem
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 
+
 class IDemoContent(Interface):
+
     def mymethod():
-        "Return some text"
-        
+        """Return some text.
+        """
+
+
 class DemoContent(SimpleItem):
+
     implements(IDemoContent)
 
-    meta_type = 'Five Demo Content'
-
     def __init__(self, id, title):
         self.id = id
         self.title = title
 
     def mymethod(self):
         return "Hello world"
-
-
-manage_addDemoContentForm = PageTemplateFile(
-    "www/demoContentAdd", globals(),
-    __name__ = 'manage_addDemoContentForm')
-
-def manage_addDemoContent(self, id, title, REQUEST=None):
-    """Add the demo content."""
-    id = self._setObject(id, DemoContent(id, title))
-    if REQUEST is None:
-        return
-    REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_main')

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/green5.png
===================================================================
(Binary files differ)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/doc/products/ViewsTutorial/green5.png
___________________________________________________________________
Name: svn:mime-type
   + image/png

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/event.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/event.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/event.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <!-- Adapter giving sublocations for ObjectManagers, used
+       by dispatchToSublocations -->
+
+  <adapter
+      for="OFS.interfaces.IObjectManager"
+      provides="zope.app.location.interfaces.ISublocations"
+      factory="OFS.subscribers.ObjectManagerSublocations"
+      />
+
+  <!-- dispatch IObjectWillBeMovedEvent with "bottom-up" semantics -->
+
+  <subscriber
+      for="OFS.interfaces.IItem
+           OFS.interfaces.IObjectWillBeMovedEvent"
+      handler="OFS.subscribers.dispatchObjectWillBeMovedEvent"
+      />
+
+  <!-- dispatch IObjectMovedEvent with "top-down" semantics -->
+
+  <subscriber
+      for="OFS.interfaces.IItem
+           zope.app.container.interfaces.IObjectMovedEvent"
+      handler="OFS.subscribers.dispatchObjectMovedEvent"
+      />
+
+  <!-- dispatch IObjectClonedEvent with "top-down" semantics -->
+
+  <subscriber
+      for="OFS.interfaces.IItem
+           OFS.interfaces.IObjectClonedEvent"
+      handler="OFS.subscribers.dispatchObjectClonedEvent"
+      />
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/event.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/eventconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/eventconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/eventconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2004, 2005 Zope Corporation and Contributors.
+# Copyright (c) 2005 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -15,109 +15,38 @@
 Use 'structured monkey patching' to enable zope.app.container event sending for
 Zope 2 objects.
 
-$Id: eventconfigure.py 17810 2005-09-24 09:12:59Z efge $
+$Id: eventconfigure.py 19413 2005-11-02 14:37:52Z efge $
 """
-from Products.Five.fiveconfigure import isFiveMethod
-from zope.event import notify
-from zope.interface import implements
-from zope.app.container.interfaces import IObjectAddedEvent,\
-     IObjectRemovedEvent
-from zope.app.container.contained import ObjectMovedEvent
-from zope.app.event.objectevent import ObjectCopiedEvent
 
-# holds classes that were monkeyed with; for clean up
-_monkied = []
+import warnings
+from OFS.subscribers import deprecatedManageAddDeleteClasses
 
-# ObjectAddedEvent and ObjectRemovedEvent are different in Zope 2
-class ObjectAddedEvent(ObjectMovedEvent):
-    implements(IObjectAddedEvent)
+def setContainerEvents():
+    warnings.warn("Using <five:containerEvents/> is deprecated (it is now "
+                  "the default), it will be removed in Zope 2.11",
+                  DeprecationWarning)
 
-    def __init__(self, object, newParent=None, newName=None):
-        if newParent is None:
-            newParent = object.aq_inner.aq_parent
-        if newName is None:
-            newName = object.id
-        ObjectMovedEvent.__init__(self, object, None, None, newParent, newName)
-    
-class ObjectRemovedEvent(ObjectMovedEvent):
-    implements(IObjectRemovedEvent)
+def setDeprecatedManageAddDelete(class_):
+    """Instances of the class will still see their old methods called."""
+    deprecatedManageAddDeleteClasses.append(class_)
 
-    def __init__(self, object, oldParent=None, oldName=None):
-        if oldParent is None:
-            oldParent = object.aq_inner.aq_parent
-        if oldName is None:
-            oldName = object.id
-        ObjectMovedEvent.__init__(self, object, oldParent, oldName, None, None)
-    
-def manage_afterAdd(self, item, container):
-    original_location_path = getattr(self, '__five_location_path__', None)
-    self.__five_location_path__ = self.getPhysicalPath()
-    # if there still is an object in the original location, we're copied
-    # we cannot rely on manage_afterClone, as this gets triggered only
-    # *after* a manage_afterAdd. This logic might fail in the case where
-    # something *is* somehow left in the original location that can
-    # be traversed to.
-    is_copied = original_location_path and (self.unrestrictedTraverse(
-        original_location_path, None) is not None)
-    if is_copied:
-        notify(ObjectCopiedEvent(self))
-    if original_location_path is None or is_copied:
-        notify(ObjectAddedEvent(self))
-    else:
-        original_location = self.unrestrictedTraverse(
-            original_location_path[:-1])
-        notify(ObjectMovedEvent(self,
-                                original_location, original_location_path[-1],
-                                container, self.id))
-    # call original
-    method = getattr(self, '__five_original_manage_afterAdd', None)
-    if method is not None:
-        self.__five_original_manage_afterAdd(item, container)
+def cleanUp():
+    deprecatedManageAddDeleteClasses[:] = []
 
-manage_afterAdd.__five_method__ = True
+def containerEvents(_context):
+    _context.action(
+        discriminator=None,
+        callable=setContainerEvents,
+        args=(),
+        )
 
-def manage_beforeDelete(self, item, container):
-    notify(ObjectRemovedEvent(self))
-    # call original
-    method = getattr(self, '__five_original_manage_beforeDelete', None)
-    if method is not None:
-        self.__five_original_manage_beforeDelete(item, container)
-
-manage_beforeDelete.__five_method__ = True
-
-def classSendEvents(class_):
-    """Make instances of the class send Object*Event."""
-    # tuck away original methods if necessary
-    for name in ['manage_afterAdd', 'manage_beforeDelete']:
-        method = getattr(class_, name, None)
-        if not isFiveMethod(method):
-            # if we haven't alread overridden this, tuck away originals
-            setattr(class_, '__five_original_' + name, method)
-
-    class_.manage_afterAdd = manage_afterAdd
-    class_.manage_beforeDelete = manage_beforeDelete
-    # remember class for clean up
-    _monkied.append(class_)
-    
-def sendEvents(_context, class_):
+def deprecatedManageAddDelete(_context, class_):
     _context.action(
-        discriminator = ('five:sendEvents', class_),
-        callable = classSendEvents,
-        args=(class_,)
+        discriminator=('five:deprecatedManageAddDelete', class_),
+        callable=setDeprecatedManageAddDelete,
+        args=(class_,),
         )
 
-# clean up code
-from Products.Five.fiveconfigure import killMonkey
 from zope.testing.cleanup import addCleanUp
-
-def unsendEvents(class_):
-    """Restore class's initial state with respect to sending events"""
-    for name in ['manage_afterAdd', 'manage_beforeDelete']:
-        killMonkey(class_, name, '__five_original_'+name)
-
-def cleanUp():
-    for class_ in _monkied:
-        unsendEvents(class_)
-
 addCleanUp(cleanUp)
 del addCleanUp

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fiveconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fiveconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fiveconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -22,12 +22,20 @@
 import glob
 import warnings
 
-import App
+import App.config
+import Products
 from zLOG import LOG, ERROR
 
-from zope.interface import classImplements
+from zope.interface import classImplements, classImplementsOnly, implementedBy
+from zope.interface.interface import InterfaceClass
 from zope.configuration import xmlconfig
+from zope.configuration.exceptions import ConfigurationError
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+from zope.app import zapi
 from zope.app.component.interface import provideInterface
+from zope.app.component.metaconfigure import adapter
+from zope.app.security.interfaces import IPermission
 
 from viewable import Viewable
 from traversable import Traversable
@@ -55,7 +63,7 @@
     # in the control panel. However, all attempts to do so has failed from my 
     # side. //regebro
     exc = sys.exc_info()
-    LOG('Five', ERROR, 'Could not import Product %s' % name, error=exc)
+    LOG('Five', ERROR, 'Could not import Product %s' % product.__name__, error=exc)
 
 def loadProducts(_context):
     products = findProducts()
@@ -177,20 +185,6 @@
         args = (class_,)
         )
 
-def viewable(_context, class_):
-    # XXX do not need to mark where this is used, as simple search
-    # should find all instances easily
-    warnings.warn(
-        'The five:viewable directive has been deprecated. '
-        'Please use the five:traversable directive instead.',
-        DeprecationWarning)
-
-    _context.action(
-        discriminator = None,
-        callable = classTraversable,
-        args=(class_,)
-        )
-
 def createZope2Bridge(zope2, package, name):
     # Map a Zope 2 interface into a Zope3 interface, seated within 'package'
     # as 'name'.
@@ -215,7 +209,7 @@
         )
 
 def pagesFromDirectory(_context, directory, module, for_=None,
-                  layer='default', permission='zope.Public'):
+                       layer=IDefaultBrowserLayer, permission='zope.Public'):
 
     if isinstance(module, basestring):
         module = _context.resolve(module)
@@ -233,6 +227,41 @@
         page(_context, name=name, permission=permission,
              layer=layer, for_=for_, template=fname)
 
+
+_register_monkies = []
+_meta_type_regs = []
+def _registerClass(class_, meta_type, permission, addview, icon, global_):
+    setattr(class_, 'meta_type', meta_type)
+
+    permission_obj = zapi.getUtility(IPermission, permission)
+
+    if icon:
+        setattr(class_, 'icon', '++resource++%s' % icon)
+
+    interfaces = tuple(implementedBy(class_))
+
+    info = {'name': meta_type,
+            'action': addview and ('+/%s' % addview) or '',
+            'product': 'Five',
+            'permission': str(permission_obj.title),
+            'visibility': global_ and 'Global' or None,
+            'interfaces': interfaces,
+            'instance': class_,
+            'container_filter': None}
+
+    Products.meta_types += (info,)
+
+    _register_monkies.append(class_)
+    _meta_type_regs.append(meta_type)
+
+def registerClass(_context, class_, meta_type, permission, addview=None,
+                  icon=None, global_=True):
+    _context.action(
+        discriminator = ('registerClass', meta_type),
+        callable = _registerClass,
+        args = (class_, meta_type, permission, addview, icon, global_)
+        )
+
 # clean up code
 
 def killMonkey(class_, name, fallback, attr=None):
@@ -265,12 +294,34 @@
     killMonkey(class_, '__browser_default__', '__fallback_default__',
                '__five_viewable__')
 
+def unregisterClass(class_):
+    delattr(class_, 'meta_type')
+    try:
+        delattr(class_, 'icon')
+    except AttributeError:
+        pass
+
 def cleanUp():
+    global _traversable_monkies
     for class_ in _traversable_monkies:
         untraversable(class_)
+    _traversable_monkies = []
+
+    global _defaultviewable_monkies
     for class_ in _defaultviewable_monkies:
         undefaultViewable(class_)
+    _defaultviewable_monkies = []
 
+    global _register_monkies
+    for class_ in _register_monkies:
+        unregisterClass(class_)
+    _register_monkies = []
+
+    global _meta_type_regs
+    Products.meta_types = tuple([ info for info in Products.meta_types
+                                  if info['name'] not in _meta_type_regs ])
+    _meta_type_regs = []
+
 from zope.testing.cleanup import addCleanUp
 addCleanUp(cleanUp)
 del addCleanUp

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fivedirectives.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fivedirectives.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/fivedirectives.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -17,7 +17,10 @@
 """
 from zope.interface import Interface
 from zope.app.publisher.browser.metadirectives import IBasicResourceInformation
+from zope.app.security.fields import Permission
 from zope.configuration.fields import GlobalObject, Tokens, PythonIdentifier
+from zope.configuration.fields import Bool
+from zope.schema import ASCII
 from zope.schema import TextLine
 
 class IImplementsDirective(Interface):
@@ -56,7 +59,7 @@
         required=True
         )
 
-class ISendEventsDirective(Interface):
+class ISizableDirective(Interface):
     """Make instances of class send events.
     """
 
@@ -65,6 +68,19 @@
         required=True
         )
 
+class IContainerEventsDirective(Interface):
+    """Global switch to enable container events
+    """
+
+class IDeprecatedManageAddDeleteDirective(Interface):
+    """Call manage_afterAdd & co for these contained content classes.
+    """
+    class_ = GlobalObject(
+        title=u"Class",
+        required=True,
+        )
+
+
 class IBridgeDirective(Interface):
     """Bridge from a Zope 2 interface to an equivalent Zope3 interface.
     """
@@ -104,3 +120,51 @@
         description=u"The directory containing the resource data.",
         required=True
         )
+
+class IRegisterClassDirective(Interface):
+
+    """registerClass directive schema.
+
+    Register Five content with Zope 2.
+    """
+
+    class_ = GlobalObject(
+        title=u'Instance Class',
+        description=u'Dotted name of the class that is registered.',
+        required=True
+        )
+
+    meta_type = ASCII(
+        title=u'Meta Type',
+        description=u'A human readable unique identifier for the class.',
+        required=True
+        )
+
+    permission = Permission(
+        title=u'Add Permission',
+        description=u'The permission for adding objects of this class.',
+        required=True
+        )
+
+    addview = ASCII(
+        title=u'Add View ID',
+        description=u'The ID of the add view used in the ZMI. Consider this '
+                    u'required unless you know exactly what you do.',
+        default=None,
+        required=False
+        )
+
+    icon = ASCII(
+        title=u'Icon ID',
+        description=u'The ID of the icon used in the ZMI.',
+        default=None,
+        required=False
+        )
+
+    global_ = Bool(
+        title=u'Global scope?',
+        description=u'If "global" is False the class is only available in '
+                    u'containers that explicitly allow one of its interfaces.',
+        default=True,
+        required=False
+        )

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -33,7 +33,7 @@
 from zope.app.form.utility import setUpWidgets, getWidgetsData
 from zope.app.form.interfaces import IInputWidget, WidgetsError
 from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent
-from zope.app.i18n import ZopeMessageIDFactory as _
+from zope.app.i18n import ZopeMessageFactory as _
 
 from Products.Five.browser import BrowserView
 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
@@ -144,12 +144,13 @@
                 if changed:
                     self.changed()
                     # XXX: Needs locale support:
-                    # formatter = self.request.locale.dates.getFormatter(
-                    #     'dateTime', 'medium')
-                    status = _("Updated on ${date_time}")
-                    # status.mapping = {'date_time': formatter.format(
-                    #     datetime.utcnow())}
-                    status.mapping = {'date_time': str(datetime.utcnow())}
+                    #formatter = self.request.locale.dates.getFormatter(
+                    #    'dateTime', 'medium')
+                    #status = _("Updated on ${date_time}",
+                    #           mapping={'date_time':
+                    #                    formatter.format(datetime.utcnow())})
+                    status = _("Updated on ${date_time}",
+                               mapping={'date_time': str(datetime.utcnow())})
 
         self.update_status = status
         return status
@@ -249,9 +250,3 @@
 
     def nextURL(self):
         return self.context.nextURL()
-
-
-# BBB: Will be removed in future versions
-from Products.Five import browser
-browser.AddView = AddView
-browser.EditView = EditView

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/metaconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/metaconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/metaconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,28 +13,29 @@
 ##############################################################################
 """Edit form directives
 
-$Id: metaconfigure.py 12884 2005-05-30 13:10:41Z philikon $
+$Id: metaconfigure.py 19283 2005-10-31 17:43:51Z philikon $
 """
 import ExtensionClass
+from Globals import InitializeClass as initializeClass
 
-from zope.component import getGlobalService
-from zope.component.servicenames import Presentation
+from zope.interface import Interface
 from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.app.publisher.browser.globalbrowsermenuservice import \
-     menuItemDirective
+
+from zope.app import zapi
+from zope.app.publisher.browser.menumeta import menuItemDirective
 from zope.app.form.browser.metaconfigure import BaseFormDirective
 from zope.app.container.interfaces import IAdding
+from zope.app.i18n import ZopeMessageFactory as _
 
 from Products.Five.form import EditView, AddView
 from Products.Five.metaclass import makeClass
-from Products.Five.security import protectClass, initializeClass
+from Products.Five.security import protectClass
 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
 from Products.Five.browser.metaconfigure import makeClassForTemplate
 
 def EditViewFactory(name, schema, label, permission, layer,
                     template, default_template, bases, for_, fields,
                     fulledit_path=None, fulledit_label=None, menu=u''):
-    s = getGlobalService(Presentation)
     class_ = makeClassForTemplate(template, globals(), used_for=schema,
                                   bases=bases)
     class_.schema = schema
@@ -49,8 +50,15 @@
 
     class_.generated_form = ZopeTwoPageTemplateFile(default_template)
 
+    if layer is None:
+        layer = IDefaultBrowserLayer
 
-    s.provideView(for_, name, IBrowserRequest, class_, layer)
+    s = zapi.getGlobalSiteManager()
+    s.provideAdapter((for_, layer), Interface, name, class_)
+
+    # Reminder: the permission we got has already been processed by
+    # BaseFormDirective, that means that zope.Public has been
+    # translated to the CheckerPublic object
     protectClass(class_, permission)
     initializeClass(class_)
 
@@ -58,20 +66,22 @@
 
     def _processWidgets(self):
         if self._widgets:
-            customWidgetsObject = makeClass('CustomWidgetsMixin', (ExtensionClass.Base,), self._widgets)
+            customWidgetsObject = makeClass(
+                'CustomWidgetsMixin', (ExtensionClass.Base,), self._widgets)
             self.bases = self.bases + (customWidgetsObject,)
 
 class EditFormDirective(FiveFormDirective):
 
     view = EditView
     default_template = 'edit.pt'
-    title = 'Edit'
+    title = _('Edit')
 
     def _handle_menu(self):
         if self.menu:
             menuItemDirective(
                 self._context, self.menu, self.for_ or self.schema,
-                '@@' + self.name, self.title, permission=self.permission)
+                '@@' + self.name, self.title, permission=self.permission,
+                layer=self.layer)
 
     def __call__(self):
         self._processWidgets()
@@ -89,8 +99,6 @@
                    fields, content_factory, arguments,
                    keyword_arguments, set_before_add, set_after_add,
                    menu=u''):
-
-    s = getGlobalService(Presentation)
     class_ = makeClassForTemplate(template, globals(), used_for=schema,
                                   bases=bases)
 
@@ -105,7 +113,15 @@
 
     class_.generated_form = ZopeTwoPageTemplateFile(default_template)
 
-    s.provideView(for_, name, IBrowserRequest, class_, layer)
+    if layer is None:
+        layer = IDefaultBrowserLayer
+
+    s = zapi.getGlobalSiteManager()
+    s.provideAdapter((for_, layer), Interface, name, class_)
+
+    # Reminder: the permission we got has already been processed by
+    # BaseFormDirective, that means that zope.Public has been
+    # translated to the CheckerPublic object
     protectClass(class_, permission)
     initializeClass(class_)
 
@@ -132,7 +148,7 @@
             # for=self.schema.
             menuItemDirective(
                 self._context, self.menu, self.for_, '@@' + self.name,
-                self.title, permission=self.permission,
+                self.title, permission=self.permission, layer=self.layer,
                 description=self.description)
 
     def _handle_arguments(self, leftover=None):

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.pt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.pt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.pt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,15 @@
+<fieldset>
+  <legend tal:content="context/legendTitle"
+        i18n:translate="">The Legend</legend>
+  <div class="row" tal:repeat="widget context/subwidgets">
+    <tal:comment condition="nothing">
+      This is why we have to duplicate this template: we want to look
+      up the @@form_macros browser page from something that's
+      definitely five:traversable (it doesn't really matter where we
+      look it up, just *that* we look it up); we know the object we're
+      editing is five:traversable, so we just use that.  Yes, three
+      times context.  Weird, eh?
+    </tal:comment>
+    <metal:block use-macro="context/context/context/@@form_macros/widget_row" />
+  </div>
+</fieldset>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,66 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Five-compatible version of ObjectWidget
+
+This is needed because ObjectWidget uses ViewPageTemplateFile whose
+macro definition is unfortunately incompatible with
+ZopeTwoPageTemplateFile.  So this subclass uses
+ZopeTwoPageTemplateFile for the template that renders the widget's
+sub-editform.  Acquisition has to be mixed in to provide the
+ZopeTwoPageTemplateFile with the proper acquisition context.
+
+$Id$
+"""
+import os.path
+import Acquisition
+import zope.app.form.browser.objectwidget
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass as initializeClass
+from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
+
+class ObjectWidgetView(Acquisition.Explicit,
+                       zope.app.form.browser.objectwidget.ObjectWidgetView):
+    security = ClassSecurityInfo()
+    security.declareObjectPublic()
+
+    template = ZopeTwoPageTemplateFile('objectwidget.pt')
+
+initializeClass(ObjectWidgetView)
+
+class ObjectWidgetClass(Acquisition.Explicit,
+                        zope.app.form.browser.objectwidget.ObjectWidget):
+
+    def __init__(self, context, request, factory, **kw):
+        super(ObjectWidgetClass, self).__init__(context, request, factory, **kw)
+        self.view = ObjectWidgetView(self, request)
+
+    def setRenderedValue(self, value):
+        """Slightly more robust re-implementation this method."""
+        # re-call setupwidgets with the content
+        self._setUpEditWidgets()
+        for name in self.names:
+            val = getattr(value, name, None)
+            if val is None:
+                # this is where we are more robust than Zope 3.2's
+                # object widget: we supply subwidgets with the default
+                # from the schema, not None (Zope 3.2's list widget
+                # breaks when the rendered value is None)
+                val = self.context.schema[name].default
+            self.getSubWidget(name).setRenderedValue(val)
+
+def ObjectWidget(context, request, factory, **kw):
+    """Return an ObjectWidget suitable in the Five environment, with
+    right acquisition context"""
+    return ObjectWidgetClass(context, request, factory, **kw
+                             ).__of__(context.context)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/objectwidget.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -34,7 +34,7 @@
       type="zope.publisher.interfaces.browser.IBrowserRequest"
       for="zope.schema.interfaces.IObject"
       provides="zope.app.form.interfaces.IInputWidget"
-      factory="zope.app.form.browser.objectwidget.ObjectWidget"
+      factory="Products.Five.form.objectwidget.ObjectWidget"
       permission="zope.Public"
       />
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/forms.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/forms.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/forms.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -17,7 +17,7 @@
 Finally, we need to setup a traversable folder.  Otherwise, Five won't
 get to to do its view lookup:
 
-  >>> from Products.Five.testing import manage_addFiveTraversableFolder
+  >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
   >>> manage_addFiveTraversableFolder(self.folder, 'ftf')
 
 
@@ -47,9 +47,10 @@
 
   >>> print http(r"""
   ... GET /test_folder_1_/ftf/+/protectedaddform.html HTTP/1.1
-  ... """, handle_errors=True)
-  HTTP/1.1 401 Unauthorized
+  ... """, handle_errors=False)
+  Traceback (most recent call last):
   ...
+  Unauthorized: ...
 
 Now let's add a piece of our sample content object to test more things
 on it:
@@ -372,7 +373,11 @@
   ... -----------------------------968064918930967154199105236
   ... Content-Disposition: form-data; name="field.somelist.add"
   ... 
-  ... Add
+  ... Add Some item
+  ... -----------------------------968064918930967154199105236
+  ... Content-Disposition: form-data; name="field.somelist.count"
+  ... 
+  ... 0
   ... -----------------------------968064918930967154199105236--
   ... """ % (wo_hen_hao, ni_hao), handle_errors=False)
   HTTP/1.1 200 OK
@@ -408,6 +413,10 @@
   ... 
   ... %s
   ... -----------------------------968064918930967154199105236
+  ... Content-Disposition: form-data; name="field.somelist.count"
+  ... 
+  ... 1
+  ... -----------------------------968064918930967154199105236
   ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
   ... 
   ... Change
@@ -572,5 +581,5 @@
 
 Finally, we need to clean up:
 
-  >>> from zope.app.tests.placelesssetup import tearDown
+  >>> from zope.app.testing.placelesssetup import tearDown
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/schemacontent.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/schemacontent.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/schemacontent.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -18,13 +18,13 @@
 from OFS.SimpleItem import SimpleItem
 from Globals import InitializeClass
 
-from zope.i18nmessageid import MessageIDFactory
+from zope.i18nmessageid import MessageFactory
 from zope.interface import implements, Interface
 from zope.schema import TextLine, Text, Object, Int, List
 from zope.app.form import CustomWidgetFactory
-from zope.app.form.browser import ObjectWidget
+from Products.Five.form.objectwidget import ObjectWidget
 
-_ = MessageIDFactory('formtest')
+_ = MessageFactory('formtest')
 
 class IFieldContent(Interface):
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/test_forms.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/test_forms.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/form/tests/test_forms.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -46,25 +46,26 @@
       >>> from zope.app.form.browser.textwidgets import TextWidget
       >>> from zope.app.form.browser.itemswidgets import DropdownWidget
 
-      >>> view1 = zapi.getViewProviding(contactname, IInputWidget, request)
+      >>> view1 = zapi.getMultiAdapter((contactname, request), IInputWidget)
       >>> view1.__class__ == TextWidget
       True
 
-      >>> view2 = zapi.getViewProviding(salutation, IInputWidget, request)
+      >>> view2 = zapi.getMultiAdapter((salutation, request), IInputWidget)
       >>> view2.__class__ == DropdownWidget
       True
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 
 def test_suite():
     import unittest
-    from Testing.ZopeTestCase import ZopeDocTestSuite, FunctionalDocFileSuite
+    from zope.testing.doctest import DocTestSuite
+    from Testing.ZopeTestCase import FunctionalDocFileSuite
     return unittest.TestSuite((
-            ZopeDocTestSuite(),
+            DocTestSuite(),
             FunctionalDocFileSuite('forms.txt',
                                    package="Products.Five.form.tests",),
             ))

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/i18n.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/i18n.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/i18n.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,15 +13,21 @@
 ##############################################################################
 """Mimick Zope3 i18n machinery for Zope 2
 
-$Id: i18n.py 14400 2005-07-07 17:55:08Z philikon $
+$Id: i18n.py 19435 2005-11-02 16:34:58Z philikon $
 """
+from Acquisition import aq_acquire
 from zope.interface import implements
 from zope.i18n import interpolate
 from zope.i18n.interfaces import ITranslationDomain, IUserPreferredLanguages
-from zope.i18nmessageid import MessageID
 from zope.app import zapi
 from zope.publisher.browser import BrowserLanguages
 
+# BBB 2005/10/10 -- MessageIDs are to be removed for Zope 3.3
+import zope.deprecation
+zope.deprecation.__show__.off()
+from zope.i18nmessageid import MessageID, Message
+zope.deprecation.__show__.on()
+
 class FiveTranslationService:
     """Translation service that delegates to ``zope.i18n`` machinery.
     """
@@ -29,7 +35,7 @@
     # regarding fallback and Zope 2 compatability
     def translate(self, domain, msgid, mapping=None,
                   context=None, target_language=None, default=None):
-        if isinstance(msgid, MessageID):
+        if isinstance(msgid, (Message, MessageID)):
             domain = msgid.domain
             default = msgid.default
             mapping = msgid.mapping
@@ -46,7 +52,7 @@
         # in Zope3, context is adapted to IUserPreferredLanguages,
         # which means context should be the request in this case.
         if context is not None:
-            context = context.REQUEST
+            context = aq_acquire(context, 'REQUEST', None)
         return util.translate(msgid, mapping=mapping, context=context,
                               target_language=target_language, default=default)
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,7 +13,7 @@
 ##############################################################################
 """Five interfaces
 
-$Id: interfaces.py 14613 2005-07-13 10:39:05Z philikon $
+$Id: interfaces.py 19283 2005-10-31 17:43:51Z philikon $
 """
 from zope.interface import Interface
 from zope.interface.interfaces import IInterface
@@ -33,23 +33,3 @@
     Menu item types are interfaces that define classes of
     menu items.
     """
-
-
-#
-# BBB: Zope core interfaces
-#
-# The interfaces here are only provided for backwards compatibility and will
-# be removed in Five 1.2. Please import interfaces from the corresponding Zope
-# package instead.
-#
-
-from persistent.interfaces import IPersistent
-from AccessControl.interfaces import *
-from Acquisition.interfaces import *
-from App.interfaces import *
-from OFS.interfaces import *
-from webdav.interfaces import *
-
-# BBB: for old names used in Five 1.0
-IAcquisition = IAcquirer
-IPermissionMapping = IPermissionMappingSupport

Deleted: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/interfaces.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,140 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/five">
-
-  <!-- IPersistent, IPersistentExtra -->
-
-  <!-- Acquisition -->
-
-  <implements
-      class="Acquisition.ImplicitAcquisitionWrapper"
-      interface="Acquisition.interfaces.IAcquisitionWrapper"
-      />
-
-  <implements
-      class="Acquisition.ExplicitAcquisitionWrapper"
-      interface="Acquisition.interfaces.IAcquisitionWrapper"
-      />
-
-  <implements
-      class="Acquisition.Implicit"
-      interface="Acquisition.interfaces.IAcquirer"
-      />
-
-  <implements
-      class="Acquisition.Explicit"
-      interface="Acquisition.interfaces.IAcquirer"
-      />
-
-  <!-- DAV -->
-
-  <implements
-      class="webdav.Lockable.LockableItem"
-      interface="webdav.interfaces.IWriteLock"
-      />
-
-  <implements
-      class="webdav.Resource.Resource"
-      interface="webdav.interfaces.IDAVResource"
-      />
-
-  <implements
-      class="webdav.Collection.Collection"
-      interface="webdav.interfaces.IDAVCollection"
-      />
-
-  <!-- OFS -->
-
-  <implements
-      class="OFS.CopySupport.CopySource"
-      interface="OFS.interfaces.ICopySource"
-      />
-
-  <implements
-      class="OFS.CopySupport.CopyContainer"
-      interface="OFS.interfaces.ICopyContainer"
-      />
-
-  <implements
-      class="OFS.Traversable.Traversable"
-      interface="OFS.interfaces.ITraversable"
-      />
-
-  <implements
-      class="OFS.SimpleItem.Item"
-      interface="OFS.interfaces.IItem"
-      />
-
-  <implements
-      class="OFS.SimpleItem.Item_w__name__"
-      interface="OFS.interfaces.IItemWithName"
-      />
-
-  <implements
-      class="OFS.SimpleItem.SimpleItem"
-      interface="OFS.interfaces.ISimpleItem"
-      />
-
-  <implements
-      class="OFS.ObjectManager.ObjectManager"
-      interface="OFS.interfaces.IObjectManager"
-      />
-
-  <implements
-      class="OFS.PropertyManager.PropertyManager"
-      interface="OFS.interfaces.IPropertyManager"
-      />
-
-  <implements
-      class="OFS.FindSupport.FindSupport"
-      interface="OFS.interfaces.IFindSupport"
-      />
-
-  <implements
-      class="OFS.Folder.Folder"
-      interface="OFS.interfaces.IFolder"
-      />
-
-  <implements
-      class="OFS.OrderSupport.OrderSupport"
-      interface="OFS.interfaces.IOrderedContainer"
-      />
-
-  <implements
-      class="OFS.OrderedFolder.OrderedFolder"
-      interface="OFS.interfaces.IOrderedFolder"
-      />
-
-  <implements
-      class="OFS.Application.Application"
-      interface="OFS.interfaces.IApplication"
-      />
-
- <!-- App -->
-
-  <implements
-      class="App.Undo.UndoSupport"
-      interface="App.interfaces.IUndoSupport"
-      />
-
-  <implements
-      class="App.Management.Navigation"
-      interface="App.interfaces.INavigation"
-      />
-
-  <!-- AccessControl -->
-
-  <implements
-      class="AccessControl.Owned.Owned"
-      interface="AccessControl.interfaces.IOwned"
-      />
-
-  <implements
-      class="AccessControl.PermissionMapping.RoleManager"
-      interface="AccessControl.interfaces.IPermissionMappingSupport"
-      />
-
-  <implements
-      class="AccessControl.Role.RoleManager"
-      interface="AccessControl.interfaces.IRoleManager"
-      />
-
-</configure>

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/meta.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/meta.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/meta.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -2,13 +2,10 @@
     xmlns="http://namespaces.zope.org/zope"
     xmlns:meta="http://namespaces.zope.org/meta">
 
+  <include package=".site" file="meta.zcml" />
   <include package=".browser" file="meta.zcml" />
   <include package=".form" file="meta.zcml" />
 
-  <!-- load the zope:modulealias and zope:hook directives -->
-  <include package="zope.modulealias" file="meta.zcml" />
-  <include package="zope.configuration" file="meta.zcml" />
-
   <meta:directives namespace="http://namespaces.zope.org/zope">
 
     <meta:directive
@@ -53,18 +50,6 @@
         handler="zope.app.component.metaconfigure.factory"
         />
 
-    <meta:directive
-        name="serviceType"
-        schema="zope.app.component.metadirectives.IServiceTypeDirective"
-        handler="zope.app.component.metaconfigure.serviceType"
-        />
-
-    <meta:directive
-        name="service"
-        schema="zope.app.component.metadirectives.IServiceDirective"
-        handler="zope.app.component.metaconfigure.service"
-        />
-
     <meta:complexDirective
         name="content"
         schema="zope.app.component.metadirectives.IClassDirective"
@@ -131,14 +116,20 @@
        />
 
     <meta:directive
-       name="sendEvents"
-       schema=".fivedirectives.ISendEventsDirective"
-       handler=".eventconfigure.sendEvents"
+       name="containerEvents"
+       schema=".fivedirectives.IContainerEventsDirective"
+       handler=".eventconfigure.containerEvents"
        />
 
     <meta:directive
+       name="deprecatedManageAddDelete"
+       schema=".fivedirectives.IDeprecatedManageAddDeleteDirective"
+       handler=".eventconfigure.deprecatedManageAddDelete"
+       />
+
+    <meta:directive
        name="sizable"
-       schema=".fivedirectives.ISendEventsDirective"
+       schema=".fivedirectives.ISizableDirective"
        handler=".sizeconfigure.sizable"
        />
 
@@ -148,20 +139,18 @@
         handler=".fiveconfigure.pagesFromDirectory"
         />
 
-    <!-- viewable is deprecated, use traversable instead -->
-
     <meta:directive
-       name="viewable"
-       schema=".fivedirectives.ITraversableDirective"
-       handler=".fiveconfigure.viewable"
-       />
-
-    <meta:directive
        name="bridge"
        schema=".fivedirectives.IBridgeDirective"
        handler=".fiveconfigure.bridge"
        />
 
+    <meta:directive
+       name="registerClass"
+       schema=".fivedirectives.IRegisterClassDirective"
+       handler=".fiveconfigure.registerClass"
+       />
+
   </meta:directives>
 
   <meta:directive
@@ -171,6 +160,9 @@
       handler="zope.app.security.metaconfigure.redefinePermission"
       />
 
+  <!-- load the zope:modulealias directive -->
+  <include package="zope.modulealias" file="meta.zcml" />
+
   <!-- load the i18n:registerTranslations directive -->
   <include package="zope.app.i18n" file="meta.zcml" />
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/metaconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/metaconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/metaconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,73 +13,25 @@
 ##############################################################################
 """Generic Components ZCML Handlers
 
-$Id: metaconfigure.py 12884 2005-05-30 13:10:41Z philikon $
+$Id: metaconfigure.py 19283 2005-10-31 17:43:51Z philikon $
 """
-from types import ModuleType
+from Products.Five.security import CheckerPublic, protectName
+from Globals import InitializeClass as initializeClass
 
-from zope.interface import classImplements
-from zope.configuration.exceptions import ConfigurationError
+from zope.app.component.contentdirective import ContentDirective as \
+     zope_app_ContentDirective
 
-from security import CheckerPublic
-from security import protectName, initializeClass
-
-class ContentDirective:
-
-    def __init__(self, _context, class_):
-        self.__class = class_
-        if isinstance(self.__class, ModuleType):
-            raise ConfigurationError('Content class attribute must be a class')
-        self.__context = _context
-
-    def implements(self, _context, interface):
-        for interface in interface:
-            _context.action(
-                discriminator = (
-                'five::directive:content', self.__class, object()),
-                callable = classImplements,
-                args = (self.__class, interface),
-                )
-            interface(_context, interface)
-
-    def require(self, _context, permission=None,
-                attributes=None, interface=None):
-        """Require a the permission to access a specific aspect"""
-
-        if not (interface or attributes):
-            raise ConfigurationError("Nothing required")
-
-        if interface:
-            for i in interface:
-                if i:
-                    self.__protectByInterface(i, permission)
-        if attributes:
-            self.__protectNames(attributes, permission)
-
-    def allow(self, _context, attributes=None, interface=None):
-        """Like require, but with permission_id zope.Public"""
-        return self.require(_context, CheckerPublic, attributes, interface)
-
-    def __protectByInterface(self, interface, permission_id):
-        "Set a permission on names in an interface."
-        for n, d in interface.namesAndDescriptions(1):
-            self.__protectName(n, permission_id)
-        interface(self.__context, interface)
-
+class ContentDirective(zope_app_ContentDirective):
+        
     def __protectName(self, name, permission_id):
-        "Set a permission on a particular name."
         self.__context.action(
             discriminator = ('five:protectName', self.__class, name),
             callable = protectName,
             args = (self.__class, name, permission_id)
             )
 
-    def __protectNames(self, names, permission_id):
-        "Set a permission on a bunch of names."
-        for name in names:
-            self.__protectName(name, permission_id)
-
     def __call__(self):
-        "Handle empty/simple declaration."
+        """Handle empty/simple declaration."""
         return self.__context.action(
             discriminator = ('five:initialize:class', self.__class),
             callable = initializeClass,

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/permissions.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/permissions.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/permissions.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,6 +1,11 @@
 <configure xmlns="http://namespaces.zope.org/zope"
            i18n_domain="Five">
 
+  <permission
+      id="five.ManageSite"
+      title="Manage Five local sites"
+      />
+
   <!-- Give common Zope2 and CMF permissions a permission ID
        The title of the permission is what Zope 2 knows it under -->
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/security.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/security.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/security.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -24,7 +24,7 @@
 from zope.app import zapi
 
 from AccessControl import ClassSecurityInfo, getSecurityManager
-from Globals import InitializeClass
+from Globals import InitializeClass as initializeClass
 from types import StringTypes
 
 CheckerPublicId = 'zope.Public'
@@ -99,9 +99,6 @@
     if getattr(thread_local, 'interaction', None) is None:
         thread_local.interaction = FiveSecurityPolicy()
 
-def initializeClass(klass):
-    InitializeClass(klass)
-
 def _getSecurity(klass):
     # a Zope 2 class can contain some attribute that is an instance
     # of ClassSecurityInfo. Zope 2 scans through things looking for
@@ -121,15 +118,12 @@
     """Protect the attribute 'name' on 'klass' using the given
        permission"""
     security = _getSecurity(klass)
-    # XXX: Sometimes, the object CheckerPublic is used instead of the
-    # string zope.Public. I haven't ben able to figure out why, or if
-    # it is correct, or a bug. So this is a workaround.
-    if permission_id is CheckerPublic:
-        security.declarePublic(name)
-        return
     # Zope 2 uses string, not unicode yet
     name = str(name)
-    if permission_id == CheckerPublicId:
+    if permission_id == CheckerPublicId or permission_id is CheckerPublic:
+        # Sometimes, we already get a processed permission id, which
+        # can mean that 'zope.Public' has been interchanged for the
+        # CheckerPublic object
         security.declarePublic(name)
     elif permission_id == CheckerPrivateId:
         security.declarePrivate(name)
@@ -142,7 +136,10 @@
 def protectClass(klass, permission_id):
     """Protect the whole class with the given permission"""
     security = _getSecurity(klass)
-    if permission_id == CheckerPublicId:
+    if permission_id == CheckerPublicId or permission_id is CheckerPublic:
+        # Sometimes, we already get a processed permission id, which
+        # can mean that 'zope.Public' has been interchanged for the
+        # CheckerPublic object
         security.declareObjectPublic()
     elif permission_id == CheckerPrivateId:
         security.declareObjectPrivate()

Deleted: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/services.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/services.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/services.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,27 +0,0 @@
-<configure xmlns="http://namespaces.zope.org/zope">
-
-  <serviceType
-      id="Utilities"
-      interface="zope.component.interfaces.IUtilityService" />
-   
-  <service
-      serviceType="Utilities"
-      factory="zope.component.utility.GlobalUtilityService" />
-   
-  <serviceType
-      id="Adapters"
-      interface="zope.component.interfaces.IAdapterService" />
-   
-  <service
-      serviceType="Adapters"
-      factory="zope.component.adapter.GlobalAdapterService" />
-
-  <serviceType
-      id="Presentation"
-      interface="zope.component.interfaces.IPresentationService" />
-  
-  <service
-      serviceType="Presentation"
-      factory="zope.component.presentation.GlobalPresentationService" />
- 
-</configure>

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1 @@
+# make this directory a package


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/browser.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/browser.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/browser.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Local sites browser views
+
+$Id$
+"""
+from zope.app.component.interfaces import ISite
+from zope.app.component.hooks import clearSite
+
+from Products.Five.browser import BrowserView
+from Products.Five.site.localsite import enableLocalSiteHook, \
+     disableLocalSiteHook
+
+class LocalSiteView(BrowserView):
+    """View for convering a possible site to a site
+    """
+
+    def update(self):
+        form = self.request.form
+        if form.has_key('UPDATE_MAKESITE'):
+            self.makeSite()
+        elif form.has_key('UPDATE_UNMAKESITE'):
+            self.unmakeSite()
+
+    def isSite(self):
+        return ISite.providedBy(self.context)
+
+    def makeSite(self):
+        """Convert a possible site to a site"""
+        if self.isSite():
+            raise ValueError('This is already a site')
+
+        enableLocalSiteHook(self.context)
+        return "This object is now a site"
+
+    def unmakeSite(self):
+        """Convert a site to a possible site"""
+        if not self.isSite():
+            raise ValueError('This is not a site')
+
+        disableLocalSiteHook(self.context)
+
+        # disableLocalSiteHook circumcised our context so that it's
+        # not an ISite anymore.  That can mean that certain things for
+        # it can't be found anymore.  So, for the rest of this request
+        # (which will be over in about 20 CPU cycles), already clear
+        # the local site from the thread local.
+        clearSite()
+
+        return "This object is no longer a site"


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/browser.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,35 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:browser="http://namespaces.zope.org/browser">
+
+  <adapter
+      for="*"
+      provides="zope.component.interfaces.ISiteManager"
+      factory=".localsite.siteManagerAdapter"
+      />
+
+  <adapter
+      for="zope.app.site.interfaces.ISite"
+      provides=".interfaces.IFiveUtilityRegistry"
+      factory=".utility.SimpleLocalUtilityRegistry"
+      />
+
+  <subscriber
+      for="zope.app.component.interfaces.ISite
+           zope.app.publication.interfaces.IBeforeTraverseEvent"
+      handler="zope.app.component.site.threadSiteSubscriber"
+      />
+
+  <subscriber
+      for="zope.app.publication.interfaces.IEndRequestEvent"
+      handler="zope.app.component.site.clearThreadSiteSubscriber"
+      />
+
+  <browser:page
+      for="zope.app.component.interfaces.IPossibleSite"
+      name="manage_site.html"
+      permission="five.ManageSite"
+      class=".browser.LocalSiteView"
+      template="managesite.pt"
+      />
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/interfaces.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/interfaces.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/interfaces.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,95 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Five interfaces
+
+$Id: interfaces.py 18584 2005-10-14 17:13:27Z regebro $
+"""
+from zope.interface import Interface, Attribute
+from zope.component.interfaces import ISiteManager
+
+class IRegisterUtilitySimply(Interface):
+    """Register utilities simply
+
+    Allow local registrations of utilities, in a much simpler
+    manner than Zope 3 does it currently.
+
+    Note: The name of this interface is expressed as a verb
+    (describing the action it expresses, namely registering
+    utilities).  The reason for that is that the names *utility
+    registry* (successor of the Zope 3 utility service) and *utility
+    registration* (object in a registration stack, part of the
+    complicated registration framework in Zope 3) have different
+    connotations in Zope 3 than we want to express here.
+    """
+
+    def registerUtility(self, interface, utility, name=''):
+        """Registers a utility in the local context"""
+        # TODO Define an exception than is to be thrown when a local
+        # utility of that interface and name is already registered.
+
+    next = Attribute("The next local registry in the tree. This attribute "
+                     "represents the parent of this registry node. If the "
+                     "value is ``None``, then this registry represents the "
+                     "root of the tree")
+
+class IFiveUtilityRegistry(IRegisterUtilitySimply):
+    """Look up and register utilities"""
+     
+    def getUtility(interface, name='', context=None):
+        """Get the utility that provides interface
+
+        Returns the nearest utility to the context that implements the
+        specified interface.  If one is not found, raises
+        ComponentLookupError.
+        """
+
+    def queryUtility(interface, name='', default=None, context=None):
+        """Look for the utility that provides interface
+
+        Returns the nearest utility to the context that implements
+        the specified interface.  If one is not found, returns default.
+        """
+
+    def getUtilitiesFor(interface, context=None):
+        """Return the utilities that provide an interface
+
+        An iterable of utility name-value pairs is returned.
+        """
+
+    def getAllUtilitiesRegisteredFor(interface, context=None):
+        """Return all registered utilities for an interface
+
+        This includes overridden utilities.
+
+        An iterable of utility instances is returned.  No names are
+        returned.
+        """
+
+class IFiveSiteManager(ISiteManager, IRegisterUtilitySimply):
+    """Five site manager
+
+    For the sake of forward-portability, registering utilities can be
+    done directly on the site manager to cut out the middle man called
+    utility service (this corresponds to Zope 3.1's understanding of
+    site managers).  An implementation of this interface will probably
+    delegate the work to an IFiveUtilityService component, though."""
+
+
+# BBB 2005/11/01 -- gone in Five 1.5.
+IFiveUtilityService = IFiveUtilityRegistry
+import zope.deprecation
+zope.deprecation.deprecated(
+    'IFiveUtilityService', "'IFiveUtilityService' has been renamed to "
+    "'IFiveUtilityRegistry' and will disappear in Five 1.5."
+    )


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/interfaces.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/localsite.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/localsite.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/localsite.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,151 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Local sites
+
+$Id$
+"""
+from zope.event import notify
+from zope.interface import directlyProvides, directlyProvidedBy
+from zope.interface import implements
+from zope.component import getGlobalSiteManager
+from zope.component.exceptions import ComponentLookupError
+
+from zope.app.component.interfaces import ISite, IPossibleSite
+from zope.app.publication.zopepublication import BeforeTraverseEvent
+
+from ExtensionClass import Base
+from Acquisition import aq_base, aq_inner, aq_parent
+from Products.SiteAccess.AccessRule import AccessRule
+from ZPublisher.BeforeTraverse import registerBeforeTraverse
+from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
+
+from Products.Five.site.interfaces import IFiveSiteManager, IFiveUtilityRegistry
+
+# Hook up custom component architecture calls
+import zope.app.component.hooks
+zope.app.component.hooks.setHooks()
+
+def siteManagerAdapter(ob):
+    """An adapter * -> ISiteManager.
+
+    This is registered in place of the one in Zope 3 so that we lookup
+    using acquisition instead of ILocation.
+    """
+    current = ob
+    while True:
+        if ISite.providedBy(current):
+            return current.getSiteManager()
+        current = getattr(current, '__parent__', aq_parent(aq_inner(current)))
+        if current is None:
+            # It does not support acquisition or has no parent, so we
+            # return the global site
+            return getGlobalSiteManager()
+
+HOOK_NAME = '__local_site_hook__'
+
+class LocalSiteHook(Base):
+    def __call__(self, container, request):
+        notify(BeforeTraverseEvent(container, request))
+
+
+def enableLocalSiteHook(obj):
+    """Install __before_traverse__ hook for Local Site
+    """
+    # We want the original object, not stuff in between, and no acquisition
+    obj = aq_base(obj)
+    if not IPossibleSite.providedBy(obj):
+        raise TypeError, 'Must provide IPossibleSite'
+    hook = AccessRule(HOOK_NAME)
+    registerBeforeTraverse(obj, hook, HOOK_NAME, 1)
+
+    if not hasattr(obj, HOOK_NAME):
+        setattr(obj, HOOK_NAME, LocalSiteHook())
+
+    directlyProvides(obj, ISite, directlyProvidedBy(obj))
+
+def disableLocalSiteHook(obj):
+    """Remove __before_traverse__ hook for Local Site
+    """
+    # We want the original object, not stuff in between, and no acquisition
+    obj = aq_base(obj)
+    if not ISite.providedBy(obj):
+        raise TypeError, 'Must provide ISite'
+    unregisterBeforeTraverse(obj, HOOK_NAME)
+    if hasattr(obj, HOOK_NAME):
+        delattr(obj, HOOK_NAME)
+
+    directlyProvides(obj, directlyProvidedBy(obj) - ISite)
+
+class FiveSiteManager(object):
+    implements(IFiveSiteManager)
+
+    def __init__(self, context):
+        # make {get|query}NextSiteManager() work without having to
+        # resort to Zope 2 acquisition
+        self.context = self.__parent__ = context
+
+    @property
+    def next(self):
+        obj = self.context
+        while obj is not None:
+            obj = aq_parent(aq_inner(obj))
+            if ISite.providedBy(obj):
+                return obj.getSiteManager()
+        # In Zope 3.1+, returning None here is understood by
+        # getNextSiteManager as that our next site manager is the
+        # global one. If we returned the global one, it would be
+        # understood as a lookup error. Yeah, it's weird, tell me
+        # about it.
+        return None
+
+    @property
+    def adapters(self):
+        return getGlobalSiteManager().adapters #XXX wrong
+
+    @property
+    def utilities(self):
+        return IFiveUtilityRegistry(self.context)
+
+    def queryAdapter(self, object, interface, name, default=None):
+        return self.adapters.queryAdapter(object, interface, name, default)
+
+    def queryMultiAdapter(self, objects, interface, name, default=None):
+        return self.adapters.queryMultiAdapter(objects, interface, name, default)
+
+    def getAdapters(self, objects, provided):
+        return self.adapters.getAdapters(objects, provided)
+
+    def subscribers(self, required, provided):
+        return self.adapters.subscribers(required, provided)
+
+    def queryUtility(self, interface, name='', default=None):
+        return self.utilities.queryUtility(interface, name, default)
+
+    def getUtilitiesFor(self, interface):
+        return self.utilities.getUtilitiesFor(interface)
+
+    def getAllUtilitiesRegisteredFor(self, interface):
+        return self.utilities.getAllUtilitiesRegisteredFor(interface)
+
+    def registerUtility(self, interface, utility, name=''):
+        return self.utilities.registerUtility(interface, utility, name)
+
+class FiveSite:
+    implements(IPossibleSite)
+
+    def getSiteManager(self):
+        return FiveSiteManager(self)
+
+    def setSiteManager(self, sm):
+        raise NotImplementedError('This class has a fixed site manager')


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/localsite.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/managesite.pt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/managesite.pt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/managesite.pt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,25 @@
+<tal:tag condition="view/update"/>
+<html metal:use-macro="context/@@standard_macros/view"
+      i18n:domain="zope">
+  <body>
+  <div metal:fill-slot="body">
+
+  <form action="." tal:attributes="action request/URL" method="POST"
+        enctype="multipart/form-data">
+      <div class="row">
+        <div class="controls">
+          <input type="submit" value="Make site" name="UPDATE_MAKESITE"
+              i18n:attributes="value" 
+              tal:attributes="disabled view/isSite"/>
+          <input type="submit" value="Unmake site" name="UPDATE_UNMAKESITE" 
+              i18n:attributes="value"
+              tal:attributes="disabled not:view/isSite"/>
+
+        </div>
+      </div>
+  </form>
+
+  </div>
+  </body>
+
+</html>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/managesite.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/meta.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/meta.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/meta.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,15 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/five">
+
+    <meta:directive
+       name="localsite"
+       schema=".metadirectives.ILocalSiteDirective"
+       handler=".metaconfigure.installSiteHook"
+       />
+       
+  </meta:directives>
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metaconfigure.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metaconfigure.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metaconfigure.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Five-specific directive handlers
+
+These directives are specific to Five and have no equivalents in Zope 3.
+
+$Id: fiveconfigure.py 18581 2005-10-14 16:54:25Z regebro $
+"""
+from zope.interface import classImplements, classImplementsOnly, implementedBy
+from zope.interface.interface import InterfaceClass
+from zope.configuration.exceptions import ConfigurationError
+from zope.app.component.metaconfigure import adapter
+from zope.app.component.interfaces import IPossibleSite
+
+from Products.Five.site.localsite import FiveSite
+
+def classSiteHook(class_, site_class):
+    setattr(class_, 'getSiteManager',
+            site_class.getSiteManager.im_func)
+    setattr(class_, 'setSiteManager',
+            site_class.setSiteManager.im_func)
+
+_localsite_monkies = []
+def installSiteHook(_context, class_, site_class=None):
+    if site_class is None:
+        if not IPossibleSite.implementedBy(class_):
+            # This is not a possible site, we need to monkey-patch it so that
+            # it is.
+            site_class = FiveSite
+    else:
+        if not IPossibleSite.implementedBy(site_class):
+            raise ConfigurationError('Site class does not implement '
+                                     'IPossibleClass: %s' % site_class)
+    if site_class is not None:
+        _context.action(
+            discriminator = (class_,),
+            callable = classSiteHook,
+            args=(class_, site_class)
+            )
+        _context.action(
+            discriminator = (class_, IPossibleSite),
+            callable = classImplements,
+            args=(class_, IPossibleSite)
+            )
+    _localsite_monkies.append(class_)
+
+# clean up code
+
+def uninstallSiteHooks():
+    for class_ in _localsite_monkies:
+        delattr(class_, 'getSiteManager')
+        delattr(class_, 'setSiteManager')
+        classImplementsOnly(class_, implementedBy(class_)-IPossibleSite)
+        _localsite_monkies.remove(class_)
+
+from zope.testing.cleanup import addCleanUp
+addCleanUp(uninstallSiteHooks)
+del addCleanUp


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metaconfigure.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metadirectives.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metadirectives.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metadirectives.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Site support ZCML directive schemas
+
+$Id: fivedirectives.py 18581 2005-10-14 16:54:25Z regebro $
+"""
+from zope.interface import Interface
+from zope.configuration.fields import GlobalObject
+
+class ILocalSiteDirective(Interface):
+    """Make instances of class hookable for Site.
+
+    site_class is an implementation of ISite, which will have it's methods
+    monkey_patched into the the class. If not given a default implementation
+    will be used.
+    """
+    class_ = GlobalObject(
+        title=u"Class",
+        required=True
+        )
+
+    site_class = GlobalObject(
+        title=u"Site Class",
+        required=False
+        )


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/metadirectives.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1 @@
+# make this directory a package


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/dummy.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/dummy.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/dummy.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Dummy test fixtures
+
+$Id$
+"""
+from zope.interface import implements, Interface
+from OFS.SimpleItem import SimpleItem
+from Products.Five.tests.testing import FiveTraversableFolder
+
+class IDummySite(Interface):
+    pass
+
+class DummySite(FiveTraversableFolder):
+    """A very dummy Site
+    """
+    implements(IDummySite)
+
+def manage_addDummySite(self, id, REQUEST=None):
+    """Add the dummy site."""
+    id = self._setObject(id, DummySite(id))
+    return ''
+
+class IDummyUtility(Interface):
+    pass
+
+class ISuperDummyUtility(IDummyUtility):
+    pass
+
+class DummyUtility(SimpleItem):
+    implements(IDummyUtility)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/dummy.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/framework.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/framework.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/framework.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# ZopeTestCase 
+#
+# COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+#
+# This version of framework.py will use the SOFTWARE_HOME
+# environment variable to locate Zope and the Testing package.
+#
+# If the tests are run in an INSTANCE_HOME installation of Zope,
+# Products.__path__ and sys.path with be adjusted to include the
+# instance's Products and lib/python directories respectively.
+#
+# If you explicitly set INSTANCE_HOME prior to running the tests,
+# auto-detection is disabled and the specified path will be used 
+# instead.
+#
+# If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+# will be adjusted to use it.
+#
+# If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup 
+# is assumed, and you can attach to a running ZEO server (via the 
+# instance's custom_zodb.py).
+#
+##############################################################################
+#
+# The following code should be at the top of every test module:
+#
+# import os, sys
+# if __name__ == '__main__':
+#     execfile(os.path.join(sys.path[0], 'framework.py'))
+#
+# ...and the following at the bottom:
+#
+# if __name__ == '__main__':
+#     framework()
+#
+##############################################################################
+
+__version__ = '0.2.3'
+
+# Save start state
+#
+__SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')
+__INSTANCE_HOME = os.environ.get('INSTANCE_HOME', '')
+
+if __SOFTWARE_HOME.endswith(os.sep):
+    __SOFTWARE_HOME = os.path.dirname(__SOFTWARE_HOME)
+
+if __INSTANCE_HOME.endswith(os.sep):
+    __INSTANCE_HOME = os.path.dirname(__INSTANCE_HOME)
+
+# Find and import the Testing package
+#
+if not sys.modules.has_key('Testing'):
+    p0 = sys.path[0]
+    if p0 and __name__ == '__main__':
+        os.chdir(p0)
+        p0 = ''
+    s = __SOFTWARE_HOME
+    p = d = s and s or os.getcwd()
+    while d:
+        if os.path.isdir(os.path.join(p, 'Testing')):
+            zope_home = os.path.dirname(os.path.dirname(p))
+            sys.path[:1] = [p0, p, zope_home]
+            break
+        p, d = s and ('','') or os.path.split(p)
+    else:
+        print 'Unable to locate Testing package.',
+        print 'You might need to set SOFTWARE_HOME.'
+        sys.exit(1)
+
+import Testing, unittest
+execfile(os.path.join(os.path.dirname(Testing.__file__), 'common.py'))
+
+# Include ZopeTestCase support
+#
+if 1:   # Create a new scope
+
+    p = os.path.join(os.path.dirname(Testing.__file__), 'ZopeTestCase')
+
+    if not os.path.isdir(p):
+        print 'Unable to locate ZopeTestCase package.',
+        print 'You might need to install ZopeTestCase.'
+        sys.exit(1)
+
+    ztc_common = 'ztc_common.py'
+    ztc_common_global = os.path.join(p, ztc_common)
+
+    f = 0
+    if os.path.exists(ztc_common_global):
+        execfile(ztc_common_global)
+        f = 1
+    if os.path.exists(ztc_common):
+        execfile(ztc_common)
+        f = 1
+
+    if not f:
+        print 'Unable to locate %s.' % ztc_common
+        sys.exit(1)
+
+# Debug
+#
+print 'SOFTWARE_HOME: %s' % os.environ.get('SOFTWARE_HOME', 'Not set')
+print 'INSTANCE_HOME: %s' % os.environ.get('INSTANCE_HOME', 'Not set')
+sys.stdout.flush()
+


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/framework.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/functional.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/functional.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/functional.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,147 @@
+Functional test for local sites
+===============================
+
+Set up all of Five:
+
+  >>> import Products.Five
+  >>> from Products.Five import zcml
+  >>> zcml.load_config("configure.zcml", Products.Five)
+
+First we turn our DummySite class into a site in ZCML (and register
+some views that will provide us with some test info),
+
+  >>> zcml_text = """
+  ... <configure xmlns="http://namespaces.zope.org/zope"
+  ...            xmlns:meta="http://namespaces.zope.org/meta"
+  ...            xmlns:five="http://namespaces.zope.org/five"
+  ...            xmlns:browser="http://namespaces.zope.org/browser">
+  ... 
+  ...   <!-- make the zope2.Public permission work -->
+  ...   <meta:redefinePermission from="zope2.Public" to="zope.Public" />
+  ... 
+  ...   <five:localsite class="Products.Five.site.tests.dummy.DummySite" />
+  ...
+  ...   <browser:page
+  ...       for="Products.Five.site.tests.dummy.IDummySite"
+  ...       name="checkSiteManager.html"
+  ...       class="Products.Five.site.tests.test_functional.CheckSiteManagerView"
+  ...       permission="zope2.Public"
+  ...       />
+  ...
+  ...   <browser:page
+  ...       for="Products.Five.site.tests.dummy.IDummySite"
+  ...       name="lookupUtilities.html"
+  ...       class="Products.Five.site.tests.test_functional.LookupUtilitiesView"
+  ...       permission="zope2.Public"
+  ...       />
+  ... 
+  ... </configure>"""
+  >>> zcml.load_string(zcml_text)
+
+then we add an instance to our folder:
+
+  >>> from Products.Five.site.tests.dummy import manage_addDummySite
+  >>> nothing = manage_addDummySite(self.folder, 'site')
+
+Now we check what the info view tells us about local component lookup:
+
+  >>> print http(r'''
+  ... GET /test_folder_1_/site/@@checkSiteManager.html HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 OK
+  ...
+  {'IFiveUtilityRegistry.providedBy(utility_service)': False,
+   'isinstance(zapi.getSiteManager(), FiveSiteManager)': False,
+   'zapi.getSiteManager() is zapi.getGlobalSiteManager()': True}
+
+We see that we have no local component lookup yet, because we haven't
+set the site.  Therefore, enable the traversal hook by using the view
+that's provided for this task (we first need to create a manager
+account in order to be able to access it):
+
+  >>> uf = self.folder.acl_users
+  >>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
+
+  >>> print http(r'''
+  ... POST /test_folder_1_/site/@@manage_site.html HTTP/1.1
+  ... Authorization: Basic manager:r00t
+  ... Content-Length: 25
+  ... 
+  ... UPDATE_MAKESITE=Make site''')
+  HTTP/1.1 200 OK
+  ...
+
+Now we call the info view again and find that local component lookup
+is working:
+
+  >>> print http(r'''
+  ... GET /test_folder_1_/site/@@checkSiteManager.html HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 OK
+  ...
+  {'IFiveUtilityRegistry.providedBy(utility_service)': True,
+   'isinstance(zapi.getSiteManager(), FiveSiteManager)': True,
+   'zapi.getSiteManager() is zapi.getGlobalSiteManager()': False}
+
+Of course, sites are only active *during* traversal; after traversal
+they're gone:
+
+  >>> from zope.app.component.hooks import getSite
+  >>> getSite() is None
+  True
+
+
+We can also register utilities now:
+
+  >>> from zope.app import zapi
+  >>> sm = self.folder.site.getSiteManager()
+
+  >>> from Products.Five.site.tests.dummy import IDummyUtility, DummyUtility
+  >>> dummy = DummyUtility()
+  >>> sm.registerUtility(IDummyUtility, dummy)
+
+and find them being looked up just fine:
+
+  >>> print http(r'''
+  ... GET /test_folder_1_/site/@@lookupUtilities.html HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 OK
+  ...
+  zapi.getUtility(IDummyUtility) == dummy: True
+
+Of course, we can't look it up once the request has ended, because we
+lose the local site setup:
+
+  >>> zapi.getUtility(IDummyUtility)
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: (<InterfaceClass Products.Five.site.tests.dummy.IDummyUtility>, '')
+
+At last we can "unmake" the site using the browser view provided by
+Five:
+
+  >>> print http(r'''
+  ... POST /test_folder_1_/site/@@manage_site.html HTTP/1.1
+  ... Authorization: Basic manager:r00t
+  ... Content-Length: 29
+  ... 
+  ... UPDATE_UNMAKESITE=Unmake site''')
+  HTTP/1.1 200 OK
+  ...
+
+And everything is back to normal with respect to local component
+lookup:
+
+  >>> print http(r'''
+  ... GET /test_folder_1_/site/@@checkSiteManager.html HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 OK
+  ...
+  {'IFiveUtilityRegistry.providedBy(utility_service)': False,
+   'isinstance(zapi.getSiteManager(), FiveSiteManager)': False,
+   'zapi.getSiteManager() is zapi.getGlobalSiteManager()': True}
+
+Finally, global services and the monkeys:
+
+  >>> from zope.app.testing.placelesssetup import tearDown
+  >>> tearDown()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/functional.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/sitemanager.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/sitemanager.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/sitemanager.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,124 @@
+Five Site Manager
+=================
+
+In this test we want to test Five's implementation of a site manager.
+First, we need to set a few things up...
+
+  >>> from zope.app.testing.placelesssetup import setUp, tearDown
+  >>> setUp()
+
+  >>> import Products.Five
+  >>> from Products.Five import zcml
+  >>> zcml.load_config("meta.zcml", Products.Five)
+  >>> zcml.load_config("permissions.zcml", Products.Five)
+  >>> zcml.load_config("configure.zcml", Products.Five.site)
+  >>> zcml_text = """\
+  ... <five:localsite
+  ...     xmlns:five="http://namespaces.zope.org/five"
+  ...     class="Products.Five.site.tests.dummy.DummySite" />"""
+  >>> zcml.load_string(zcml_text)
+
+...for example some sort of site object:
+
+  >>> from Products.Five.site.tests.dummy import manage_addDummySite
+  >>> nothing = manage_addDummySite(self.folder, 'dummysite')
+  >>> dummysite = self.folder.dummysite
+
+
+Local vs. global sites
+----------------------
+
+Let's make the possible site a real site:
+
+  >>> from Products.Five.site.localsite import enableLocalSiteHook
+  >>> enableLocalSiteHook(dummysite)
+
+and tell Zope 3 about it:
+
+  >>> from zope.app.component.hooks import setSite, setHooks
+  >>> setSite(dummysite)
+
+Also hook up custom component architecture calls; we need to do this
+here because zope.app.component.hooks registers a cleanup with the
+testing cleanup framework, so the hooks get torn down by
+placelesssetup each time.
+
+  >>> setHooks()
+
+That seems to have worked (we test this by using the context property
+of FiveSiteManager):
+
+  >>> from zope.app import zapi
+  >>> zapi.getSiteManager().context == dummysite
+  True
+
+Since there's no other local site in between this one and the global
+one, the next one should be the global one.  FiveSiteManager indicates
+that to us by return ``None``:
+
+  >>> from zope.app import zapi
+  >>> zapi.getSiteManager().next is None
+  True
+
+To the the Zope 3 API, this means the next site manager should be the
+global one:
+
+  >>> from zope.app.component import getNextSiteManager
+  >>> getNextSiteManager(dummysite.getSiteManager()) is zapi.getGlobalSiteManager()
+  True
+
+
+ISiteManager API
+----------------
+
+Site managers are supposed to have an ``adapters`` and a ``utilities``
+attribute.  Five's site manager simply passes through the global
+adapter registry:
+
+  >>> zapi.getSiteManager().adapters is zapi.getGlobalSiteManager().adapters
+  True
+
+The utility registry, however, is an ``IFiveUtilityRegistry``:
+
+  >>> from Products.Five.site.interfaces import IFiveUtilityRegistry
+  >>> IFiveUtilityRegistry.providedBy(zapi.getSiteManager().utilities)
+  True
+
+The methods on registering and looking up utilities are covered by the
+utility tests in depth.  The methods on adapter look up are indirectly
+covered in the functional test; view look up, for example, is adapter
+look up.
+
+
+Nesting sites
+-------------
+
+Let's set up another site to test nested sites:
+
+  >>> nothing = manage_addDummySite(self.folder.dummysite, 'subsite')
+  >>> subsite = self.folder.dummysite.subsite
+
+Now we set the current site to the ``subsite``:
+
+  >>> enableLocalSiteHook(subsite)
+  >>> setSite(subsite)
+
+When we call getServices() now, we get the correct site manager:
+
+  >>> zapi.getSiteManager().context == subsite
+  True
+
+The "next" site is the less local one:
+
+  >>> zapi.getSiteManager().next.context == dummysite
+  True
+
+The Zope 3 API for this agrees with that:
+
+  >>> getNextSiteManager(subsite.getSiteManager()).context == dummysite
+  True
+
+
+Finally, some clean up:
+
+  >>> tearDown()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/sitemanager.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_functional.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_functional.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_functional.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Test local sites
+
+$Id$
+"""
+import os, sys
+
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+import pprint
+from zope.app import zapi
+from Products.Five import BrowserView
+from Products.Five.site.interfaces import IFiveUtilityRegistry
+from Products.Five.site.localsite import FiveSiteManager
+from Products.Five.site.tests.dummy import IDummyUtility
+
+class CheckSiteManagerView(BrowserView):
+
+    def __call__(self):
+        sm = zapi.getSiteManager()
+        result = {
+            'zapi.getSiteManager() is zapi.getGlobalSiteManager()':
+            sm is zapi.getGlobalSiteManager(),
+            'IFiveUtilityRegistry.providedBy(utility_service)':
+            IFiveUtilityRegistry.providedBy(sm.utilities),
+            'isinstance(zapi.getSiteManager(), FiveSiteManager)':
+            isinstance(sm, FiveSiteManager),
+            }
+        return pprint.pformat(result)
+
+class LookupUtilitiesView(BrowserView):
+
+    def __call__(self):
+        dummy = getattr(self.context.utilities, IDummyUtility.getName())
+        return "zapi.getUtility(IDummyUtility) == dummy: %s" % \
+               (zapi.getUtility(IDummyUtility) == dummy)
+
+def test_suite():
+    from Testing.ZopeTestCase import FunctionalDocFileSuite
+    suite = FunctionalDocFileSuite('functional.txt',
+                                   package='Products.Five.site.tests')
+    suite.level = 2
+    return suite
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_functional.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_localsite.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_localsite.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_localsite.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,215 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Test local sites
+
+$Id$
+"""
+import os, sys
+
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+import unittest
+from Testing import ZopeTestCase
+
+from zope.interface import implements
+from zope.interface import directlyProvides, directlyProvidedBy
+from zope.component import getGlobalSiteManager, getSiteManager
+from zope.component.exceptions import ComponentLookupError
+from zope.component.interfaces import ISiteManager
+from zope.app.component.hooks import setSite, getSite, setHooks
+from zope.app.component.interfaces import IPossibleSite, ISite
+from zope.app.traversing.interfaces import IContainmentRoot
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+from Acquisition import Implicit
+from OFS.ObjectManager import ObjectManager
+
+import Products.Five
+from Products.Five import zcml
+
+class SiteManager(Implicit):
+    implements(ISiteManager)
+
+class Folder(ObjectManager):
+    implements(IPossibleSite)
+
+    sm = None
+
+    def getId(self):
+        return self.id
+
+    def getSiteManager(self, default=None):
+        return self.sm
+
+    def setSiteManager(self, sm):
+        self.sm = sm
+        directlyProvides(self, ISite, directlyProvidedBy(self))
+
+class Package(Implicit):
+    pass
+
+class Root(Folder):
+    implements(IContainmentRoot, ISite)
+    def getSiteManager(self):
+        return getGlobalSiteManager()
+
+class SiteManagerStub(object):
+    implements(ISiteManager)
+
+class SiteManagerTest(PlacelessSetup, unittest.TestCase):
+
+    def setUp(self):
+        super(SiteManagerTest, self).setUp()
+        self.root = root = Root()
+
+        self.f1 = f1 = Folder().__of__(root)
+        self.sm1 = sm1 = SiteManager()
+        f1.setSiteManager(sm1)
+        self.p1 = p1 = Package().__of__(sm1)
+
+        self.f2 = f2 = Folder().__of__(f1)
+        self.sm2 = sm2 = SiteManager()
+        f2.setSiteManager(sm2)
+        self.p2 = p2 = Package().__of__(sm2)
+
+        sm1.next = getGlobalSiteManager()
+        sm2.next = sm1
+
+        self.unparented_folder = Folder()
+        self.unrooted_subfolder = Folder().__of__(self.unparented_folder)
+        zcml.load_config("meta.zcml", Products.Five)
+        zcml.load_config("permissions.zcml", Products.Five)
+        zcml.load_config("configure.zcml", Products.Five.site)
+        zcml_text = """\
+        <five:localsite
+            xmlns:five="http://namespaces.zope.org/five"
+            class="Products.Five.site.tests.dummy.DummySite" />"""
+        zcml.load_string(zcml_text)
+
+        # Hook up custom component architecture calls; we need to do
+        # this here because zope.app.component.hooks registers a
+        # cleanup with the testing cleanup framework, so the hooks get
+        # torn down by placelesssetup each time.
+        setHooks()
+
+    def test_getSiteManager(self):
+        self.assertEqual(getSiteManager(None), getGlobalSiteManager())
+        self.assertEqual(getSiteManager(self.root), getGlobalSiteManager())
+        self.assertEqual(getSiteManager(self.f1), self.sm1)
+        self.assertEqual(getSiteManager(self.f2), self.sm2)
+        setSite(self.f2)
+        self.assertEqual(getSiteManager(None), self.sm2)
+
+    def test_queryNextSiteManager(self):
+        from zope.app.component import queryNextSiteManager
+        marker = object()
+        self.assert_(queryNextSiteManager(self.root, marker) is marker)
+        self.assert_(queryNextSiteManager(self.f1, marker) is getGlobalSiteManager())
+        #XXX the following used to be
+        #self.assertEqual(queryNextSiteManager(self.f2, marker), marker)
+        self.assertEqual(queryNextSiteManager(self.f2, marker), self.sm1)
+        self.assertEqual(queryNextSiteManager(self.sm1), getGlobalSiteManager())
+        self.assertEqual(queryNextSiteManager(self.sm2), self.sm1)
+        #XXX the following used to be
+        #self.assert_(queryNextSiteManager(self.p1) is getGlobalSiteManager())
+        self.assert_(queryNextSiteManager(self.p1, marker) is marker)
+        #XXX the following used to be
+        #self.assertEqual(queryNextSiteManager(self.p2), self.sm1)
+        self.assert_(queryNextSiteManager(self.p2, marker) is marker)
+
+        self.assert_(queryNextSiteManager(self.unparented_folder, marker)
+                     is marker)
+        self.assert_(queryNextSiteManager(self.unrooted_subfolder, marker)
+                     is marker)
+
+    def test_getNextSiteManager(self):
+        from zope.app.component import getNextSiteManager
+        self.assertRaises(ComponentLookupError, getNextSiteManager, self.root)
+        self.assertEqual(getNextSiteManager(self.f1), getGlobalSiteManager())
+        #XXX the following used to be
+        #self.assertRaises(ComponentLookupError, getNextSiteManager, self.f2)
+        self.assertEqual(getNextSiteManager(self.f2), self.sm1)
+        self.assertEqual(getNextSiteManager(self.sm1), getGlobalSiteManager())
+        self.assertEqual(getNextSiteManager(self.sm2), self.sm1)
+        #XXX the following used to be
+        #self.assert_(getNextSiteManager(self.p1) is getGlobalSiteManager())
+        self.assertRaises(ComponentLookupError, getNextSiteManager, self.p1)
+        #XXX the following used to be
+        #self.assertEqual(getNextSiteManager(self.p2), self.sm1)
+        self.assertRaises(ComponentLookupError, getNextSiteManager, self.p2)
+
+        self.assertRaises(ComponentLookupError,
+                          getNextSiteManager, self.unparented_folder)
+        self.assertRaises(ComponentLookupError,
+                          getNextSiteManager, self.unrooted_subfolder)
+
+# XXX Maybe we need to test this with RestrictedPython in the context
+# of Zope2? Maybe we just don't care.
+#
+#     def test_getNextSiteManager_security(self):
+#         from zope.app.component import getNextSiteManager
+#         from zope.security.checker import ProxyFactory, NamesChecker
+#         sm = ProxyFactory(self.sm1, NamesChecker(('next',)))
+#         # Check that getGlobalSiteManager() is not proxied
+#         self.assert_(getNextSiteManager(sm) is getGlobalSiteManager())
+
+    def test_siteManagerAdapter(self):
+        from Products.Five.site.localsite import siteManagerAdapter
+
+        # If it is a site, return the service service.
+        sm = SiteManagerStub()
+        site = Folder()
+        site.setSiteManager(sm)
+        self.assertEqual(siteManagerAdapter(site), sm)
+
+        # If it has an acquisition context, "acquire" the site
+        # and return the service service
+        ob = Folder()
+        ob = ob.__of__(site)
+        self.assertEqual(siteManagerAdapter(ob), sm)
+        ob2 = Folder()
+        ob2 = ob2.__of__(ob)
+        self.assertEqual(siteManagerAdapter(ob2), sm)
+
+        # If it does we are unable to find a service service, raise
+        # ComponentLookupError
+        orphan = Folder()
+        self.failUnless(siteManagerAdapter(orphan) is getGlobalSiteManager())
+
+    def test_setThreadSite_clearThreadSite(self):
+        from zope.app.component.site import threadSiteSubscriber, clearSite
+        from zope.app.publication.zopepublication import BeforeTraverseEvent
+
+        self.assertEqual(getSite(), None)
+
+        # A site is traversed
+        sm = SiteManagerStub()
+        site = Folder()
+        site.setSiteManager(sm)
+
+        ev = BeforeTraverseEvent(site, object())
+        threadSiteSubscriber(site, ev)
+        self.assertEqual(getSite(), site)
+
+        clearSite()
+        self.assertEqual(getSite(), None)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(SiteManagerTest))
+    return suite
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_localsite.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_sitemanager.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_sitemanager.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_sitemanager.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Test Five site manager
+
+$Id$
+"""
+import os, sys
+
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+def test_suite():
+    from Testing.ZopeTestCase import ZopeDocFileSuite
+    return ZopeDocFileSuite('sitemanager.txt', package="Products.Five.site.tests")
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_sitemanager.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_utility.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_utility.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_utility.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,228 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Test local sites
+
+$Id$
+"""
+import os, sys
+
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+import unittest
+import sets
+from Testing import ZopeTestCase
+
+from zope.interface import directlyProvides
+from zope.component import provideUtility
+from zope.component.exceptions import ComponentLookupError
+from zope.app import zapi
+from zope.app.testing.placelesssetup import setUp, tearDown
+from zope.app.component import getNextUtility
+from zope.app.component.hooks import setSite, clearSite, setHooks
+
+import Products.Five
+from Products.Five import zcml
+from Products.Five.site.interfaces import IRegisterUtilitySimply
+from Products.Five.site.localsite import enableLocalSiteHook
+from Products.Five.site.tests.dummy import manage_addDummySite, \
+     IDummyUtility, ISuperDummyUtility, DummyUtility
+
+class LocalUtilityServiceTest(ZopeTestCase.ZopeTestCase):
+
+    def afterSetUp(self):
+        setUp()
+        zcml.load_config("meta.zcml", Products.Five)
+        zcml.load_config("permissions.zcml", Products.Five)
+        zcml.load_config("configure.zcml", Products.Five.site)
+        zcml_text = """\
+        <five:localsite
+            xmlns:five="http://namespaces.zope.org/five"
+            class="Products.Five.site.tests.dummy.DummySite" />"""
+        zcml.load_string(zcml_text)
+        manage_addDummySite(self.folder, 'site')
+        enableLocalSiteHook(self.folder.site)
+        setSite(self.folder.site)
+
+        # Hook up custom component architecture calls; we need to do
+        # this here because zope.app.component.hooks registers a
+        # cleanup with the testing cleanup framework, so the hooks get
+        # torn down by placelesssetup each time.
+        setHooks()
+
+    def beforeTearDown(self):
+        tearDown()
+
+    def test_getSiteManagerHook(self):
+        from Products.Five.site.localsite import FiveSiteManager
+        from Products.Five.site.utility import SimpleLocalUtilityRegistry
+
+        local_sm = zapi.getSiteManager(None)
+        self.failIf(local_sm is zapi.getGlobalSiteManager())
+        self.failUnless(isinstance(local_sm, FiveSiteManager))
+
+        local_sm = zapi.getSiteManager(self.folder.site)
+        self.failIf(local_sm is zapi.getGlobalSiteManager())
+        self.failUnless(isinstance(local_sm, FiveSiteManager))
+
+        sm = zapi.getSiteManager()
+        self.failUnless(isinstance(sm.utilities, SimpleLocalUtilityRegistry))
+
+    def test_getUtilitiesNoUtilitiesFolder(self):
+        sm = zapi.getSiteManager()
+        #XXX test whether sm really is a local site...
+        self.failUnless(sm.queryUtility(IDummyUtility) is None)
+        self.assertEquals(list(sm.getUtilitiesFor(IDummyUtility)), [])
+        self.assertEquals(list(sm.getAllUtilitiesRegisteredFor(IDummyUtility)), [])
+
+    def test_registerUtilityOnUtilityRegistry(self):
+        utils = zapi.getSiteManager().utilities
+        dummy = DummyUtility()
+        utils.registerUtility(IDummyUtility, dummy, 'dummy')
+
+        self.assertEquals(zapi.getUtility(IDummyUtility, name='dummy'), dummy)
+        self.assertEquals(list(zapi.getUtilitiesFor(IDummyUtility)), 
+                          [('dummy', dummy)])
+        self.assertEquals(list(zapi.getAllUtilitiesRegisteredFor(
+            IDummyUtility)), [dummy])
+
+    def test_registerUtilityOnSiteManager(self):
+        sm = zapi.getSiteManager()
+        self.failUnless(IRegisterUtilitySimply.providedBy(sm))
+        dummy = DummyUtility()
+        sm.registerUtility(IDummyUtility, dummy, 'dummy')
+
+        self.assertEquals(zapi.getUtility(IDummyUtility, name='dummy'), dummy)
+        self.assertEquals(list(zapi.getUtilitiesFor(IDummyUtility)), 
+                          [('dummy', dummy)])
+        self.assertEquals(list(zapi.getAllUtilitiesRegisteredFor(
+            IDummyUtility)), [dummy])
+
+    def test_registerTwoUtilitiesWithSameNameDifferentInterface(self):
+        sm = zapi.getSiteManager()
+        self.failUnless(IRegisterUtilitySimply.providedBy(sm))
+        dummy = DummyUtility()
+        superdummy = DummyUtility()
+        directlyProvides(superdummy, ISuperDummyUtility)
+        sm.registerUtility(IDummyUtility, dummy, 'dummy')
+        sm.registerUtility(ISuperDummyUtility, superdummy, 'dummy')
+
+        self.assertEquals(zapi.getUtility(IDummyUtility, 'dummy'), dummy)
+        self.assertEquals(zapi.getUtility(ISuperDummyUtility, 'dummy'),
+                          superdummy)
+
+    def test_nestedSitesDontConflictButStillAcquire(self):
+        # let's register a dummy utility in the dummy site
+        dummy = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, dummy)
+
+        # let's also create a subsite and make that our site
+        manage_addDummySite(self.folder.site, 'subsite')
+        enableLocalSiteHook(self.folder.site.subsite)
+        setSite(self.folder.site.subsite)
+
+        # we should still be able to lookup the original utility from
+        # the site one level above
+        self.assertEqual(zapi.getUtility(IDummyUtility), dummy)
+
+        # now we register a dummy utility in the subsite and see that
+        # its registration doesn't conflict
+        subdummy = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, subdummy)
+
+        # when we look it up we get the more local one now because the
+        # more local one shadows the less local one
+        self.assertEqual(zapi.getUtility(IDummyUtility), subdummy)
+
+        # getAllUtilitiesFor gives us both the more local and the less
+        # local utility (XXX not sure if this is the right semantics
+        # for getAllUtilitiesFor)
+        self.assertEqual(sets.Set(zapi.getAllUtilitiesRegisteredFor(IDummyUtility)),
+                         sets.Set([subdummy, dummy]))
+
+        # getUtilitiesFor will only find one, because the more local
+        # one shadows the less local one
+        self.assertEqual(list(zapi.getUtilitiesFor(IDummyUtility)),
+                         [('', subdummy)])
+
+    def test_registeringTwiceIsConflict(self):
+        dummy1 = DummyUtility()
+        dummy2 = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, dummy1)
+        self.assertRaises(ValueError, sm.registerUtility,
+                          IDummyUtility, dummy2)
+
+        sm.registerUtility(IDummyUtility, dummy1, 'dummy')
+        self.assertRaises(ValueError, sm.registerUtility,
+                          IDummyUtility, dummy2, 'dummy')
+
+    def test_utilitiesHaveProperAcquisitionContext(self):
+        dummy = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, dummy)
+
+        # let's see if we can acquire something all the way from the
+        # root (Application) object; we need to be careful to choose
+        # something that's only available from the root object
+        from Acquisition import aq_acquire
+        dummy = zapi.getUtility(IDummyUtility)
+        acquired = aq_acquire(dummy, 'ZopeAttributionButton', None)
+        self.failUnless(acquired is not None)
+
+        name, dummy = zapi.getUtilitiesFor(IDummyUtility).next()
+        acquired = aq_acquire(dummy, 'ZopeAttributionButton', None)
+        self.failUnless(acquired is not None)
+
+        dummy = zapi.getAllUtilitiesRegisteredFor(IDummyUtility).next()
+        acquired = aq_acquire(dummy, 'ZopeAttributionButton', None)
+        self.failUnless(acquired is not None)        
+
+    def test_getNextUtility(self):
+        # test local site vs. global site
+        global_dummy = DummyUtility()
+        provideUtility(global_dummy, IDummyUtility)
+
+        local_dummy = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, local_dummy)
+
+        self.assertEquals(zapi.getUtility(IDummyUtility), local_dummy)
+        self.assertEquals(getNextUtility(self.folder.site, IDummyUtility),
+                          global_dummy)
+
+        # test local site vs. nested local site
+        manage_addDummySite(self.folder.site, 'subsite')
+        enableLocalSiteHook(self.folder.site.subsite)
+        setSite(self.folder.site.subsite)
+
+        sublocal_dummy = DummyUtility()
+        sm = zapi.getSiteManager()
+        sm.registerUtility(IDummyUtility, sublocal_dummy)
+
+        self.assertEquals(zapi.getUtility(IDummyUtility), sublocal_dummy)
+        self.assertEquals(getNextUtility(self.folder.site.subsite, IDummyUtility),
+                          local_dummy)
+        self.assertEquals(getNextUtility(self.folder.site, IDummyUtility),
+                          global_dummy)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(LocalUtilityServiceTest))
+    return suite
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/tests/test_utility.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/utility.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/utility.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/utility.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""Local utility registration
+
+$Id$
+"""
+from zope.interface import implements
+from zope.component import getGlobalSiteManager
+from zope.component.exceptions import ComponentLookupError
+from zope.app.component import getNextSiteManager
+
+from Acquisition import aq_base
+from OFS.Folder import Folder
+from Products.Five.site.interfaces import IFiveUtilityRegistry
+
+class SimpleLocalUtilityRegistry(object):
+    implements(IFiveUtilityRegistry)
+
+    def __init__(self, context):
+        self.context = context
+        # make {get|query}NextSiteManager() work without having to
+        # resort to Zope 2 acquisition
+        self.__parent__ = self.context.getSiteManager()
+
+    @property
+    def next(self):
+        try:
+            return getNextSiteManager(self)
+        except ComponentLookupError:
+            return getGlobalSiteManager()
+
+    def getUtility(self, interface, name=''):
+        """See IFiveUtilityRegistry interface
+        """
+        c = self.queryUtility(interface, name)
+        if c is not None:
+            return c
+        raise ComponentLookupError(interface, name)
+
+    def queryUtility(self, interface, name='', default=None):
+        """See IFiveUtilityRegistry interface
+        """
+        if name == '':
+            # Singletons. Only one per interface allowed, so, let's call it
+            # by the interface.
+            id = interface.getName()
+        else:
+            id = interface.getName() + '-' + name
+
+        if getattr(aq_base(self.context), 'utilities', None) is not None:
+            utility = self.context.utilities._getOb(id, None)
+            if utility is not None:
+                return utility
+        return self.next.queryUtility(interface, name, default)
+
+    def getUtilitiesFor(self, interface):
+        names = []
+        prefix = interface.getName() + '-'
+        if getattr(aq_base(self.context), 'utilities', None) is not None:
+            for name, utility in self.context.utilities.objectItems():
+                if name == interface.getName():
+                    names.append('')
+                    yield '', utility
+                elif name.startswith(prefix):
+                    name = name[len(prefix):]
+                    names.append(name)
+                    yield (name, utility)
+        for name, utility in self.next.getUtilitiesFor(interface):
+            if name not in names:
+                yield name, utility
+
+    def getAllUtilitiesRegisteredFor(self, interface):
+        # This also supposedly returns "overridden" utilities, but we don't
+        # keep them around. It also does not return the name-value pair that
+        # getUtilitiesFor returns.
+        if getattr(aq_base(self.context), 'utilities', None) is not None:
+            for utility in self.context.utilities.objectValues():
+                if interface.providedBy(utility):
+                    yield utility
+        for utility in self.next.getAllUtilitiesRegisteredFor(interface):
+            yield utility
+
+    def registerUtility(self, interface, utility, name=''):
+        # I think you are *really* supposed to:
+        # 1. Check if there is a "registrations" object for utilities.
+        # 2. If not create one.
+        # 3. Get it.
+        # 4. Create a registration object for the utility.
+        # 5. Rgister the registration object in the registrations.
+        # But that is quite complex, and Jim sais he wants to change that
+        # anyway, and in any case the way you would normally do this in Zope3
+        # and Five would probably differ anyway, so, here is this new
+        # Five-only, easy to use method!
+
+        if getattr(aq_base(self.context), 'utilities', None) is None:
+            self.context._setObject('utilities', Folder('utilities'))
+        utilities = self.context.utilities
+
+        if name == '':
+            # Singletons. Only one per interface allowed, so, let's call it
+            # by the interface.
+            id = interface.getName()
+        else:
+            id = interface.getName() + '-' + name
+
+        if id in utilities.objectIds():
+            raise ValueError("There is already a utility registered for "
+                             "%s with the name '%s'" % (interface.getName(),
+                                                        name))
+        utilities._setObject(id, utility)
+
+# BBB 2005/11/01 -- gone in Five 1.5.
+SimpleLocalUtilityService = SimpleLocalUtilityRegistry
+import zope.deprecation
+zope.deprecation.deprecated(
+    'SimpleLocalUtilityService', "'SimpleLocalUtilityService' has been renamed to "
+    "'SimpleLocalUtilityRegistry' and will disappear in Five 1.5."
+    )


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/site/utility.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/standardmacros.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/standardmacros.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/standardmacros.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,17 +13,17 @@
 ##############################################################################
 """Mimick the Zope 3 skinning system in Five.
 
-$Id: standardmacros.py 12884 2005-05-30 13:10:41Z philikon $
+$Id: standardmacros.py 19283 2005-10-31 17:43:51Z philikon $
 """
-from zope.interface.common.mapping import IItemMapping
-from zope.interface import implements
-from zope.component import getView
+import zope.interface
+
+from zope.app import zapi
 from Products.Five.browser import BrowserView
 
 # this is a verbatim copy of zope.app.basicskin except that it doesn't
 # derive from ``object``
 class Macros:
-    implements(IItemMapping)
+    zope.interface.implements(zope.interface.common.mapping.IItemMapping)
 
     macro_pages = ()
     aliases = {
@@ -37,7 +37,7 @@
         context = self.context
         request = self.request
         for name in self.macro_pages:
-            page = getView(context, name, request)
+            page = zapi.getMultiAdapter((context, request), name=name)
             try:
                 v = page[key]
             except KeyError:

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/tests/test_standardmacros.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/tests/test_standardmacros.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/skin/tests/test_standardmacros.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -26,7 +26,7 @@
       >>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
       >>> self.login('manager')
 
-      >>> from Products.Five.testing import manage_addFiveTraversableFolder
+      >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
       >>> manage_addFiveTraversableFolder(self.folder, 'testoid', 'Testoid')
 
       >>> import Products.Five.skin.tests
@@ -72,7 +72,7 @@
 
     Clean up:
 
-      >>> from zope.app.tests.placelesssetup import tearDown
+      >>> from zope.app.testing.placelesssetup import tearDown
       >>> tearDown()
     """
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/README.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/README.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/README.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,16 +1,8 @@
 Five tests
 ==========
 
-The tests require ZopeTestCase to be installed. ZopeTestCase can be
-downloaded from here:
+All you have to do is type::
 
-http://zope.org/Members/shh/ZopeTestCase
+  $ bin/zopectl test -s Products.Five
 
-it needs to be installed in your Zope software's lib/python/Testing
-directory.
-
-Then, if you have Zope 2.7.3 or better all you have to do is type::
-
-  ./bin/zopectl test --dir Products/Five
-
-to run the Five tests. 
+to run the Five tests.

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/boilerplate.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/boilerplate.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/boilerplate.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -21,16 +21,16 @@
 
 def test_boilerplate():
     """
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
       >>> import Products.Five.tests
       >>> from Products.Five import zcml
       >>> zcml.load_config('boilerplate.zcml', Products.Five.tests)
 
-      >>> from Products.Five.testing import manage_addFiveTraversableFolder
-      >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
-      >>> from Products.Five.testing.fancycontent import manage_addFancyContent
+      >>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
+      >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
+      >>> from Products.Five.tests.testing.fancycontent import manage_addFancyContent
 
       >>> tearDown()
     """

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/directives.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/directives.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/directives.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -11,17 +11,17 @@
        once on a class; SimpleContent inherits from Traversable, so
        one directive suffices here -->
 
-  <five:traversable class="Products.Five.testing.simplecontent.SimpleContent" />
+  <five:traversable class="Products.Five.tests.testing.simplecontent.SimpleContent" />
 
   <!-- this is a test whether the *directive* can be called more than
        once without raising a conflicting configuration exception -->
 
-  <five:traversable class="Products.Five.testing.simplecontent.SimpleContent" />
+  <five:traversable class="Products.Five.tests.testing.simplecontent.SimpleContent" />
 
   <!-- this tests whether five:traversable can be called on a class that
        already provides __bobo_traverse__, such as our FancyContent -->
 
-  <five:traversable class="Products.Five.testing.fancycontent.FancyContent" />
+  <five:traversable class="Products.Five.tests.testing.fancycontent.FancyContent" />
 
   <!-- Testing the vocabulary directive -->
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/event.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/event.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/event.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,295 +1,394 @@
-Test events
-===========
+================
+Container events
+================
 
-Before we can start, we need to set up an event subscriber that allows
-us to inspect events that will be thrown during the test:
+Zope 3 container events are used to inform subscribers that an object is
+about to be added/removed from a container, and also after it has been
+done. This is used for bookkeeping and cleaning up in subobjects.
 
-  >>> from zope.app.tests.placelesssetup import setUp, tearDown
-  >>> setUp()
+These events replace the old Zope 2 manage_afterAdd, manage_beforeDelete
+and manage_afterClone methods.
 
-Add a folder that doesn't verify objects on paste.  We use it as a
-test sandbox:
+All standard Zope containers will only call manage_afterAdd & co on
+classes specified with the directive::
 
-  >>> from Products.Five.testing import manage_addNoVerifyPasteFolder
-  >>> manage_addNoVerifyPasteFolder(self.folder, 'npvf')
-  >>> folder = self.folder.npvf
+  <five:deprecatedManageAddDelete class="some.content.class"/>
 
-Finally add a manager user login, give it the right permissions and
-log in using it:
+Classes that don't have this directive but still have manage_afterAdd &
+co methods will trigger a warning when they are called (and this is
+strictly a compatibility call, behavior may not be strictly equivalent
+to the original one).
 
-  >>> uf = self.folder.acl_users
-  >>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
-  >>> self.setPermissions(standard_permissions + ['Copy or Move'], 'Manager')
-  >>> self.login('manager')
+Test setup
+==========
 
-  >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+A bit of setup for the tests. Because we'll test copy/paste, we need to
+work inside a database::
 
+  >>> from zope.app.testing.placelesssetup import setUp, tearDown
+  >>> setUp()
 
-Sending events
---------------
+  >>> import ZODB.tests.util
+  >>> db = ZODB.tests.util.DB()
+  >>> connection = db.open()
+  >>> root = connection.root()
 
-Zope 2 classes need to be modified so that they send Zope 3 style
-events.  Our stub class here is such a case.  We can add it to a
-folder, for example, ...
+We'll use a few simple classes (defined in python code for picklability)
+for our tests.
 
-  >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
-  >>> manage_addSimpleContent(folder, 'foo', 'Foo')
+  >>> from Products.Five.tests.test_event import MyApp, MyContent
+  >>> from Products.Five.tests.test_event import MyFolder, MyBTreeFolder
+  >>> from Products.Five.tests.test_event import MyOrderedFolder
 
-and no event will have been triggered:
+  >>> app = MyApp('')
+  >>> root['app'] = app
+  >>> folder = MyFolder('folder')
+  >>> app._setObject('folder', folder) # doctest: +NORMALIZE_WHITESPACE
+  old manage_afterAdd folder folder
+  'folder'
+  >>> folder = app.folder
+  >>> btfolder = MyBTreeFolder('btfolder')
+  >>> app._setObject('btfolder', btfolder) # doctest: +NORMALIZE_WHITESPACE
+  old manage_afterAdd btfolder btfolder
+  'btfolder'
 
-  >>> len(getEvents())
-  0
+To observe what object events are dispatched, we'll have some
+subscribers print them. We'll actually do that for a specific interface,
+not for (None, IObjectEvent), and register our subscribers before the
+framework's ones, so ours will be called first. This has the effect that
+printed events will be in their "natural" order::
 
-Clean up:
+  >>> from zope.app.event.interfaces import IObjectEvent
+  >>> from zope.app.container.interfaces import IObjectMovedEvent
+  >>> from OFS.interfaces import IObjectWillBeMovedEvent
+  >>> from OFS.interfaces import IObjectClonedEvent
+  >>> from OFS.interfaces import IItem
+  >>> def printObjectEvent(object, event):
+  ...     print event.__class__.__name__, object.getId()
+  >>> def printObjectEventExceptSome(object, event):
+  ...     if (IObjectMovedEvent.providedBy(event) or
+  ...         IObjectWillBeMovedEvent.providedBy(event) or
+  ...         IObjectClonedEvent.providedBy(event)):
+  ...         return
+  ...     print event.__class__.__name__, object.getId()
 
-  >>> folder.manage_delObjects(['foo'])
+  >>> from zope.component import provideHandler
+  >>> provideHandler(printObjectEvent, (IItem, IObjectMovedEvent))
+  >>> provideHandler(printObjectEvent, (IItem, IObjectWillBeMovedEvent))
+  >>> provideHandler(printObjectEvent, (IItem, IObjectClonedEvent))
+  >>> provideHandler(printObjectEventExceptSome, (None, IObjectEvent))
 
-Now make the class send events:
+Finally we need to load the subscribers configuration::
 
-  >>> from Products.Five.eventconfigure import classSendEvents
-  >>> from Products.Five.testing.simplecontent import SimpleContent
-  >>> classSendEvents(SimpleContent)
+  >>> from Products.Five import zcml
+  >>> import Products.Five
+  >>> import zope.app.component
+  >>> zcml.load_config('meta.zcml', zope.app.component)
+  >>> zcml.load_config('event.zcml', Products.Five)
 
+Old class
+=========
 
-Added event
-------------
+If we use an instance of an old class for which we haven't specified
+anything, events are sent and the manage_afterAdd & co methods are
+called but in a "compatibility" way.
 
-Let's add an object to a folder:
+Because the bases classes of Zope have been changed to not recurse
+except through the event framework, unexpected behavior may happen
+(however a warning will be sent)::
 
-  >>> manage_addSimpleContent(folder, 'foo', 'Foo')
+  >>> ob = MyContent('dog')
+  >>> folder._setObject('dog', ob)
+  ObjectWillBeAddedEvent dog
+  ObjectAddedEvent dog
+  old manage_afterAdd dog dog folder
+  'dog'
 
-One object event should have been sent with the event's object being
-our foo object:
+And when we delete the object, manage_beforeDelete is also called and
+events are sent::
 
-  >>> events = getEvents()
-  >>> len(events)
-  1
-  >>> foo = folder.foo
-  >>> events[0].object == foo
-  True
+  >>> folder.manage_delObjects('dog')
+  old manage_beforeDelete dog dog folder
+  ObjectWillBeRemovedEvent dog
+  ObjectRemovedEvent dog
 
-That object event should have been an object added event:
+Old class with deprecatedManageAddDelete
+========================================
 
-  >>> from zope.app.container.interfaces import IObjectAddedEvent
-  >>> events = getEvents(IObjectAddedEvent)
-  >>> len(events)
-  1
-  >>> events[0].object == foo
-  True
-  >>> events[0].newParent == foo.aq_parent
-  True
+We specifiy that our class is deprecated (using zcml in real life)::
 
-Check that the object's original manage_afterAdd method was also called:
+  >>> from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+  >>> setDeprecatedManageAddDelete(MyContent)
+  >>> setDeprecatedManageAddDelete(MyFolder)
+  >>> setDeprecatedManageAddDelete(MyOrderedFolder)
 
-  >>> foo.afterAdd_called
-  True
+Now some events are sent but the old manage_afterAdd method is also
+called correctly::
 
-Now clean up:
+  >>> ob = MyContent('lassie')
+  >>> folder._setObject('lassie', ob)
+  ObjectWillBeAddedEvent lassie
+  ObjectAddedEvent lassie
+  old manage_afterAdd lassie lassie folder
+  'lassie'
 
-  >>> clearEvents()
+And when we delete the object, manage_beforeDelete is also called and
+events are sent::
 
+  >>> folder.manage_delObjects('lassie')
+  ObjectWillBeRemovedEvent lassie
+  old manage_beforeDelete lassie lassie folder
+  ObjectRemovedEvent lassie
 
-Moved event (I) -- Renaming
---------------------------
+The old behavior happens for a move or a copy, with events too.
+For a move::
 
-Somehow we need to at least commit a subtransaction to make renaming
-succeed:
+  >>> ob = MyContent('blueberry')
+  >>> folder._setObject('blueberry', ob)
+  ObjectWillBeAddedEvent blueberry
+  ObjectAddedEvent blueberry
+  old manage_afterAdd blueberry blueberry folder
+  'blueberry'
+  >>> cp = folder.manage_cutObjects('blueberry')
+  >>> folder.manage_pasteObjects(cp)
+  ObjectWillBeMovedEvent blueberry
+  old manage_beforeDelete blueberry blueberry folder
+  ObjectMovedEvent blueberry
+  old manage_afterAdd blueberry blueberry folder
+  [{'new_id': 'blueberry', 'id': 'blueberry'}]
 
-  >>> import transaction
-  >>> transaction.commit(1)
+Old behavior with events for a copy::
 
-Let's rename the object we created before:
+  >>> cp = folder.manage_copyObjects('blueberry')
+  >>> folder.manage_pasteObjects(cp)
+  ObjectCopiedEvent copy_of_blueberry
+  ObjectWillBeAddedEvent copy_of_blueberry
+  ObjectAddedEvent copy_of_blueberry
+  old manage_afterAdd copy_of_blueberry copy_of_blueberry folder
+  ObjectClonedEvent copy_of_blueberry
+  old manage_afterClone copy_of_blueberry copy_of_blueberry
+  [{'new_id': 'copy_of_blueberry', 'id': 'blueberry'}]
 
-  >>> folder.manage_renameObject('foo', 'bar')
+Old behavior with events for a renaming::
 
-We should get two events...
+  >>> folder.manage_renameObject('copy_of_blueberry', 'myrtille')
+  ObjectWillBeMovedEvent copy_of_blueberry
+  old manage_beforeDelete copy_of_blueberry copy_of_blueberry folder
+  ObjectMovedEvent myrtille
+  old manage_afterAdd myrtille myrtille folder
 
-  >>> events = getEvents()
-  >>> len(events)
-  2
+Old behavior with events for a clone::
 
-the removed event...
+  >>> res = folder.manage_clone(folder.blueberry, 'strawberry')
+  ObjectCopiedEvent strawberry
+  ObjectWillBeAddedEvent strawberry
+  ObjectAddedEvent strawberry
+  old manage_afterAdd strawberry strawberry folder
+  ObjectClonedEvent strawberry
+  old manage_afterClone strawberry strawberry
+  >>> res.getId()
+  'strawberry'
 
-  >>> event = events[0]
-  >>> from zope.app.container.interfaces import IObjectRemovedEvent
-  >>> IObjectRemovedEvent.providedBy(event)
-  True
-  >>> event.object == foo
-  True
-  >>> event.oldName, event.newName
-  ('foo', None)
-  >>> event.oldParent == folder
-  True
-  >>> event.newParent is None
-  True
+Events are also sent when we work with a BTreeFolder::
 
-and the moved event:
+  >>> ob = MyContent('luckyluke')
+  >>> btfolder._setObject('luckyluke', ob)
+  ObjectWillBeAddedEvent luckyluke
+  ObjectAddedEvent luckyluke
+  old manage_afterAdd luckyluke luckyluke btfolder
+  'luckyluke'
 
-  >>> event = events[1]
-  >>> event.object == foo
-  True
-  >>> event.oldName, event.newName
-  ('foo', 'bar')
-  >>> event.oldParent == folder
-  True
-  >>> event.newParent == folder
-  True
+  >>> btfolder.manage_delObjects('luckyluke')
+  ObjectWillBeRemovedEvent luckyluke
+  old manage_beforeDelete luckyluke luckyluke btfolder
+  ObjectRemovedEvent luckyluke
 
-Now clean up:
+Here is what happens for a tree of objects. Let's create a simple one::
 
-  >>> folder.manage_delObjects(['bar'])
-  >>> clearEvents()
+  >>> subfolder = MyFolder('subfolder')
+  >>> folder._setObject('subfolder', subfolder)
+  ObjectWillBeAddedEvent subfolder
+  ObjectAddedEvent subfolder
+  old manage_afterAdd subfolder subfolder folder
+  'subfolder'
+  >>> subfolder = folder.subfolder
+  >>> ob = MyContent('donald')
+  >>> subfolder._setObject('donald', ob)
+  ObjectWillBeAddedEvent donald
+  ObjectAddedEvent donald
+  old manage_afterAdd donald donald subfolder
+  'donald'
 
-We don't delete the stub object just yet because it's being used in
-the next part of the test.
+Renaming a tree of objects. Note that manage_beforeDelete is called
+bottom-up::
 
+  >>> folder.manage_renameObject('subfolder', 'pluto')
+  ObjectWillBeMovedEvent subfolder
+  ObjectWillBeMovedEvent donald
+  old manage_beforeDelete donald subfolder folder
+  old manage_beforeDelete subfolder subfolder folder
+  ObjectMovedEvent pluto
+  old manage_afterAdd pluto pluto folder
+  ObjectMovedEvent donald
+  old manage_afterAdd donald pluto folder
 
-Moved event (II) -- Cut and paste
----------------------------------
+Cloning a tree of objects::
 
-Let's move from one folder to another:
+  >>> res = folder.manage_clone(folder.pluto, 'mickey')
+  ObjectCopiedEvent mickey
+  ObjectWillBeAddedEvent mickey
+  ObjectWillBeAddedEvent donald
+  ObjectAddedEvent mickey
+  old manage_afterAdd mickey mickey folder
+  ObjectAddedEvent donald
+  old manage_afterAdd donald mickey folder
+  ObjectClonedEvent mickey
+  old manage_afterClone mickey mickey
+  ObjectClonedEvent donald
+  old manage_afterClone donald mickey
+  >>> res.getId()
+  'mickey'
 
-  >>> manage_addNoVerifyPasteFolder(folder, 'folder1', 'Folder1')
-  >>> folder1 = folder.folder1
-  >>> manage_addNoVerifyPasteFolder(folder, 'folder2', 'Folder2')
-  >>> folder2 = folder.folder2
-  >>> manage_addSimpleContent(folder1, 'foo', 'Foo')
-  >>> foo = folder1.foo
+New class
+=========
 
-We need to trigger a subtransaction before cut/paste can work:
+If we use classes that don't have any manage_afterAdd & co method,
+everything happens correctly::
 
-  >>> transaction.commit(1)
-  >>> cb = folder1.manage_cutObjects(['foo'])
-  >>> info = folder2.manage_pasteObjects(cb)
+  >>> from Products.Five.tests.test_event import MyNewFolder, MyNewContent
+  >>> app = MyApp('')
+  >>> root['app'] = app
+  >>> folder = MyNewFolder('folder')
+  >>> app._setObject('folder', folder)
+  ObjectWillBeAddedEvent folder
+  ObjectAddedEvent folder
+  'folder'
+  >>> folder = app.folder
 
-Apart from the added event we triggerred when we added the stub object
-to the folder, we expect two events...
+  >>> ob = MyNewContent('dogbert')
+  >>> folder._setObject('dogbert', ob)
+  ObjectWillBeAddedEvent dogbert
+  ObjectAddedEvent dogbert
+  'dogbert'
+  >>> folder.manage_delObjects('dogbert')
+  ObjectWillBeRemovedEvent dogbert
+  ObjectRemovedEvent dogbert
 
-  >>> events = getEvents()
-  >>> len(events)
-  3
-  >>> len(getEvents(IObjectAddedEvent))
-  1
+Now move::
 
-a removed event...
+  >>> ob = MyNewContent('dilbert')
+  >>> folder._setObject('dilbert', ob)
+  ObjectWillBeAddedEvent dilbert
+  ObjectAddedEvent dilbert
+  'dilbert'
+  >>> cp = folder.manage_cutObjects('dilbert')
+  >>> folder.manage_pasteObjects(cp)
+  ObjectWillBeMovedEvent dilbert
+  ObjectMovedEvent dilbert
+  [{'new_id': 'dilbert', 'id': 'dilbert'}]
 
-  >>> event = events[1]
-  >>> from zope.app.container.interfaces import IObjectRemovedEvent
-  >>> IObjectRemovedEvent.providedBy(event)
-  True
-  >>> event.oldParent == folder1
-  True
-  >>> event.newParent is None
-  True
+And copy::
 
-and a moved event:
+  >>> cp = folder.manage_copyObjects('dilbert')
+  >>> folder.manage_pasteObjects(cp)
+  ObjectCopiedEvent copy_of_dilbert
+  ObjectWillBeAddedEvent copy_of_dilbert
+  ObjectAddedEvent copy_of_dilbert
+  ObjectClonedEvent copy_of_dilbert
+  [{'new_id': 'copy_of_dilbert', 'id': 'dilbert'}]
 
-  >>> event = events[2]
-  >>> event.object == foo
-  True
-  >>> event.oldName, event.newName
-  ('foo', 'foo')
-  >>> event.oldParent == folder1
-  True
-  >>> event.newParent == folder2
-  True
+Then rename::
 
-Now clean up:
+  >>> folder.manage_renameObject('copy_of_dilbert', 'wally')
+  ObjectWillBeMovedEvent copy_of_dilbert
+  ObjectMovedEvent wally
 
-  >>> folder.manage_delObjects(['folder1'])
-  >>> folder.manage_delObjects(['folder2'])
-  >>> clearEvents()
+Or copy using manage_clone::
 
+  >>> res = folder.manage_clone(folder.dilbert, 'phb')
+  ObjectCopiedEvent phb
+  ObjectWillBeAddedEvent phb
+  ObjectAddedEvent phb
+  ObjectClonedEvent phb
+  >>> res.getId()
+  'phb'
 
-Copied event
-------------
+Also on a BTreeFolder::
 
-  >>> manage_addSimpleContent(folder, 'foo', 'Foo')
-  >>> manage_addNoVerifyPasteFolder(folder, 'folder1')
-  >>> folder1 = folder.folder1
+  >>> ob = MyNewContent('alice')
+  >>> btfolder._setObject('alice', ob)
+  ObjectWillBeAddedEvent alice
+  ObjectAddedEvent alice
+  'alice'
+  >>> btfolder.manage_renameObject('alice', 'rabbit')
+  ObjectWillBeMovedEvent alice
+  ObjectMovedEvent rabbit
+  >>> btfolder.manage_delObjects('rabbit')
+  ObjectWillBeRemovedEvent rabbit
+  ObjectRemovedEvent rabbit
 
-We need to trigger subtransaction before copy/paste can work
+Now for a tree of objects. Let's create a simple one::
 
-  >>> transaction.commit(1)
-  >>> cb = folder.manage_copyObjects(['foo'])
-  >>> info = folder1.manage_pasteObjects(cb)
-  >>> foo = folder1.foo
+  >>> subfolder = MyNewFolder('subfolder')
+  >>> folder._setObject('subfolder', subfolder)
+  ObjectWillBeAddedEvent subfolder
+  ObjectAddedEvent subfolder
+  'subfolder'
+  >>> subfolder = folder.subfolder
+  >>> ob = MyNewContent('mel')
+  >>> subfolder._setObject('mel', ob)
+  ObjectWillBeAddedEvent mel
+  ObjectAddedEvent mel
+  'mel'
 
-Apart from the added event we triggerred when we added the stub object
-to the folder, we expect two events...
+Renaming a tree of objects::
 
-  >>> events = getEvents()
-  >>> len(events)
-  3
+  >>> folder.manage_renameObject('subfolder', 'firefly')
+  ObjectWillBeMovedEvent subfolder
+  ObjectWillBeMovedEvent mel
+  ObjectMovedEvent firefly
+  ObjectMovedEvent mel
 
-a copied event...
+Cloning a tree of objects::
 
-  >>> event = events[1]
-  >>> from zope.app.event.interfaces import IObjectCopiedEvent
-  >>> IObjectCopiedEvent.providedBy(event)
-  True
-  >>> events[1].object == foo
-  True
+  >>> res = folder.manage_clone(folder.firefly, 'serenity')
+  ObjectCopiedEvent serenity
+  ObjectWillBeAddedEvent serenity
+  ObjectWillBeAddedEvent mel
+  ObjectAddedEvent serenity
+  ObjectAddedEvent mel
+  ObjectClonedEvent serenity
+  ObjectClonedEvent mel
+  >>> res.getId()
+  'serenity'
 
-and an added event:
+OrderedFolder has the same renaming behavior than before::
 
-  >>> event = events[2]
-  >>> IObjectAddedEvent.providedBy(event)
-  True
-  >>> event.object == foo
-  True
-  >>> event.newName
-  'foo'
-  >>> event.newParent == folder1
-  True
+  >>> ofolder = MyOrderedFolder('ofolder')
+  >>> app._setObject('ofolder', ofolder) # doctest: +NORMALIZE_WHITESPACE
+  ObjectWillBeAddedEvent ofolder
+  ObjectAddedEvent ofolder
+  old manage_afterAdd ofolder ofolder
+  'ofolder'
+  >>> ob1 = MyNewContent('ob1')
+  >>> ofolder._setObject('ob1', ob1)
+  ObjectWillBeAddedEvent ob1
+  ObjectAddedEvent ob1
+  'ob1'
+  >>> ob2 = MyNewContent('ob2')
+  >>> ofolder._setObject('ob2', ob2)
+  ObjectWillBeAddedEvent ob2
+  ObjectAddedEvent ob2
+  'ob2'
+  >>> ofolder.manage_renameObject('ob1', 'ob4')
+  ObjectWillBeMovedEvent ob1
+  ObjectMovedEvent ob4
+  >>> ofolder.objectIds()
+  ['ob4', 'ob2']
 
-Now clean up:
 
-  >>> folder.manage_delObjects(['folder1'])
-  >>> folder.manage_delObjects(['foo'])
-  >>> clearEvents()
+Now cleanup::
 
-
-Removed event
--------------
-
-  >>> manage_addSimpleContent(folder, 'foo', 'Foo')
-  >>> foo = folder.foo
-  >>> foo.beforeDelete_called
-  False
-  >>> folder.manage_delObjects(['foo'])
-
-  >>> events = getEvents()
-  >>> len(events)
-  2
-
-  >>> events[1].object.id
-  'foo'
-
-Check that the object's original manage_beforeDelete method was also called:
-
-  >>> foo.beforeDelete_called
-  True
-
-  >>> clearEvents()
-
-
-Clean up
---------
-
-Finally, we need to put our stub class back the way it was before we
-monkeyed with it:
-
-  >>> from Products.Five.eventconfigure import cleanUp
-  >>> cleanUp()
-
-Now adding an object won't trigger an event anymore:
-
-  >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
-  >>> manage_addSimpleContent(folder, 'foo', 'Foo')
-  >>> len(getEvents())
-  0
-
-Finally, we need to tear down everything else (services, etc.)
-
+  >>> import transaction
+  >>> transaction.abort()
   >>> tearDown()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_directives.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_directives.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_directives.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -23,9 +23,6 @@
     """
     Test ZCML directives
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
-      >>> setUp()
-
     There isn't much to test here since the actual directive handlers
     are either tested in other, more specific tests, or they're
     already tested in Zope 3.  We'll just do a symbolic test of
@@ -62,9 +59,10 @@
       >>> dest.method()
       'Overridden'
 
-    Clean up:
+    Clean up adapter registry and others:
 
-      >>> tearDown()
+      >>> from zope.testing.cleanup import cleanUp
+      >>> cleanUp()
     """
 
 def test_suite():

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_event.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_event.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_event.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -19,9 +19,64 @@
 if __name__ == '__main__':
     execfile(os.path.join(sys.path[0], 'framework.py'))
 
+
+# These classes aren't defined in the doctest because otherwise
+# they wouldn't be picklable, and we need that to test copy/paste.
+
+from OFS.SimpleItem import SimpleItem
+from OFS.Folder import Folder
+from OFS.OrderedFolder import OrderedFolder
+from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
+
+class DontComplain(object):
+    def _verifyObjectPaste(self, object, validate_src=1):
+        pass
+    def cb_isMoveable(self):
+        return True
+    def cb_isCopyable(self):
+        return True
+
+class NotifyBase(DontComplain):
+    def manage_afterAdd(self, item, container):
+        print 'old manage_afterAdd %s %s %s' % (self.getId(), item.getId(),
+                                                container.getId())
+    def manage_beforeDelete(self, item, container):
+        print 'old manage_beforeDelete %s %s %s' % (self.getId(), item.getId(),
+                                                    container.getId())
+    def manage_afterClone(self, item):
+        print 'old manage_afterClone %s %s' % (self.getId(), item.getId())
+
+class MyApp(Folder):
+    def getPhysicalRoot(self):
+        return self
+
+class MyFolder(NotifyBase, Folder):
+    pass
+
+class MyOrderedFolder(NotifyBase, OrderedFolder):
+    pass
+
+class MyBTreeFolder(NotifyBase, BTreeFolder2):
+    def _verifyObjectPaste(self, object, validate_src=1):
+        pass
+
+class MyContent(NotifyBase, SimpleItem):
+    def __init__(self, id):
+        self._setId(id)
+
+# These don't have manage_beforeDelete & co methods
+
+class MyNewContent(DontComplain, SimpleItem):
+    def __init__(self, id):
+        self._setId(id)
+
+class MyNewFolder(DontComplain, Folder):
+    pass
+
+
 def test_suite():
-    from Testing.ZopeTestCase import ZopeDocFileSuite
-    return ZopeDocFileSuite('event.txt', package="Products.Five.tests")
+    from zope.testing.doctest import DocFileSuite
+    return DocFileSuite('event.txt', package="Products.Five.tests")
 
 if __name__ == '__main__':
     framework()

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_i18n.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_i18n.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_i18n.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -23,7 +23,7 @@
     """
     Test the i18n directive
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     First, we need to register the ZCML directive:
@@ -44,9 +44,9 @@
 
     Now, take an arbitrary message id from that domain:
 
-      >>> from zope.i18nmessageid import MessageIDFactory
+      >>> from zope.i18nmessageid import MessageFactory
       >>> from zope.i18n import translate
-      >>> _ = MessageIDFactory('fivetest')
+      >>> _ = MessageFactory('fivetest')
       >>> msg = _(u'explicit-msg', u'This is an explicit message')
 
     As you can see, both the default functionality and translation to

Deleted: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_import_conflicts.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_import_conflicts.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_import_conflicts.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1,40 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004, 2005 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.
-#
-##############################################################################
-"""Test import conflicts
-
-$Id: test_import_conflicts.py 18150 2005-10-04 16:19:49Z philikon $
-"""
-import os, sys
-if __name__ == '__main__':
-    execfile(os.path.join(sys.path[0], 'framework.py'))
-
-def testImportConflicts():
-    """
-    In a Five environment, importing Zope 3 packages that would use
-    interfaces from the Zope 3 transaction module would lead to an
-    error, because of the monkey patching.  The zope.app.mail package
-    makes use of transaction interfaces, for example the following
-    class:
-
-      >>> from zope.app.mail.delivery import QueueProcessorThread
-
-    Note that this only concerns Zope 2.7 and Zope X3 3.0.
-    """
-
-def test_suite():
-    from Testing.ZopeTestCase import ZopeDocTestSuite
-    return ZopeDocTestSuite()
-
-if __name__ == '__main__':
-    framework()

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_registerclass.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_registerclass.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_registerclass.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,151 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Unit tests for the registerClass directive.
+
+$Id$
+"""
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+def test_registerClass():
+    """
+    Testing registerClass
+
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
+      >>> setUp()
+      >>> import Products
+      >>> import Products.Five
+      >>> from Products.Five import zcml
+      >>> from Products.Five.tests.testing.simplecontent import SimpleContent
+      >>> from Products.Five.tests.testing.simplecontent import ISimpleContent
+      >>> from persistent.interfaces import IPersistent
+
+    Use the five:registerClass directive::
+
+      >>> configure_zcml = '''
+      ... <configure
+      ...     xmlns="http://namespaces.zope.org/zope"
+      ...     xmlns:five="http://namespaces.zope.org/five"
+      ...     i18n_domain="foo">
+      ...   <permission id="foo.add" title="Add Foo"/>
+      ...   <five:registerClass
+      ...       class="Products.Five.tests.testing.simplecontent.SimpleContent"
+      ...       meta_type="Foo Type"
+      ...       permission="foo.add"
+      ...       addview="addfoo.html"
+      ...       icon="foo_icon.png"
+      ...       global="false"
+      ...       />
+      ... </configure>'''
+      >>> zcml.load_config('meta.zcml', Products.Five)
+      >>> zcml.load_string(configure_zcml)
+
+    Make sure that the class attributes are set correctly::
+
+      >>> SimpleContent.meta_type
+      'Foo Type'
+      >>> SimpleContent.icon
+      '++resource++foo_icon.png'
+
+    And the meta_type is registered correctly::
+
+      >>> for info in Products.meta_types:
+      ...     if info['name'] == 'Foo Type':
+      ...         break
+      >>> info['product']
+      'Five'
+      >>> info['permission']
+      'Add Foo'
+      >>> ISimpleContent in info['interfaces']
+      True
+      >>> IPersistent in info['interfaces']
+      True
+      >>> info['visibility'] is None
+      True
+      >>> info['instance'] is SimpleContent
+      True
+      >>> info['action']
+      '+/addfoo.html'
+      >>> info['container_filter'] is None
+      True
+
+    Now reset everything and see what happens without optional parameters::
+
+      >>> tearDown()
+      >>> setUp()
+
+    Use the five:registerClass directive again::
+
+      >>> configure_zcml = '''
+      ... <configure
+      ...     xmlns="http://namespaces.zope.org/zope"
+      ...     xmlns:five="http://namespaces.zope.org/five"
+      ...     i18n_domain="bar">
+      ...   <permission id="bar.add" title="Add Bar"/>
+      ...   <five:registerClass
+      ...       class="Products.Five.tests.testing.simplecontent.SimpleContent"
+      ...       meta_type="Bar Type"
+      ...       permission="bar.add"
+      ...       />
+      ... </configure>'''
+      >>> zcml.load_config('meta.zcml', Products.Five)
+      >>> zcml.load_string(configure_zcml)
+
+    Make sure that the class attributes are set correctly::
+
+      >>> SimpleContent.meta_type
+      'Bar Type'
+      >>> SimpleContent.icon
+      ''
+
+    And the meta_type is registered correctly::
+
+      >>> for info in Products.meta_types:
+      ...     if info['name'] == 'Bar Type':
+      ...         break
+      >>> info['product']
+      'Five'
+      >>> info['permission']
+      'Add Bar'
+      >>> ISimpleContent in info['interfaces']
+      True
+      >>> IPersistent in info['interfaces']
+      True
+      >>> info['visibility']
+      'Global'
+      >>> info['instance'] is SimpleContent
+      True
+      >>> info['action']
+      ''
+      >>> info['container_filter'] is None
+      True
+
+    Clean up:
+
+      >>> tearDown()
+      >>> SimpleContent.meta_type
+      'simple item'
+      >>> SimpleContent.icon
+      ''
+      >>> [info for info in Products.meta_types if info['name'] == 'Bar Type']
+      []
+    """
+
+def test_suite():
+    from Testing.ZopeTestCase import ZopeDocTestSuite
+    return ZopeDocTestSuite()
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_registerclass.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_security.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_security.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_security.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -45,7 +45,7 @@
     Zope 2 can be replaced by ZCML statements without any loss of
     information.
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     We start out with two classes, ``Dummy1`` and ``Dummy2``.  They
@@ -141,7 +141,7 @@
     """
     Test checkPermission
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
     Zope 3 has a function zope.security.checkPermission which provides

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_size.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_size.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_size.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -54,21 +54,21 @@
 
     Set up:
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
       >>> setUp()
 
       >>> configure_zcml = '''
       ... <configure xmlns="http://namespaces.zope.org/zope"
       ...            xmlns:five="http://namespaces.zope.org/five">
-      ...   <five:sizable class="Products.Five.testing.simplecontent.SimpleContent" />
-      ...   <five:sizable class="Products.Five.testing.fancycontent.FancyContent" />
+      ...   <five:sizable class="Products.Five.tests.testing.simplecontent.SimpleContent" />
+      ...   <five:sizable class="Products.Five.tests.testing.fancycontent.FancyContent" />
       ...   <adapter
-      ...       for="Products.Five.testing.simplecontent.ISimpleContent"
+      ...       for="Products.Five.tests.testing.simplecontent.ISimpleContent"
       ...       provides="zope.app.size.interfaces.ISized"
       ...       factory="Products.Five.tests.test_size.SimpleContentSize"
       ...       />
       ...   <adapter
-      ...       for="Products.Five.testing.fancycontent.IFancyContent"
+      ...       for="Products.Five.tests.testing.fancycontent.IFancyContent"
       ...       provides="zope.app.size.interfaces.ISized"
       ...       factory="Products.Five.tests.test_size.FancyContentSize"
       ...       />
@@ -79,8 +79,8 @@
       >>> zcml.load_config('meta.zcml', Products.Five)
       >>> zcml.load_string(configure_zcml)
 
-      >>> from Products.Five.testing.simplecontent import manage_addSimpleContent
-      >>> from Products.Five.testing.fancycontent import manage_addFancyContent
+      >>> from Products.Five.tests.testing.simplecontent import manage_addSimpleContent
+      >>> from Products.Five.tests.testing.fancycontent import manage_addFancyContent
 
     We have registered an ``ISized`` adapter for SimpleContent:
 

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_viewable.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_viewable.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/test_viewable.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -23,9 +23,6 @@
     """
     Testing default view functionality
 
-      >>> from zope.app.tests.placelesssetup import setUp, tearDown
-      >>> setUp()
-
     Take a class Foo and an interface IFoo:
 
       >>> class Foo:
@@ -37,14 +34,14 @@
 
     Set up a default view for IFoo:
 
-      >>> from zope.app import zapi
-      >>> pres = zapi.getGlobalService('Presentation')
+      >>> from zope.component import provideAdapter
+      >>> from zope.component.interfaces import IDefaultViewName
       >>> from zope.publisher.interfaces.browser import IBrowserRequest
 
     and default view names for everything and IFoo objects in particular:
 
-      >>> pres.setDefaultViewName(None, IBrowserRequest, u'index.html')
-      >>> pres.setDefaultViewName(IFoo, IBrowserRequest, u'foo.html')
+      >>> provideAdapter(u'index.html', (None, IBrowserRequest), IDefaultViewName)
+      >>> provideAdapter(u'foo.html', (IFoo, IBrowserRequest), IDefaultViewName)
 
     Now take a BrowserDefault for an instance of Foo::
 
@@ -73,10 +70,10 @@
       >>> path
       [u'foo.html']
 
+    Clean up adapter registry:
 
-    Clean up:
-
-      >>> tearDown()
+      >>> from zope.testing.cleanup import cleanUp
+      >>> cleanUp()
     """
 
 def test_suite():

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Test helpers
+
+$Id$
+"""
+from Products.Five.tests.testing.restricted import RestrictedPythonTestCase
+
+from Products.Five.tests.testing.folder import FiveTraversableFolder
+from Products.Five.tests.testing.folder import manage_addFiveTraversableFolder
+from Products.Five.tests.testing.folder import NoVerifyPasteFolder
+from Products.Five.tests.testing.folder import manage_addNoVerifyPasteFolder


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/fancycontent.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/fancycontent.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/fancycontent.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Test content objects.
+
+$Id$
+"""
+import Acquisition
+from AccessControl import ClassSecurityInfo
+from OFS.SimpleItem import SimpleItem
+from Globals import InitializeClass
+
+from zope.interface import Interface, implements
+
+class IFancyContent(Interface):
+    pass
+
+class FancyAttribute(Acquisition.Explicit):
+    """Doc test fanatics"""
+
+    def __init__(self, name):
+        self.name = name
+
+    security = ClassSecurityInfo()
+
+    security.declarePublic('index_html')
+    def index_html(self, REQUEST):
+        """Doc test fanatics"""
+        return self.name
+
+InitializeClass(FancyAttribute)
+
+class FancyContent(SimpleItem):
+    """A class that already comes with its own __bobo_traverse__ handler.
+    Quite fancy indeed.
+
+    It also comes with its own get_size method.
+    """
+    implements(IFancyContent)
+
+    meta_type = "Fancy Content"
+    security = ClassSecurityInfo()
+
+    def __bobo_traverse__(self, REQUEST, name):
+        return FancyAttribute(name).__of__(self)
+
+    def get_size(self):
+        return 43
+
+InitializeClass(FancyContent)
+
+def manage_addFancyContent(self, id, REQUEST=None):
+    """Add the fancy fancy content."""
+    id = self._setObject(id, FancyContent(id))
+    return ''


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/fancycontent.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/folder.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/folder.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/folder.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Test folders
+
+$Id$
+"""
+from OFS.Folder import Folder
+from OFS.interfaces import IFolder
+from zope.interface import implements
+from Products.Five.traversable import Traversable
+
+class NoVerifyPasteFolder(Folder):
+    """Folder that does not perform paste verification.
+    Used by test_events
+    """
+    def _verifyObjectPaste(self, object, validate_src=1):
+        pass
+
+def manage_addNoVerifyPasteFolder(container, id, title=''):
+    container._setObject(id, NoVerifyPasteFolder())
+    folder = container[id]
+    folder.id = id
+    folder.title = title
+
+class FiveTraversableFolder(Traversable, Folder):
+    """Folder that is five-traversable
+    """
+    implements(IFolder)
+
+def manage_addFiveTraversableFolder(container, id, title=''):
+    container._setObject(id, FiveTraversableFolder())
+    folder = container[id]
+    folder.id = id
+    folder.title = title


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/folder.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/restricted.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/restricted.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/restricted.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Restricted python test helpers
+
+Based on Plone's RestrictedPythonTestCase, with kind permission by the
+Plone developers.
+
+$Id$
+"""
+from AccessControl import Unauthorized
+from Testing.ZopeTestCase import ZopeTestCase
+
+def addPythonScript(folder, id, params='', body=''):
+    """Add a PythonScript to folder."""
+    # clean up any 'ps' that's already here..
+    try:
+        folder._getOb(id)
+        folder.manage_delObjects([id])
+    except AttributeError:
+        pass # it's okay, no 'ps' exists yet
+    factory = folder.manage_addProduct['PythonScripts']
+    factory.manage_addPythonScript(id)
+    folder[id].ZPythonScript_edit(params, body)
+
+def checkRestricted(folder, psbody):
+    """Perform a check by running restricted Python code."""
+    addPythonScript(folder, 'ps', body=psbody)
+    try:
+        folder.ps()
+    except Unauthorized, e:
+        raise AssertionError, e
+
+def checkUnauthorized(folder, psbody):
+    """Perform a check by running restricted Python code.  Expect to
+    encounter an Unauthorized exception."""
+    addPythonScript(folder, 'ps', body=psbody)
+    try:
+        folder.ps()
+    except Unauthorized:
+        pass
+    else:
+        raise AssertionError, "Authorized but shouldn't be"
+
+class RestrictedPythonTestCase(ZopeTestCase):
+    """Javiotic test case for restricted code."""
+
+    def addPS(self, id, params='', body=''):
+        addPythonScript(self.folder, id, params, body)
+
+    def check(self, psbody):
+        checkRestricted(self.folder, psbody)
+
+    def checkUnauthorized(self, psbody):
+        checkUnauthorized(self.folder, psbody)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/restricted.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/simplecontent.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/simplecontent.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/simplecontent.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,90 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Simple content class(es) for browser tests
+
+$Id$
+"""
+from OFS.SimpleItem import SimpleItem
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+from zope.interface import Interface, implements
+from Products.Five.traversable import Traversable
+
+class ISimpleContent(Interface):
+    pass
+
+class ICallableSimpleContent(ISimpleContent):
+    pass
+
+class IIndexSimpleContent(ISimpleContent):
+    pass
+
+class SimpleContent(Traversable, SimpleItem):
+    implements(ISimpleContent)
+
+    meta_type = 'Five SimpleContent'
+    security = ClassSecurityInfo()
+
+    def __init__(self, id, title):
+        self.id = id
+        self.title = title
+
+    security.declarePublic('mymethod')
+    def mymethod(self):
+        return "Hello world"
+
+    security.declarePublic('direct')
+    def direct(self):
+        """Should be able to traverse directly to this as there is no view.
+        """
+        return "Direct traversal worked"
+
+InitializeClass(SimpleContent)
+
+class CallableSimpleContent(SimpleItem):
+    """A Viewable piece of content"""
+    implements(ICallableSimpleContent)
+
+    meta_type = "Five CallableSimpleContent"
+
+    def __call__(self, *args, **kw):
+        """ """
+        return "Default __call__ called"
+
+InitializeClass(CallableSimpleContent)
+
+class IndexSimpleContent(SimpleItem):
+    """A Viewable piece of content"""
+    implements(IIndexSimpleContent)
+
+    meta_type = 'Five IndexSimpleContent'
+
+    def index_html(self, *args, **kw):
+        """ """
+        return "Default index_html called"
+
+InitializeClass(IndexSimpleContent)
+
+def manage_addSimpleContent(self, id, title, REQUEST=None):
+    """Add the simple content."""
+    self._setObject(id, SimpleContent(id, title))
+
+def manage_addCallableSimpleContent(self, id, title, REQUEST=None):
+    """Add the viewable simple content."""
+    self._setObject(id, CallableSimpleContent(id, title))
+
+def manage_addIndexSimpleContent(self, id, title, REQUEST=None):
+    """Add the viewable simple content."""
+    self._setObject(id, IndexSimpleContent(id, title))


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/tests/testing/simplecontent.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/traversable.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/traversable.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/traversable.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -13,28 +13,29 @@
 ##############################################################################
 """Machinery for making things traversable through adaptation
 
-$Id: traversable.py 18841 2005-10-23 09:57:38Z philikon $
+$Id: traversable.py 19283 2005-10-31 17:43:51Z philikon $
 """
 from zExceptions import NotFound
-from zope.exceptions import NotFoundError
-from zope.component import getView, ComponentLookupError
-from zope.interface import implements
+
+from zope.component import getMultiAdapter, ComponentLookupError
+from zope.interface import implements, Interface
+from zope.publisher.interfaces import ILayer
 from zope.publisher.interfaces.browser import IBrowserRequest
+
 from zope.app.traversing.interfaces import ITraverser, ITraversable
 from zope.app.traversing.adapters import DefaultTraversable
 from zope.app.traversing.adapters import traversePathElement
+from zope.app.publication.browser import setDefaultSkin
+from zope.app.interface import queryType
 
 from AccessControl import getSecurityManager
 from Products.Five.security import newInteraction
 
 _marker = object
 
-class FakeRequest:
+class FakeRequest(dict):
     implements(IBrowserRequest)
 
-    def getPresentationSkin(self):
-        return None
-
     def has_key(self, key):
         return False
 
@@ -69,16 +70,20 @@
             REQUEST = getattr(self, 'REQUEST', None)
             if not IBrowserRequest.providedBy(REQUEST):
                 REQUEST = FakeRequest()
+
+        # set the default skin on the request if it doesn't have any
+        # layers set on it yet
+        if queryType(REQUEST, ILayer) is None:
+            setDefaultSkin(REQUEST)
+
         # con Zope 3 into using Zope 2's checkPermission
         newInteraction()
-
         try:
             return ITraverser(self).traverse(
                 path=[name], request=REQUEST).__of__(self)
-        except (ComponentLookupError, NotFoundError,
+        except (ComponentLookupError, LookupError,
                 AttributeError, KeyError, NotFound):
             pass
-
         try:
             return getattr(self, name)
         except AttributeError:
@@ -100,8 +105,9 @@
         REQUEST = getattr(context, 'REQUEST', None)
         if not IBrowserRequest.providedBy(REQUEST):
             REQUEST = FakeRequest()
-        # Try to lookup a view first
+            setDefaultSkin(REQUEST)
+        # Try to lookup a view
         try:
-            return getView(context, name, REQUEST)
+            return getMultiAdapter((context, REQUEST), Interface, name)
         except ComponentLookupError:
             pass

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1 @@
+# make this directory a package


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1 @@
+# make this directory a package


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,20 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+    xmlns:browser="http://namespaces.zope.org/browser">
+
+  <browser:page
+      for="*"
+      name="edit-markers.html"
+      template="edit_markers.pt"
+      class="Products.Five.utilities.browser.marker.EditView"
+      permission="zope2.ManageProperties"
+      />
+
+  <browser:page
+      for="*"
+      name="manage_interfaces"
+      template="manage_interfaces.pt"
+      class="Products.Five.utilities.browser.marker.EditView"
+      permission="zope2.ManageProperties"
+      />
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/edit_markers.pt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/edit_markers.pt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/edit_markers.pt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,63 @@
+<html metal:use-macro="context/@@standard_macros/page">
+<body>
+
+<metal:slot metal:fill-slot="body">
+<metal:macro metal:define-macro="heading">
+<h1 i18n:translate="heading_edit_marker">Assign Marker Interfaces</h1>
+</metal:macro>
+<metal:macro metal:define-macro="main">
+<p class="form-help formHelp" i18n:translate="">Change the behavior of this
+ object by adding or removing marker interfaces. You can choose one or more
+ interfaces to be added to the list of provided interfaces for this
+ object.</p>
+
+<p class="form-help formHelp" i18n:translate="">A marker interface is used to
+ identify an instance of a piece of content. When in conjunction with Five,
+ this allows you to enable and disable views based on marker interfaces for
+ example.</p>
+
+<form action="." method="post"
+   tal:attributes="action request/ACTUAL_URL">
+
+<fieldset>
+ <legend i18n:translate="legend_provided">Provided Interfaces</legend>
+ <tal:loop tal:repeat="interface view/getInterfaceNames">
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <label class="form-mono"
+    tal:content="interface/name" i18n:translate="">INTERFACE</label><br />
+ </tal:loop>
+ <tal:loop tal:repeat="interface view/getDirectlyProvidedNames">
+ <input type="checkbox" id="INTERFACE" name="remove:list"
+    tal:attributes="id interface/name; value interface/name" />
+ <label class="form-mono" for="INTERFACE" tal:attributes="for interface/name"
+    tal:content="interface/name" i18n:translate="">INTERFACE</label><br />
+ </tal:loop>
+ <tal:case tal:condition="view/getDirectlyProvidedNames">
+ <div class="formControls FormButtons">
+  <input class="form-element" type="submit" name="SAVE" value="Remove"
+     i18n:attributes="value" />
+ </div>
+ </tal:case>
+</fieldset>
+
+<fieldset>
+ <legend i18n:translate="legend_available_marker">Available Marker
+  Interfaces</legend>
+ <tal:loop tal:repeat="interface view/getAvailableInterfaceNames">
+ <input type="checkbox" id="INTERFACE" name="add:list"
+    tal:attributes="id interface/name; value interface/name" />
+ <label class="form-mono" for="INTERFACE" tal:attributes="for interface/name"
+    tal:content="interface/name" i18n:translate="">INTERFACE</label><br />
+ </tal:loop>
+ <div class="formControls FormButtons">
+  <input class="form-element" type="submit" name="SAVE" value="Add"
+     i18n:attributes="value" />
+ </div>
+</fieldset>
+
+</form>
+</metal:macro>
+</metal:slot>
+
+</body>
+</html>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/edit_markers.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/manage_interfaces.pt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/manage_interfaces.pt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/manage_interfaces.pt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,7 @@
+<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
+<h2 tal:replace="structure context/manage_tabs">TABS</h2>
+<style type="text/css">
+ fieldset {width:auto; float:left}
+</style>
+<metal:macro metal:use-macro="context/@@edit-markers.html/main" />
+<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/manage_interfaces.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/marker.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/marker.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/marker.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Marker interfaces adapter views.
+
+$Id$
+"""
+from Products.Five.utilities.interfaces import IMarkerInterfaces
+
+
+class EditView:
+
+    """Marker interface edit view.
+    """
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+        self.adapted = IMarkerInterfaces(context)
+        self.context_url = self.context.absolute_url()
+
+    def __call__(self, SAVE=None, add=(), remove=()):
+        if SAVE:
+            self.update(add, remove)
+            self.request.response.redirect(self.request.ACTUAL_URL)
+            return ''
+        return self.index()
+
+    def _getLinkToInterfaceDetailsView(self, interfaceName):
+        return (self.context_url +
+            '/views-details.html?iface=%s&type=zope.publisher.interfaces.browser.IBrowserRequest' % interfaceName)
+
+    def _getNameLinkDicts(self, interfaceNames):
+        return [dict(name=name,
+                     link=self._getLinkToInterfaceDetailsView(name))
+                for name in interfaceNames]
+
+    def getAvailableInterfaceNames(self):
+        return self._getNameLinkDicts(
+            self.adapted.getAvailableInterfaceNames())
+
+    def getDirectlyProvidedNames(self):
+        return self._getNameLinkDicts(self.adapted.getDirectlyProvidedNames())
+
+    def getInterfaceNames(self):
+        return self._getNameLinkDicts(self.adapted.getInterfaceNames())
+
+    def update(self, add, remove):
+        # this could return errors
+        add = self.adapted.dottedToInterfaces(add)
+        remove = self.adapted.dottedToInterfaces(remove)
+        self.adapted.update(add=add, remove=remove)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/marker.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/__init__.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/__init__.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/__init__.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1 @@
+# make this directory a package


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/__init__.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/framework.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/framework.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/framework.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# ZopeTestCase 
+#
+# COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+#
+# This version of framework.py will use the SOFTWARE_HOME
+# environment variable to locate Zope and the Testing package.
+#
+# If the tests are run in an INSTANCE_HOME installation of Zope,
+# Products.__path__ and sys.path with be adjusted to include the
+# instance's Products and lib/python directories respectively.
+#
+# If you explicitly set INSTANCE_HOME prior to running the tests,
+# auto-detection is disabled and the specified path will be used 
+# instead.
+#
+# If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+# will be adjusted to use it.
+#
+# If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup 
+# is assumed, and you can attach to a running ZEO server (via the 
+# instance's custom_zodb.py).
+#
+##############################################################################
+#
+# The following code should be at the top of every test module:
+#
+# import os, sys
+# if __name__ == '__main__':
+#     execfile(os.path.join(sys.path[0], 'framework.py'))
+#
+# ...and the following at the bottom:
+#
+# if __name__ == '__main__':
+#     framework()
+#
+##############################################################################
+
+__version__ = '0.2.3'
+
+# Save start state
+#
+__SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')
+__INSTANCE_HOME = os.environ.get('INSTANCE_HOME', '')
+
+if __SOFTWARE_HOME.endswith(os.sep):
+    __SOFTWARE_HOME = os.path.dirname(__SOFTWARE_HOME)
+
+if __INSTANCE_HOME.endswith(os.sep):
+    __INSTANCE_HOME = os.path.dirname(__INSTANCE_HOME)
+
+# Find and import the Testing package
+#
+if not sys.modules.has_key('Testing'):
+    p0 = sys.path[0]
+    if p0 and __name__ == '__main__':
+        os.chdir(p0)
+        p0 = ''
+    s = __SOFTWARE_HOME
+    p = d = s and s or os.getcwd()
+    while d:
+        if os.path.isdir(os.path.join(p, 'Testing')):
+            zope_home = os.path.dirname(os.path.dirname(p))
+            sys.path[:1] = [p0, p, zope_home]
+            break
+        p, d = s and ('','') or os.path.split(p)
+    else:
+        print 'Unable to locate Testing package.',
+        print 'You might need to set SOFTWARE_HOME.'
+        sys.exit(1)
+
+import Testing, unittest
+execfile(os.path.join(os.path.dirname(Testing.__file__), 'common.py'))
+
+# Include ZopeTestCase support
+#
+if 1:   # Create a new scope
+
+    p = os.path.join(os.path.dirname(Testing.__file__), 'ZopeTestCase')
+
+    if not os.path.isdir(p):
+        print 'Unable to locate ZopeTestCase package.',
+        print 'You might need to install ZopeTestCase.'
+        sys.exit(1)
+
+    ztc_common = 'ztc_common.py'
+    ztc_common_global = os.path.join(p, ztc_common)
+
+    f = 0
+    if os.path.exists(ztc_common_global):
+        execfile(ztc_common_global)
+        f = 1
+    if os.path.exists(ztc_common):
+        execfile(ztc_common)
+        f = 1
+
+    if not f:
+        print 'Unable to locate %s.' % ztc_common
+        sys.exit(1)
+
+# Debug
+#
+print 'SOFTWARE_HOME: %s' % os.environ.get('SOFTWARE_HOME', 'Not set')
+print 'INSTANCE_HOME: %s' % os.environ.get('INSTANCE_HOME', 'Not set')
+sys.stdout.flush()
+


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/framework.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/test_marker.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/test_marker.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/test_marker.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,96 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Unit tests for marker interface views.
+
+$Id$
+"""
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+def test_editview():
+    """
+    Set everything up:
+
+      >>> from zope.app.testing.placelesssetup import setUp, tearDown
+      >>> setUp()
+      >>> import Products.Five
+      >>> import Products.Five.utilities
+      >>> from Products.Five import zcml
+      >>> zcml.load_config('meta.zcml', Products.Five)
+      >>> zcml.load_config('permissions.zcml', Products.Five)
+      >>> zcml.load_config('configure.zcml', Products.Five.utilities)
+      >>> from Products.Five.utilities.browser.marker import EditView
+      >>> from Products.Five.tests.testing.simplecontent import SimpleContent
+      >>> obj = SimpleContent('foo', 'Foo').__of__(self.folder)
+
+    Create an EditView:
+
+      >>> view = EditView(obj, {})
+      >>> view.context.aq_inner is obj
+      True
+      >>> view.request
+      {}
+      >>> view.getAvailableInterfaceNames()
+      []
+      >>> view.getDirectlyProvidedNames()
+      []
+      >>> view.getInterfaceNames()
+      [...ISimpleContent...]
+
+    Try to add a marker interface that doesn't exist:
+
+      >>> view.update(('__builtin__.IFooMarker',), ())
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError...
+
+    Now create the marker interface:
+
+      >>> from Products.Five.tests.testing.simplecontent import ISimpleContent
+      >>> class IFooMarker(ISimpleContent): pass
+      >>> from zope.app.component.interface import provideInterface
+      >>> provideInterface('', IFooMarker)
+      >>> view.getAvailableInterfaceNames()
+      [...IFooMarker...]
+      >>> view.getDirectlyProvidedNames()
+      []
+
+    And try again to add it to the object:
+
+      >>> view.update(('__builtin__.IFooMarker',), ())
+      >>> view.getAvailableInterfaceNames()
+      []
+      >>> view.getDirectlyProvidedNames()
+      [...IFooMarker...]
+
+    And remove it again:
+
+      >>> view.update((), ('__builtin__.IFooMarker',))
+      >>> view.getAvailableInterfaceNames()
+      [...IFooMarker...]
+      >>> view.getDirectlyProvidedNames()
+      []
+
+    Finally tear down:
+
+      >>> tearDown()
+    """
+
+def test_suite():
+    from Testing.ZopeTestCase import ZopeDocTestSuite
+    return ZopeDocTestSuite()
+
+if __name__ == '__main__':
+    framework()


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/browser/tests/test_marker.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/configure.zcml
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/configure.zcml	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/configure.zcml	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,12 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package=".browser"/>
+
+  <adapter
+      for="*"
+      provides=".interfaces.IMarkerInterfaces"
+      factory=".marker.MarkerInterfacesAdapter"
+      permission="zope2.ManageProperties"
+      />
+
+</configure>


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/interfaces.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/interfaces.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/interfaces.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Utility Interface Definitions.
+
+$Id$
+"""
+from zope.interface import Interface
+
+
+class IReadInterface(Interface):
+
+    def getDirectlyProvided():
+        """List the interfaces directly implemented by the object.
+        """
+
+    def getDirectlyProvidedNames():
+        """List the names of interfaces directly implemented by the object.
+        """
+
+    def getAvailableInterfaces():
+        """List the marker interfaces available for the object.
+        """
+
+    def getAvailableInterfaceNames():
+        """List the names of marker interfaces available for the object.
+        """
+
+    def getInterfaces():
+        """List interfaces provided by the class of the object.
+        """
+
+    def getInterfaceNames():
+        """List the names of interfaces provided by the class of the object.
+        """
+
+    def getProvided():
+        """List interfaces provided by the object.
+        """
+
+    def getDirectlyProvidedNames():
+        """List the names of interfaces provided by the object.
+        """
+
+
+class IWriteInterface(Interface):
+
+    def update(add=(), remove=()):
+        """Update directly provided interfaces of the object.
+        """
+
+    def mark(interface):
+        """Add interface to interfaces the object directly provides.
+        """
+
+    def erase(interface):
+        """Remove interfaces from interfaces the object directly provides.
+        """
+
+
+class IMarkerInterfaces(IReadInterface, IWriteInterface):
+
+    """Provides methods for inspecting and assigning marker interfaces.
+    """


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/interfaces.py
___________________________________________________________________
Name: svn:eol-style
   + native

Added: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/marker.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/marker.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/marker.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -0,0 +1,133 @@
+##############################################################################
+#
+# Copyright (c) 2004, 2005 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.
+#
+##############################################################################
+"""Marker interfaces adapter.
+
+Allows for arbitrary application of marker interfaces to objects.
+
+$Id$
+"""
+from sets import Set
+
+from zope.interface import implements
+from zope.interface import implementedBy
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
+from zope.interface import providedBy
+from zope.interface.interfaces import IInterface
+from zope.app.component.interface import getInterface, interfaceToName
+from zope.app.component.interface import searchInterface
+
+from interfaces import IMarkerInterfaces
+
+def interfaceStringCheck(f):
+    def wrapper(ob, interface):
+        if isinstance(interface, str):
+            interface = getInterface(ob, interface)
+        return f(ob, interface)
+    return wrapper
+
+def mark(ob, interface):
+    directlyProvides(ob, directlyProvidedBy(ob), interface)
+
+def erase(ob, interface):
+    directlyProvides(ob, directlyProvidedBy(ob)-interface)
+
+mark = interfaceStringCheck(mark)
+erase = interfaceStringCheck(erase)
+
+
+class MarkerInterfacesAdapter(object):
+
+    implements(IMarkerInterfaces)
+
+    mark = staticmethod(mark)
+    erase = staticmethod(erase)
+
+    def __init__(self, context):
+        self.context = context
+
+    def dottedToInterfaces(self, seq):
+        return [getInterface(self.context, dotted) for dotted in seq]
+
+    def getDirectlyProvided(self):
+        return directlyProvidedBy(self.context)
+
+    def getDirectlyProvidedNames(self):
+        return self._getInterfaceNames(self.getDirectlyProvided())
+
+    def getAvailableInterfaces(self):
+        results = []
+        todo = list(providedBy(self.context))
+        done = []
+        while todo:
+            interface = todo.pop()
+            done.append(interface)
+            for base in interface.__bases__:
+                if base not in todo and base not in done:
+                    todo.append(base)
+            markers = self._getDirectMarkersOf(interface)
+            for interface in markers:
+                if (interface not in results
+                    and not interface.providedBy(self.context)):
+                    results.append(interface)
+            todo += markers
+        return tuple(results)
+
+    def getAvailableInterfaceNames(self):
+        names = self._getInterfaceNames(self.getAvailableInterfaces())
+        names.sort()
+        return names
+
+    def getInterfaces(self):
+        return tuple(implementedBy(self.context.__class__))
+
+    def getInterfaceNames(self):
+        return self._getInterfaceNames(self.getInterfaces())
+
+    def getProvided(self):
+        return providedBy(self.context)
+
+    def getProvidedNames(self):
+        return self._getInterfaceNames(self.getProvided())
+
+    def update(self, add=(), remove=()):
+        """Currently update adds and then removes, rendering duplicate null.
+        """
+        marker_ifaces = self.getAvailableInterfaces()
+        if len(add):
+            [mark(self.context, interface)
+             for interface in Set(marker_ifaces) & Set(add)]
+
+        direct_ifaces = self.getDirectlyProvided()
+        if len(remove):
+            [erase(self.context, interface)
+             for interface in Set(direct_ifaces) & Set(remove)]
+
+    def _getInterfaceNames(self, interfaces):
+        return [interfaceToName(self, iface) for iface in interfaces]
+
+    def _getDirectMarkersOf(self, base):
+        """Get empty interfaces directly inheriting from the given one.
+        """
+        results = []
+        interfaces = searchInterface(None, base=base)
+        for interface in interfaces:
+            # There are things registered with the interface service
+            # that are not interfaces. Yay!
+            if not IInterface.providedBy(interface):
+                continue
+            if base in interface.__bases__ and not interface.names():
+                results.append(interface)
+        results.sort()
+        return tuple(results)


Property changes on: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/utilities/marker.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/version.txt
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/version.txt	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/version.txt	2005-11-02 17:17:42 UTC (rev 39847)
@@ -1 +1 @@
-Five 1.1
+Five 1.3b

Modified: Zope/branches/philikon-zope32-integration/lib/python/Products/Five/viewable.py
===================================================================
--- Zope/branches/philikon-zope32-integration/lib/python/Products/Five/viewable.py	2005-11-02 14:51:27 UTC (rev 39846)
+++ Zope/branches/philikon-zope32-integration/lib/python/Products/Five/viewable.py	2005-11-02 17:17:42 UTC (rev 39847)
@@ -17,10 +17,10 @@
 """
 import inspect
 from zExceptions import NotFound
-from zope.exceptions import NotFoundError
-from zope.component import getView, getDefaultViewName, ComponentLookupError
+from zope.component import ComponentLookupError
 from zope.interface import implements
 from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.app.zapi import getDefaultViewName
 
 from Products.Five.traversable import FakeRequest
 from Products.Five.interfaces import IBrowserDefault



More information about the Zope-Checkins mailing list