[Zope3-checkins] CVS: Zope3/src/zope/app/principalannotation -
__init__.py:1.1 configure.zcml:1.1 interfaces.py:1.1 tests.py:1.1
Stephan Richter
srichter at cosmos.phy.tufts.edu
Sat Mar 13 13:44:51 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/principalannotation
In directory cvs.zope.org:/tmp/cvs-serv3976/src/zope/app/principalannotation
Added Files:
__init__.py configure.zcml interfaces.py tests.py
Log Message:
Moved principal annotation service to zope.app.principalannotation.
=== Added File Zope3/src/zope/app/principalannotation/__init__.py ===
##############################################################################
#
# Copyright (c) 2001, 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.
#
##############################################################################
"""Implementation of IPrincipalAnnotationService.
$Id: __init__.py,v 1.1 2004/03/13 18:44:48 srichter Exp $
"""
# TODO: register service as adapter for IAnnotations on service activation
# this depends on existence of LocalAdapterService, so once that's done
# implement this.
# Zope3 imports
from persistent import Persistent
from persistent.dict import PersistentDict
from BTrees.OOBTree import OOBTree
from zope.app.component.nextservice import queryNextService
from zope.app.interfaces.annotation import IAnnotations
from zope.interface import implements
# Sibling imports
from zope.app.principalannotation.interfaces import IPrincipalAnnotationService
from zope.app.site.interfaces import ISimpleService
from zope.app.container.contained import Contained
from zope.app.location import Location
class PrincipalAnnotationService(Persistent, Contained):
"""Stores IAnnotations for IPrinicipals.
The service ID is 'PrincipalAnnotation'.
"""
implements(IPrincipalAnnotationService, ISimpleService)
def __init__(self):
self.annotations = OOBTree()
def getAnnotations(self, principal):
"""Return object implementing IAnnotations for the given principal.
If there is no IAnnotations it will be created and then returned.
"""
return self.getAnnotationsById(principal.id)
def getAnnotationsById(self, principalId):
"""Return object implementing IAnnotations for the given principal.
If there is no IAnnotations it will be created and then returned.
"""
annotations = self.annotations.get(principalId)
if annotations is None:
annotations = Annotations(principalId, store=self.annotations)
annotations.__parent__ = self
annotations.__name__ = principalId
return annotations
def hasAnnotations(self, principal):
"""Return boolean indicating if given principal has IAnnotations."""
return principal.id in self.annotations
class Annotations(Persistent, Location):
"""Stores annotations."""
implements(IAnnotations)
def __init__(self, principalId, store=None):
self.principalId = principalId
self.data = PersistentDict() # We don't really expect that many
# _v_store is used to remember a mapping object that we should
# be saved in if we ever change
self._v_store = store
def __getitem__(wrapped_self, key):
try:
return wrapped_self.data[key]
except KeyError:
# We failed locally: delegate to a higher-level service.
service = queryNextService(wrapped_self, 'PrincipalAnnotation')
if service is not None:
annotations = service.getAnnotationsById(
wrapped_self.principalId)
return annotations[key]
raise
def __setitem__(self, key, value):
if getattr(self, '_v_store', None) is not None:
# _v_store is used to remember a mapping object that we should
# be saved in if we ever change
self._v_store[self.principalId] = self
del self._v_store
self.data[key] = value
def __delitem__(self, key):
del self.data[key]
def get(self, key, default=None):
return self.data.get(key, default)
class AnnotationsForPrincipal(object):
"""Adapter from IPrincipal to IAnnotations for a PrincipalAnnotationService.
Register an *instance* of this class as an adapter.
"""
def __init__(self, service):
self.service = service
def __call__(self, principal):
return self.service.getAnnotationsById(principal.id)
=== Added File Zope3/src/zope/app/principalannotation/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
>
<!-- For backward compatibility -->
<modulealias
module="."
alias="zope.app.services.principalannotation"
/>
<modulealias
module=".interfaces"
alias="zope.app.interfaces.services.principalannotation"
/>
<serviceType
id="PrincipalAnnotation"
interface=".interfaces.IPrincipalAnnotationService" />
<content class=".PrincipalAnnotationService">
<factory
id="IPrincipalAnnotationService"
/>
<require
permission="zope.Public"
interface=".interfaces.IPrincipalAnnotationService"
/>
</content>
<!-- Principal annotations (user data) service -->
<browser:addMenuItem
class=".PrincipalAnnotationService"
permission="zope.ManageServices"
title="Principal Annotation Service"
description="Stores Annotations for Principals" />
</configure>
=== Added File Zope3/src/zope/app/principalannotation/interfaces.py ===
##############################################################################
#
# Copyright (c) 2001, 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.
#
##############################################################################
"""Service for storing IAnnotations for principals.
$Id: interfaces.py,v 1.1 2004/03/13 18:44:48 srichter Exp $
"""
from zope.interface import Interface
class IPrincipalAnnotationService(Interface):
"""Stores IAnnotations for IPrinicipals."""
def getAnnotations(principal):
"""Return object implementing IAnnotations for the given IPrinicipal.
If there is no IAnnotations it will be created and then returned.
"""
def getAnnotationsById(principalId):
"""Return object implementing IAnnotations for the given prinicipal id.
If there is no IAnnotations it will be created and then returned.
"""
def hasAnnotations(principal):
"""Return boolean indicating if given IPrincipal has IAnnotations."""
=== Added File Zope3/src/zope/app/principalannotation/tests.py ===
##############################################################################
#
# Copyright (c) 2001, 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.
#
##############################################################################
"""Principal Annotation Tests
$Id: tests.py,v 1.1 2004/03/13 18:44:48 srichter Exp $
"""
from unittest import TestCase, TestLoader, TextTestRunner
from zope.app.site.tests.placefulsetup import PlacefulSetup
from zope.component import getServiceManager
from zope.app.principalannotation import \
PrincipalAnnotationService, AnnotationsForPrincipal
from interfaces import IPrincipalAnnotationService
from zope.app.tests import ztapi
from zope.app.interfaces.annotation import IAnnotations
from zope.app.security.interfaces import IPrincipal
from zope.app.tests import setup
from zope.interface import implements
class Principal:
implements(IPrincipal)
def __init__(self, id):
self.id = id
class PrincipalAnnotationTests(PlacefulSetup, TestCase):
def setUp(self):
PlacefulSetup.setUp(self)
sm = self.buildFolders(site='/')
root_sm = getServiceManager(None)
svc = PrincipalAnnotationService()
root_sm.defineService("PrincipalAnnotation",
IPrincipalAnnotationService)
root_sm.provideService("PrincipalAnnotation", svc)
self.svc = setup.addService(sm, 'PrincipalAnnotation', svc)
def testGetSimple(self):
prince = Principal('somebody')
self.assert_(not self.svc.hasAnnotations(prince))
princeAnnotation = self.svc.getAnnotations(prince)
# Just getting doesn't actualy store. We don't want to store unless
# we make a change.
self.assert_(not self.svc.hasAnnotations(prince))
princeAnnotation['something'] = 'whatever'
# But now we should have the annotation:
self.assert_(self.svc.hasAnnotations(prince))
def testGetFromLayered(self):
princeSomebody = Principal('somebody')
sm1 = self.makeSite('folder1')
subService = setup.addService(sm1, 'PrincipalAnnotation',
PrincipalAnnotationService())
parentAnnotation = self.svc.getAnnotations(princeSomebody)
# Just getting doesn't actualy store. We don't want to store unless
# we make a change.
self.assert_(not subService.hasAnnotations(princeSomebody))
parentAnnotation['hair_color'] = 'blue'
# But now we should have the annotation:
self.assert_(self.svc.hasAnnotations(princeSomebody))
subAnnotation = subService.getAnnotations(princeSomebody)
self.assertEquals(subAnnotation['hair_color'], 'blue')
subAnnotation['foo'] = 'bar'
self.assertEquals(parentAnnotation.get("foo"), None)
def testAdapter(self):
p = Principal('somebody')
ztapi.provideAdapter(IPrincipal, IAnnotations,
AnnotationsForPrincipal(self.svc))
annotations = IAnnotations(p)
annotations["test"] = "bar"
annotations = IAnnotations(p)
self.assertEquals(annotations["test"], "bar")
def test_suite():
loader=TestLoader()
return loader.loadTestsFromTestCase(PrincipalAnnotationTests)
if __name__=='__main__':
TextTestRunner().run(test_suite())
More information about the Zope3-Checkins
mailing list