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

Jim Fulton cvs-admin at zope.org
Wed Nov 12 15:08:14 EST 2003


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

Added Files:
      Tag: adaptergeddon-branch
	surrogate.py 
Log Message:
Added local surrogates, to be used for local adapter and presentation
services.


=== Added File Zope3/src/zope/app/services/surrogate.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.
#
##############################################################################
"""Local/persistent surrogate (adapter) registry support

$Id: surrogate.py,v 1.1.2.1 2003/11/12 20:08:12 jim Exp $
"""

from persistence import Persistent
from persistence.dict import PersistentDict
from zope.interface.surrogate import Surrogate, SurrogateRegistry
from zope.interface.surrogate import adapterImplied
from zope.app.services.registration import NotifyingRegistrationStack

class LocalSurrogate(Surrogate):
    """Local surrogates

    Local surrogates are transient, rather than persistent.

    Their adapter data are stored in their registry objects.
    """

    def __init__(self, spec, registry):
        Surrogate.__init__(self, spec, registry)
        self.registry = registry
        registry.baseFor(spec).subscribe(self)

    def clean(self):
        spec = self.spec()
        base = self.registry.baseFor(spec)
        ladapters = self.registry.adapters.get(spec)
        if ladapters:
            adapters = base.adapters.copy()
            adapters.update(ladapters)
        else:
            adapters = base.adapters
        self.adapters = adapters
        Surrogate.clean(self)

class LocalSurrogateRegistry(SurrogateRegistry, Persistent):
    """Local/persistent surrogate registry
    """

    _surrogateClass = LocalSurrogate
    next = None
    subs = ()

    def __init__(self, base, next=None):
        self.base = base
        self.adapters = {}
        self.stacks = PersistentDict()
        SurrogateRegistry.__init__(self)
        self.setNext(next)

    def setNext(self, next):
        if self.next is not None:
            self.next.removeSub(self)
        if next is not None:
            next.addSub(self)
        self.next = next
        self.adaptersChanged()

    def addSub(self, sub):
        self.subs += (sub, )

    def removeSub(self, sub):
        self.subs = tuple([s for s in self.subs if s is not sub])

    def __getstate__(self):
        return 'state1', (self.base, self.next, self.subs, self.adapters,
                          self.stacks)

    def state1(self, data):
        self.base, self.next, self.subs, self.adapters, self.stacks = data
        
    def __setstate__(self, state):
        getattr(self, state[0])(state[1])
        SurrogateRegistry.__init__(self)
    
    def baseFor(self, spec):
        return self.base.get(spec)

    def queryRegistrationsFor(self, registration, default=None):
        stacks = self.stacks.get(registration.required)
        if stacks:
            stack = stacks.get((registration.with, registration.name,
                                registration.provided))
            if stack is not None:
                return stack

        return default

    _stackType = NotifyingRegistrationStack

    def createRegistrationsFor(self, registration):
        stacks = self.stacks.get(registration.required)
        if stacks is None:
            stacks = PersistentDict()
            self.stacks[registration.required] = stacks

        key = registration.with, registration.name, registration.provided
        stack = stacks.get(key)
        if stack is None:
            stack = self._stackType(self)
            stacks[key] = stack

        return stack

    def adaptersChanged(self, *args):

        if self.next is not None:
            adapters = self.next.adapters.copy()
        else:
            adapters = {}

        for required, stacks in self.stacks.iteritems():
            radapters = adapters.get(required)
            if not radapters:
                radapters = {}
                adapters[required] = radapters

            for key, stack in stacks.iteritems():
                registration = stack.active()
                if registration is not None:
                    radapters[key] = [registration]


        if adapters != self.adapters:
            self.adapters = adapters
            for surrogate in self._surrogates.values():
                surrogate.dirty()
            for sub in self.subs:
                sub.adaptersChanged()

    notifyActivated = notifyDeactivated = adaptersChanged




More information about the Zope3-Checkins mailing list