FIXME++
[omaha.git] / Overlord / plugin_pattern.py
blob34a9b26f2ecb5ac171363c9d3bb17ecd2a08c218
1 # This file is part of the Omaha Board-Game GUI.
2 # Copyright (C) 2009-2015 Yann Dirson
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation,
7 # version 2.1 of the License.
9 # This library 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 GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 __all__ = [ 'PluginPattern' ]
20 from .misc import class_fullname
22 import logging
23 logger = logging.getLogger('Overlord.plugin_pattern')
25 class PluginPattern(object):
26 def match_distance(self, plugin):
27 raise NotImplementedError()
29 class AnyPluginPattern(PluginPattern):
30 def match_distance(self, plugin):
31 return 0
32 Any = AnyPluginPattern()
34 class Or(PluginPattern):
35 def __init__(self, *patterns):
36 super(Or, self).__init__()
37 self.__patterns = patterns
38 def match_distance(self, plugin):
39 for pat in self.__patterns:
40 d = pat.match_distance(plugin)
41 if d is not None:
42 return d
43 else:
44 return None
46 class And(PluginPattern):
47 def __init__(self, *patterns):
48 super(And, self).__init__()
49 self.__patterns = patterns
50 def match_distance(self, plugin):
51 distances = [ pat.match_distance(plugin) for pat in self.__patterns ]
52 if None in distances:
53 return None
54 return max(distances)
56 class ParentOf(PluginPattern):
57 """Assumes cls.mro() does not change over the live of the pattern object."""
58 def __init__(self, pluginkey, cls):
59 assert isinstance(cls, type)
60 super(ParentOf, self).__init__()
61 self.__pluginkey, self.__cls = pluginkey, cls
62 self.__parentnames = [ class_fullname(parent_cls)
63 for parent_cls in cls.mro() ]
64 def match_distance(self, plugin):
65 candidates = plugin.listfield(self.__pluginkey)
66 logger.debug("match_distance(%s) in %s ?", plugin, candidates)
67 for candidate in candidates:
68 try:
69 return self.__parentnames.index(candidate)
70 except ValueError:
71 continue
72 else:
73 return None
74 def __repr__(self):
75 return "ParentOf(%r, %r)" % (self.__pluginkey, self.__cls)