/usr/share/pyshared/zope/principalannotation/utility.py is in python-zope.principalannotation 3.6.1-0ubuntu4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | ##############################################################################
#
# Copyright (c) 2009 Zope Foundation 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.
#
##############################################################################
"""Implementation of IPrincipalAnnotationUtility
$Id: utility.py 104798 2009-10-05 15:01:13Z tlotze $
"""
__docformat__ = 'restructuredtext'
from BTrees.OOBTree import OOBTree
from persistent import Persistent
from persistent.dict import PersistentDict
from zope import interface, component
from zope.annotation.interfaces import IAnnotations
from zope.location import Location
from zope.location.interfaces import IContained
from zope.security.interfaces import IPrincipal
from zope.site.next import queryNextUtility
from zope.principalannotation.interfaces import IPrincipalAnnotationUtility
# TODO: register utility as adapter for IAnnotations on utility activation.
class PrincipalAnnotationUtility(Persistent):
"""Stores `IAnnotations` for `IPrinicipals`.
The utility ID is 'PrincipalAnnotation'.
"""
interface.implements(IPrincipalAnnotationUtility, IContained)
__parent__ = None
__name__ = None
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."""
interface.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 __nonzero__(self):
nz = bool(self.data)
if not nz:
# maybe higher-level utility's annotations will be non-zero
next = queryNextUtility(self, IPrincipalAnnotationUtility)
if next is not None:
annotations = next.getAnnotationsById(self.principalId)
return bool(next)
return nz
def __getitem__(self, key):
try:
return self.data[key]
except KeyError:
# We failed locally: delegate to a higher-level utility.
next = queryNextUtility(self, IPrincipalAnnotationUtility)
if next is not None:
annotations = next.getAnnotationsById(self.principalId)
return annotations[key]
raise
def get(self, key, default=None):
try:
return self[key]
except KeyError:
return default
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]
@component.adapter(IPrincipal)
@interface.implementer(IAnnotations)
def annotations(principal, context=None):
utility = component.getUtility(IPrincipalAnnotationUtility, context=context)
return utility.getAnnotations(principal)
|