1 | ## $Id: sourcefactory.py 11997 2014-11-19 17:02:48Z henrik $ |
---|
2 | ## |
---|
3 | ## Copyright (C) 2012 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 | """Smarter contextual sources, that can do faster containment checks. |
---|
19 | """ |
---|
20 | import zc.sourcefactory.policies |
---|
21 | from zc.sourcefactory.factories import ContextualSourceFactory |
---|
22 | from zc.sourcefactory.source import FactoredContextualSource |
---|
23 | |
---|
24 | class SmartFactoredContextualSource(FactoredContextualSource): |
---|
25 | """A contextual source that can be faster. |
---|
26 | |
---|
27 | Regular ContextualSources from zc.sourcefactory suffer from very |
---|
28 | expensive and slow containment checks. __contains__ is executed as |
---|
29 | a lookup over the complete set of possible values. |
---|
30 | |
---|
31 | If, however, a source could do this lookup faster, it had no |
---|
32 | chance to do that with regular ContextualSources. |
---|
33 | |
---|
34 | This source instead looks for a `contains()` method of a |
---|
35 | contextual source first and if it has one, this method is called |
---|
36 | with `value` and `context` as arguments. |
---|
37 | |
---|
38 | If a source does not provide `contains()`, the expensive default |
---|
39 | lookup method is done instead. |
---|
40 | """ |
---|
41 | def __contains__(self, value): |
---|
42 | """Check whether `value` is part of the source. |
---|
43 | |
---|
44 | If the factored source provides a `contains(value, context)` |
---|
45 | method, this method is called for faster containment |
---|
46 | checks. If not, then the getValues() method of a factored |
---|
47 | source is used to examine each single item contained in the |
---|
48 | source. |
---|
49 | """ |
---|
50 | if hasattr(self.factory, 'contains'): |
---|
51 | return self.factory.contains(self.context, value) |
---|
52 | # This is potentially expensive! |
---|
53 | return super(SmartFactoredContextualSource, self).__contains__( |
---|
54 | value) |
---|
55 | |
---|
56 | class SmartContextualSourceFactory(ContextualSourceFactory): |
---|
57 | source_class = SmartFactoredContextualSource |
---|
58 | |
---|
59 | class SmartBasicContextualSourceFactory( |
---|
60 | SmartContextualSourceFactory, |
---|
61 | zc.sourcefactory.policies.BasicContextualSourcePolicy): |
---|
62 | """Abstract base implementation for a basic but smart contextual |
---|
63 | source factory. |
---|
64 | |
---|
65 | These factories use any `contains(value, context)` method of |
---|
66 | factored sources to speed up containment checks. |
---|
67 | |
---|
68 | Instances of this class can be used as replacement for |
---|
69 | `zc.sourcefactory.BasicContextualSourceFactory`. If your |
---|
70 | implementation derived from :class:`SmartBasicContextualFactory` |
---|
71 | additionally provides a smart `contains()` method, you only get |
---|
72 | benefits from using this class. |
---|
73 | |
---|
74 | The basic requirements for a working |
---|
75 | `SmartBasicContextualSourceFactory` are the same as for regular |
---|
76 | ones: you have to implement a `getValues(context)` method. You can |
---|
77 | (optionally) implements a `contains(value, context)` method. |
---|
78 | """ |
---|