source: main/waeup.kofa/branches/uli-zc-async/src/waeup/kofa/university/certificatescontainer.py @ 10371

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

Add more roles and reorganize permissions.

Remove grok.require('waeup.manageUniversity') from grok.Container classes.

  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
1## $Id: certificatescontainer.py 8367 2012-05-06 11:19:38Z 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.kofa.interfaces import DuplicationError
26from waeup.kofa.university.interfaces import (
27    ICertificatesContainer, ICertificate)
28
29class CertificatesContainer(grok.Container):
30    """A storage for certificates.
31
32    A :class:`CertificatesContainer` stores
33    :class:`waeup.kofa.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:`CertificatesContainer` provides
45    :class:`ICertificatesContainer`.
46    """
47    grok.implements(ICertificatesContainer)
48
49    def __setitem__(self, name, certificate):
50        """Insert `certificate` with `name` as key into container.
51
52        The `certificate` must be an object implementing
53        :class:`waeup.kofa.university.interfaces.ICertificate`. If
54        not, a :exc:`TypeError` is raised.
55
56        If the certificate `code` does not equal `name` a
57        :exc:`ValueError` is raised.
58
59        If the `code` attribute of `certificate` is already in use by
60        another certificate stored in the local site
61        (:class:`waeup.kofa.app.University` instance), then a
62        :exc:`waeup.kofa.interfaces.DuplicationError` will be raised.
63
64        If `name` is already used as a key, a :exc:`KeyError` will be
65        raised.
66        """
67        if not ICertificate.providedBy(certificate):
68            raise TypeError('CertificatesContainers contain only '
69                            'ICertificate instances')
70
71        # Only accept certs with code == key.
72        if certificate.code != name:
73            raise ValueError('key must match certificate code: '
74                             '%s, %s' % (name, certificate.code))
75
76        # Lookup catalog. If we find none: no duplicates possible.
77        cat = queryUtility(ICatalog, name='certificates_catalog', default=None)
78        if cat is not None:
79            entries = cat.searchResults(
80                code=(certificate.code,certificate.code))
81            if len(entries) > 0:
82                raise DuplicationError(
83                    'Certificate exists already elsewhere.', entries)
84        else:
85            # No catalog, then this addition won't do harm to anything.
86            pass
87        super(CertificatesContainer, self).__setitem__(name, certificate)
88
89    def addCertificate(self, certificate):
90        """Add `certificate` to the container.
91
92        The certificate must be an object implementing
93        :class:`waeup.kofa.university.interfaces.ICertificate`. If
94        not, a :exc:`TypeError` is raised.
95
96        The certificate will be stored in the container with its
97        `code` attribute as key. If this key is already used for
98        another certificate stored in the local site
99        (:class:`waeup.kofa.app.University` instance), then a
100        :exc:`waeup.kofa.interfaces.DuplicationError` will be raised.
101        """
102        self[getattr(certificate, 'code', None)] = certificate
103
104    def clear(self):
105        """Remove all contents from the certificate container.
106
107        This methods is pretty fast and optimized. Use it instead of
108        removing all items manually yourself.
109        """
110        # This internal function is implemented in C and thus much
111        # faster as we could do it in pure Python.
112        self._SampleContainer__data.clear()
113        # The length attribute is 'lazy'. See `zope.container` for details.
114        # This way we make sure, the next time len() is called, it returns
115        # the real value and not a cached one.
116        del self.__dict__['_BTreeContainer__len']
117
118class CertificatesContainerFactory(grok.GlobalUtility):
119    """A factory for certificate containers.
120    """
121    grok.implements(IFactory)
122    grok.name(u'waeup.CertificatesContainer')
123    title = u"Create a new container for certificates.",
124    description = u"This factory instantiates new containers for certificates."
125
126    def __call__(self, *args, **kw):
127        return CertificatesContainer(*args, **kw)
128
129    def getInterfaces(self):
130        return implementedBy(CertificatesContainer)
Note: See TracBrowser for help on using the repository browser.