~ubuntu-branches/ubuntu/utopic/python-apptools/utopic

« back to all changes in this revision

Viewing changes to apptools/type_manager/type_manager.py

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2011-07-08 23:55:50 UTC
  • mfrom: (2.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110708235550-yz5u79ubeo4dhyfx
Tags: 4.0.0-1
* New upstream release
* Update debian/watch file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
""" A type manager. """
 
2
 
 
3
 
 
4
# Enthought library imports.
 
5
from traits.api import HasTraits, Instance, Property, Str
 
6
 
 
7
# Local imports.
 
8
from abstract_type_system import AbstractTypeSystem
 
9
from adapter_manager import AdapterManager
 
10
from factory import Factory
 
11
from hook import add_pre, add_post, remove_pre, remove_post
 
12
from python_type_system import PythonTypeSystem
 
13
 
 
14
 
 
15
class TypeManager(HasTraits):
 
16
    """ A type manager.
 
17
 
 
18
    The type manager allows for objects to be created/adapted to a particular
 
19
    type.
 
20
 
 
21
    """
 
22
 
 
23
    #### 'TypeManager' interface ##############################################
 
24
 
 
25
    # The adapter manager looks after errr, all adapters.
 
26
    adapter_manager = Property(Instance(AdapterManager))
 
27
 
 
28
    # The type manager's globally unique identifier (only required if you have
 
29
    # more than one type manager of course!).
 
30
    id = Str
 
31
 
 
32
    # The parent type manager.
 
33
    #
 
34
    # By default this is None, but you can use it to set up a hierarchy of
 
35
    # type managers. If a type manager fails to adapt or create an object of
 
36
    # some target class then it will give its parent a chance to do so.
 
37
    parent = Instance('TypeManager')
 
38
 
 
39
    # The type system used by the manager (it determines 'is_a' relationships
 
40
    # and type MROs etc).
 
41
    #
 
42
    # By default we use standard Python semantics.
 
43
    type_system = Instance(AbstractTypeSystem, PythonTypeSystem())
 
44
 
 
45
    #### Private interface ####################################################
 
46
 
 
47
    # The adapter manager looks after errr, all adapters.
 
48
    _adapter_manager = Instance(AdapterManager)
 
49
 
 
50
    ###########################################################################
 
51
    # 'TypeManager' interface.
 
52
    ###########################################################################
 
53
 
 
54
    #### Properties ###########################################################
 
55
 
 
56
    def _get_adapter_manager(self):
 
57
        """ Returns the adapter manager. """
 
58
 
 
59
        return self._adapter_manager
 
60
 
 
61
    #### Methods ##############################################################
 
62
 
 
63
    def object_as(self, obj, target_class, *args, **kw):
 
64
        """ Adapts or creates an object of the target class.
 
65
 
 
66
        Returns None if no appropriate adapter or factory is available.
 
67
 
 
68
        """
 
69
 
 
70
        # If the object is already an instance of the target class then we
 
71
        # simply return it.
 
72
        if self.type_system.is_a(obj, target_class):
 
73
            result = obj
 
74
 
 
75
        # If the object is a factory that creates instances of the target class
 
76
        # then ask it to produce one.
 
77
        elif self._is_factory_for(obj, target_class, *args, **kw):
 
78
            result = obj.create(target_class, *args, **kw)
 
79
 
 
80
        # Otherwise, see if the object can be adapted to the target class.
 
81
        else:
 
82
            result = self._adapter_manager.adapt(obj, target_class, *args,**kw)
 
83
 
 
84
        # If this type manager couldn't do the job, then give its parent a go!
 
85
        if result is None and self.parent is not None:
 
86
            result = self.parent.object_as(obj, target_class, *args, **kw)
 
87
 
 
88
        return result
 
89
 
 
90
    # Adapters.
 
91
    def register_adapters(self, factory, adaptee_class):
 
92
        """ Registers an adapter factory.
 
93
 
 
94
        'adaptee_class' can be either a class or the name of a class.
 
95
 
 
96
        """
 
97
 
 
98
        self._adapter_manager.register_adapters(factory, adaptee_class)
 
99
 
 
100
        return
 
101
 
 
102
    def unregister_adapters(self, factory):
 
103
        """ Unregisters an adapter factory. """
 
104
 
 
105
        self._adapter_manager.unregister_adapters(factory)
 
106
 
 
107
        return
 
108
 
 
109
    def register_instance_adapters(self, factory, obj):
 
110
        """ Registers an adapter factory for an individual instance.
 
111
 
 
112
        A factory can be in exactly one manager (as it uses the manager's type
 
113
        system).
 
114
 
 
115
        """
 
116
 
 
117
        self._adapter_manager.register_instance_adapters(factory, obj)
 
118
 
 
119
        return
 
120
 
 
121
    def unregister_instance_adapters(self, factory, obj):
 
122
        """ Unregisters an adapter factory for an individual instance.
 
123
 
 
124
        A factory can be in exactly one manager (as it uses the manager's type
 
125
        system).
 
126
 
 
127
        """
 
128
 
 
129
        self._adapter_manager.unregister_instance_adapters(factory, obj)
 
130
 
 
131
        return
 
132
 
 
133
    def register_type_adapters(self, factory, adaptee_class):
 
134
        """ Registers an adapter factory.
 
135
 
 
136
        'adaptee_class' can be either a class or the name of a class.
 
137
 
 
138
        """
 
139
 
 
140
        self._adapter_manager.register_type_adapters(factory, adaptee_class)
 
141
 
 
142
        return
 
143
 
 
144
    def unregister_type_adapters(self, factory):
 
145
        """ Unregisters an adapter factory. """
 
146
 
 
147
        self._adapter_manager.unregister_type_adapters(factory)
 
148
 
 
149
        return
 
150
 
 
151
    # Categories.
 
152
    #
 
153
    # Currently, there is no technical reason why we have this convenience
 
154
    # method to add categories. However, it may well turn out to be useful to
 
155
    # track all categories added via the type manager.
 
156
    def add_category(self, klass, category_class):
 
157
        """ Adds a category to a class. """
 
158
 
 
159
        klass.add_trait_category(category_class)
 
160
 
 
161
        return
 
162
 
 
163
    # Hooks.
 
164
    #
 
165
    # Currently, there is no technical reason why we have these convenience
 
166
    # methods to add and remove hooks. However, it may well turn out to be
 
167
    # useful to track all hooks added via the type manager.
 
168
    def add_pre(self, klass, method_name, callable):
 
169
        """ Adds a pre-hook to method 'method_name' on class 'klass. """
 
170
 
 
171
        add_pre(klass, method_name, callable)
 
172
 
 
173
        return
 
174
 
 
175
    def add_post(self, klass, method_name, callable):
 
176
        """ Adds a post-hook to method 'method_name' on class 'klass. """
 
177
 
 
178
        add_post(klass, method_name, callable)
 
179
 
 
180
        return
 
181
 
 
182
    def remove_pre(self, klass, method_name, callable):
 
183
        """ Removes a pre-hook to method 'method_name' on class 'klass. """
 
184
 
 
185
        remove_pre(klass, method_name, callable)
 
186
 
 
187
        return
 
188
 
 
189
    def remove_post(self, klass, method_name, callable):
 
190
        """ Removes a post-hook to method 'method_name' on class 'klass. """
 
191
 
 
192
        remove_post(klass, method_name, callable)
 
193
 
 
194
        return
 
195
 
 
196
    ###########################################################################
 
197
    # Private interface.
 
198
    ###########################################################################
 
199
 
 
200
    #### Initializers #########################################################
 
201
 
 
202
    def __adapter_manager_default(self):
 
203
        """ Initializes the '_adapter_manager' trait. """
 
204
 
 
205
        return AdapterManager(type_system=self.type_system)
 
206
 
 
207
    #### Methods ##############################################################
 
208
 
 
209
    def _is_factory_for(self, obj, target_class, *args, **kw):
 
210
        """ Returns True iff the object is a factory for the target class. """
 
211
 
 
212
        is_factory_for = self.type_system.is_a(obj, Factory) \
 
213
                         and obj.can_create(target_class, *args, **kw)
 
214
 
 
215
        return is_factory_for
 
216
 
 
217
#### EOF ######################################################################