source: main/waeup.sirp/trunk/src/waeup/sirp/university/certificatecontainer.py @ 7195

Last change on this file since 7195 was 7195, checked in by Henrik Bettermann, 13 years ago

More copyright adjustments.

  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
1## $Id: certificatecontainer.py 7195 2011-11-25 07:34:07Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""Containers for certificates.
19"""
20import grok
21from zope.catalog.interfaces import ICatalog
22from zope.component.interfaces import IFactory
23from zope.component import queryUtility
24from zope.interface import implementedBy
25from waeup.sirp.interfaces import DuplicationError
26from waeup.sirp.university.interfaces import (
27    ICertificateContainer, ICertificate)
28
29class CertificateContainer(grok.Container):
30    """A storage for certificates.
31
32    A :class:`CertificateContainer` stores
33    :class:`waeup.sirp.university.Certificate` instances.
34
35    It is a :class:`grok.Container` basically acting like a standard
36    Python dictionary. That means you can add certificates like items
37    in a normal dictionary and also get certificates by using
38    :meth:`values`, :meth:`keys`, and :meth:`items`.
39
40    This container type is picky about its contents: only real
41    certificates can be stored here and each new certificate must
42    provide a unique `code`. See :meth:`addCertificate` for details.
43
44    Each :class:`CertificateContainer` provides
45    :class:`ICertificateContainer`.
46    """
47    grok.implements(ICertificateContainer)
48    grok.require('waeup.manageUniversity')
49
50    def __setitem__(self, name, certificate):
51        """Insert `certificate` with `name` as key into container.
52
53        The `certificate` must be an object implementing
54        :class:`waeup.sirp.university.interfaces.ICertificate`. If
55        not, a :exc:`TypeError` is raised.
56
57        If the certificate `code` does not equal `name` a
58        :exc:`ValueError` is raised.
59
60        If the `code` attribute of `certificate` is already in use by
61        another certificate stored in the local site
62        (:class:`waeup.sirp.app.University` instance), then a
63        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
64
65        If `name` is already used as a key, a :exc:`KeyError` will be
66        raised.
67        """
68        if not ICertificate.providedBy(certificate):
69            raise TypeError('CertificateContainers contain only '
70                            'ICertificate instances')
71
72        # Only accept certs with code == key.
73        if certificate.code != name:
74            raise ValueError('key must match certificate code: '
75                             '%s, %s' % (name, certificate.code))
76
77        # Lookup catalog. If we find none: no duplicates possible.
78        cat = queryUtility(ICatalog, name='certificates_catalog', default=None)
79        if cat is not None:
80            entries = cat.searchResults(
81                code=(certificate.code,certificate.code))
82            if len(entries) > 0:
83                raise DuplicationError(
84                    'Certificate exists already elsewhere.', entries)
85        else:
86            # No catalog, then this addition won't do harm to anything.
87            pass
88        super(CertificateContainer, self).__setitem__(name, certificate)
89
90    def addCertificate(self, certificate):
91        """Add `certificate` to the container.
92
93        The certificate must be an object implementing
94        :class:`waeup.sirp.university.interfaces.ICertificate`. If
95        not, a :exc:`TypeError` is raised.
96
97        The certificate will be stored in the container with its
98        `code` attribute as key. If this key is already used for
99        another certificate stored in the local site
100        (:class:`waeup.sirp.app.University` instance), then a
101        :exc:`waeup.sirp.interfaces.DuplicationError` will be raised.
102        """
103        self[getattr(certificate, 'code', None)] = certificate
104
105    def clear(self):
106        """Remove all contents from the certificate container.
107
108        This methods is pretty fast and optimized. Use it instead of
109        removing all items manually yourself.
110        """
111        # This internal function is implemented in C and thus much
112        # faster as we could do it in pure Python.
113        self._SampleContainer__data.clear()
114        # The length attribute is 'lazy'. See `zope.container` for details.
115        # This way we make sure, the next time len() is called, it returns
116        # the real value and not a cached one.
117        del self.__dict__['_BTreeContainer__len']
118
119class CertificateContainerFactory(grok.GlobalUtility):
120    """A factory for certificate containers.
121    """
122    grok.implements(IFactory)
123    grok.name(u'waeup.CertificateContainer')
124    title = u"Create a new certificate container.",
125    description = u"This factory instantiates new certificate containers."
126
127    def __call__(self, *args, **kw):
128        return CertificateContainer(*args, **kw)
129
130    def getInterfaces(self):
131        return implementedBy(CertificateContainer)
Note: See TracBrowser for help on using the repository browser.