[Zope3-checkins] CVS: Zope3/src/zope/app - configuration.py:1.1.2.1

Jim Fulton jim at zope.com
Mon Aug 4 12:34:18 EDT 2003


Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv26023/src/zope/app

Added Files:
      Tag: zcml-interface-field-branch
	configuration.py 
Log Message:
Provide an application-server specific configuration context that
provides access to services.

Provided an interface field that handles already-registered interfaces
as well as resolveable interfaces, which it registers.


=== Added File Zope3/src/zope/app/configuration.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Application-server-specific extensions to the configuration facility

$Id: configuration.py,v 1.1.2.1 2003/08/04 15:34:13 jim Exp $
"""

import zope.schema
import zope.interface
import zope.component.interfaces
from zope.app.component.service import globalServiceManager
from zope.configuration import fields, config
from zope.interface.interface import InterfaceClass
from zope.app.services.servicenames import Interfaces

class ConfigurationMachine(config.ConfigurationMachine):
    """Make services available to configuration directives

    Eventually, this could make it possible to avoid storing each
    global registry as a module global. (There would still be a global
    registrty of sites.

    """

    zope.interface.implements(zope.component.interfaces.IServiceService)

    def __init__(self, service_manager):
        config.ConfigurationMachine.__init__(self)
        self.__service_manager = service_manager

    def getServiceDefinitions(self):
        return self.__service_manager.getServiceDefinitions()

    def getInterfaceFor(self, name):
        return self.__service_manager.getInterfaceFor(name)

    def getService(self, name):
        return self.__service_manager.getService(name)

    def queryService(self, name, default=None):
        return self.__service_manager.queryService(name, default=None)


class InterfaceField(fields.GlobalObject):
    """Handle interfaces as paramters in configurations

    If a configuration directive expects an interface, fetch the
    interface from the interface service.  If the interface hasn't
    been registered and can be resolved, then then resolve and
    register it.

    Let's look at some examples. First, we need to set some things up:

    >>> sm = globalServiceManager(Interfaces)
    >>> context = ConfigurationMachine(sm)
    >>> interfaceService = sm.getService(Interfaces)
    >>> class I1(zope.interface.Interface):
    ...     pass
    >>> interfaceService.provideInterface(u"xxx.yyy", I1)

    Now we'll create and bind the field:
    
    >>> field = InterfaceField().bind(context)

    If an interface is already registered, we don't resolve or
    register it:

    >>> field.fromUnicode(u"xxx.yyy") is I1
    1
    >>> context.actions
    []

    But, if we reference an interface that hasn't been registered,
    we'll resolve it's dotted name and create an action to register it:
    
    >>> i = field.fromUnicode(u"zope.component.interfaces.IServiceService")
    >>> i is zope.component.interfaces.IServiceService
    1
    >>> len(context.actions)
    1
    >>> action = context.actions[0]
    >>> action[0]
    >>> action[1].__name__
    'provideInterface'
    >>> action[2] == ('', i)
    1

    Note that if we resolve something that isn't an interface, we'll
    get an error:

    >>> i = field.fromUnicode(u"zope.component.interfaces")
    Traceback (most recent call last):
    ...
    TypeError: not an interface
    
    
    """

    def _validate(self, value):
        super(InterfaceField, self)._validate(value)
        if not isinstance(value, InterfaceClass):
            raise TypeError, "not an interface"

    def fromUnicode(self, id):
        context = self.context
        interfaceService = context.getService(Interfaces)
        interface = interfaceService.queryInterface(id, None)
        if interface is not None:
            return interface

        interface = fields.GlobalObject.fromUnicode(self, id)

        # Register the interface
        self.context.action(
            discriminator = None,
            callable = interfaceService.provideInterface,
            args = ('', interface)
            ),

        return interface
        




More information about the Zope3-Checkins mailing list