[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/OFS/Services - view.py:1.1.2.1 interfaces.py:1.1.2.3

Jim Fulton jim@zope.com
Wed, 11 Dec 2002 09:10:25 -0500


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

Modified Files:
      Tag: AdapterAndView-branch
	interfaces.py 
Added Files:
      Tag: AdapterAndView-branch
	view.py 
Log Message:
Added initial Python code for a local view service and configuration.


=== Added File Zope3/lib/python/Zope/App/OFS/Services/view.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
# 
##############################################################################
"""View Service


$Id: view.py,v 1.1.2.1 2002/12/11 14:10:24 jim Exp $
"""
__metaclass__ = type

from Interface.Registry.AdapterRegistry import AdapterRegistry
from Persistence import Persistent
from Persistence.PersistentDict import PersistentDict
from Zope.ComponentArchitecture.IViewService import IViewService
from Zope.ComponentArchitecture.Exceptions import ComponentLookupError
from Zope.ComponentArchitecture import getServiceManager
from Zope.App.OFS.Services.ConfigurationInterfaces import IConfigurable
from Zope.App.OFS.Services.Configuration import ConfigurationRegistry
from Zope.App.OFS.Services.Configuration import SimpleConfiguration
from Zope.Proxy.ContextWrapper import ContextWrapper
from Zope.ContextWrapper import ContextMethod
from Zope.App.OFS.Services.Configuration import ConfigurationStatusProperty
from Zope.App.ComponentArchitecture.NextService import getNextService
from Zope.ComponentArchitecture import getSkin

from interfaces import IViewConfiguration
from adapter import PersistentAdapterRegistry


class ViewService(Persistent):

    __implements__ = IViewService, IConfigurable

    def __init__(self):
        self._layers = PersistentDict()

    def queryConfigurationsFor(self, configuration, default=None):
        "See Zope.App.OFS.Services.ConfigurationInterfaces.IConfigurable"
        return self.queryConfigurations(
            configuration.viewName, configuration.layer,
            configuration.forInterface, configuration.presentationType,
            default)

    queryConfigurationsFor = ContextMethod(queryConfigurationsFor)

    def queryConfigurations(self, name, layer, 
                            forInterface, presentationType, default=None):

        names = self._layers.get(layer)
        if names is None:
            return default

        adapter_registry = names.get(name)
        if adapter_registry is None:
            return default

        registry = adapter_registry.getRegistered(
            forInterface, presentationType)

        if registry is None:
            return default

        return ContextWrapper(registry, self)

    queryConfigurations = ContextMethod(queryConfigurations)
    
    def createConfigurationsFor(self, configuration):
        "See Zope.App.OFS.Services.ConfigurationInterfaces.IConfigurable"
        return self.createConfigurations(
            configuration.viewName, configuration.layer,            
            configuration.forInterface, configuration.presentationType)

    createConfigurationsFor = ContextMethod(createConfigurationsFor)

    def createConfigurations(self,
                             viewName, layer, forInterface, presentationType):

        names = self._layers.get(layer)
        if names is None:
            names = PersistentDict()
            self._layers[layer] = names

        adapter_registry = names.get(viewName)
        if adapter_registry is None:
            adapter_registry = PersistentAdapterRegistry()
            names[viewName] = adapter_registry

        registry = adapter_registry.getRegistered(
            forInterface, presentationType)

        if registry is None:
            registry = ConfigurationRegistry()
            adapter_registry.register(forInterface, presentationType, registry)

        return ContextWrapper(registry, self)

    createConfigurations = ContextMethod(createConfigurations)

    def getView(self, object, name, request):
        view = self.queryView(object, name, request)
        if view is None:
            raise ComponentLookupError(object, name)
        return view

    getView = ContextMethod(getView)

    def queryView(self, object, name, request, default=None):

        type = request.getPresentationType()
        skin = request.getPresentationSkin()

        for layername in getSkin(object, skin, type):
            layer = self._layers.get(layername)
            if not layer:
                continue

            reg = layer.get(name, None)
            if reg is None:
                continue

            registry = reg.getForObject(
                object, type,
                filter = lambda registry:
                         ContextWrapper(registry, self).active(),
                )

            if registry is None:
                continue

            registry = ContextWrapper(registry, self)
            view = registry.active().getView(object, request)
            return view

        views = getNextService(self, 'Views') 

        return views.queryView(object, name, request, default)

    queryView = ContextMethod(queryView)

    def getRegisteredMatching(self,
                              required_interfaces=None,
                              presentation_type=None,
                              viewName=None,
                              layer=None,
                              ):
        if layer is None:
            layers = self._layers.keys()
        else:
            layers = (layer, )

        result = []
        
        for layer in layers:
            names_dict = self._layers.get(layer)
            if names_dict is None:
                continue

            if viewName is None:
                viewNames = names_dict.keys()
            else:
                viewNames = (viewName, )

            for viewName in viewNames:
                registry = names_dict.get(viewName)

                if registry is None:
                    continue

                for match in registry.getRegisteredMatching(
                    required_interfaces,
                    presentation_type):
                    
                    result.append(match + (layer, viewName))
            
        return result

class ViewConfiguration(SimpleConfiguration):

    __implements__ = IViewConfiguration

    status = ConfigurationStatusProperty('Views')

    def __init__(self,
                 forInterface, viewName, presentationType,
                 factoryName, layer='default'):
        self.forInterface = forInterface
        self.presentationType = presentationType
        self.factoryName = factoryName
        self.viewName = viewName
        self.layer = layer

    def getView(self, object, request):
        sm = getServiceManager(self)
        factory = sm.resolve(self.factoryName)        
        return factory(object, request)

    getView = ContextMethod(getView)
    


=== Zope3/lib/python/Zope/App/OFS/Services/interfaces.py 1.1.2.2 => 1.1.2.3 ===
--- Zope3/lib/python/Zope/App/OFS/Services/interfaces.py:1.1.2.2	Wed Dec 11 06:41:08 2002
+++ Zope3/lib/python/Zope/App/OFS/Services/interfaces.py	Wed Dec 11 09:10:24 2002
@@ -18,7 +18,7 @@
 
 from ConfigurationInterfaces import IConfiguration
 from Zope.App.ComponentArchitecture.InterfaceField import InterfaceField
-from Zope.Schema import BytesLine
+from Zope.Schema import BytesLine, TextLine
 from Interface import Interface
 
 class IAdapterConfigurationInfo(Interface):
@@ -51,4 +51,50 @@
         The adapter is computed by passing the object to the
         registered factory.
         """
+
+class IViewConfigurationInfo(Interface):
+
+    forInterface = InterfaceField(
+        title = u"For interface",
+        description = u"The interface of the objects being viewed",
+        readonly = True,
+        required = True,
+        )
+
+    presentationType = InterfaceField(
+        title = u"Presentation type",
+        description = u"The presentation type of a view",
+        readonly = True,
+        required = True,
+        )
+
+    factoryName = BytesLine(
+        title=u"The dotted name of a factory for creating the adapter",
+        readonly = True,
+        required = True,
+        )
+
+    viewName = TextLine(
+        title = u"View name",
+        readonly = True,
+        required = True,
+        )
+
+    layer = BytesLine(
+        title = u"Layer",
+        description = u"The skin layer the view is registered for",
+        required = False,
+        readonly = True,
+        default = "default",
+        )
+
+class IViewConfiguration(IConfiguration, IViewConfigurationInfo):
+
+    def getView(object, request):
+        """Return an adapter for the object
+
+        The adapter is computed by passing the object to the
+        registered factory.
+        """
+