2008-08-15 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/upstream/at-spi2-core.git] / pyatspi / cache.py
1 #Copyright (C) 2008 Codethink Ltd
2
3 #This library is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU Lesser General Public
5 #License version 2 as published by the Free Software Foundation.
6
7 #This program is distributed in the hope that it will be useful,
8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 #GNU General Public License for more details.
11 #You should have received a copy of the GNU Lesser General Public License
12 #along with this program; if not, write to the Free Software
13 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
15 import dbus as _dbus
16
17 #------------------------------------------------------------------------------
18
19 class _CacheData(object):
20         __slots__ =     [
21                         'parent',
22                         'interfaces',
23                         'children',
24                         'role',
25                         'name',
26                         'description',
27                         ]
28
29         def __init__(self, data):
30                 self.update(data)
31
32         def update(self, data):
33                 #Don't cache the path here, used as lookup in cache object dict.
34                 (path,
35                 self.parent,
36                 self.children,
37                 self.interfaces,
38                 self.name,
39                 self.role,
40                 self.description) = data
41
42 #------------------------------------------------------------------------------
43
44 class _BaseCache(object):
45
46         def __init__(self, connection, bus_name):
47                 """
48                 Creates a cache.
49
50                 connection - DBus connection.
51                 busName    - Name of DBus connection where cache interface resides.
52                 """
53                 self._connection = connection
54                 self._bus_name = bus_name
55
56                 obj = connection.get_object(bus_name, self._PATH, introspect=False)
57                 itf = _dbus.Interface(obj, self._INTERFACE)
58
59                 self._objects = {}
60
61                 get_method = itf.get_dbus_method(self._GET_METHOD)
62                 self._update_objects(get_method())
63
64                 self._signalMatch = itf.connect_to_signal(self._UPDATE_SIGNAL, self._update_handler)
65
66         def __getitem__(self, key):
67                 return self._objects[key]
68
69         def __contains__(self, key):
70                 return key in self._objects
71
72         def _update_handler(self, updates):
73                 update, remove = updates
74                 self._remove_objects(update)
75                 self._update_objects(remove)
76
77         def _update_objects(self, objects):
78                 for data in objects:
79                         #First element is the object path.
80                         path = data[0]
81                         if path in self._objects:
82                                 cachedata = self._objects[path]
83                                 cachedata.update(data)
84                         else:
85                                 self._objects[path] = _CacheData(data)
86
87         def _remove_objects(self, paths):
88                 for path in paths:
89                         del(self._objects[path])
90
91
92 #------------------------------------------------------------------------------
93
94 class AccessibleCache(_BaseCache):
95         """
96         There is one accessible cache per application.
97         For each application the accessible cache stores
98         data on every accessible object within the app.
99
100         It also acts as the factory for creating client
101         side proxies for these accessible objects.
102                 
103         connection - DBus connection.
104         busName    - Name of DBus connection where cache interface resides.
105         """
106
107         _PATH = '/org/freedesktop/atspi/tree'
108         _INTERFACE = 'org.freedesktop.atspi.Tree'
109         _GET_METHOD = 'getTree'
110         _UPDATE_SIGNAL = 'updateTree'
111
112         def __init__(self, connection, bus_name):
113                 _BaseCache.__init__(self, connection, bus_name)
114
115                 obj = connection.get_object(self._bus_name, self._PATH, introspect=False)
116                 itf = _dbus.Interface(obj, self._INTERFACE)
117
118                 self._root = itf.getRoot()
119
120         def _get_root(self):
121                 return self._root
122
123         root = property(fget=_get_root)
124
125 #END---------------------------------------------------------------------------