* qt/: Update to Subversion r548032.
[platform/upstream/dbus.git] / qt / src / qdbusintrospection.cpp
1 /* -*- C++ -*-
2  *
3  * Copyright (C) 2006 Trolltech AS. All rights reserved.
4  *    Author: Thiago Macieira <thiago.macieira@trolltech.com>
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  */
23
24 #include "qdbusintrospection_p.h"
25 #include "qdbusxmlparser_p.h"
26
27 /*!
28     \class QDBusIntrospection
29     \brief Information about introspected objects and interfaces on D-Bus.
30     \internal
31
32     This class provides structures and methods for parsing the XML introspection data for D-Bus.
33     Normally, you don't have to use the methods provided here: QDBusInterface and QDBusObject will
34     do that for you.
35
36     But they may prove useful if the XML data was obtained through other means (like parsing a file).
37 */
38
39 /*!
40     \class QDBusIntrospection::Argument
41     \brief One argument to a D-Bus method or signal.
42
43     This struct represents one argument passed to a method or received from a method or signal in
44     D-Bus. The struct does not contain information on the direction (input or output).
45 */
46
47 /*!
48     \var QDBusIntrospection::Argument::type
49     The argument type.
50 */
51
52 /*!
53     \var QDBusIntrospection::Argument::name
54     The argument name. The argument name is optional, so this may be a null QString.
55 */
56
57 /*!
58     \fn QDBusIntrospection::Argument::operator==(const Argument &other) const
59     Compares this object against \a other and return true if they are the same.
60 */
61
62 /*!
63     \class QDBusIntrospection::Method
64     \brief Information about one method.
65
66     This struct represents one method discovered through introspection. A method is composed of
67     its \a name, its input arguments, its output arguments, and, optionally, annotations. There are no
68     "in-out" arguments.
69 */
70
71 /*!
72     \var QDBusIntrospection::Method::name
73     The method's name.
74 */
75
76 /*!
77     \var QDBusIntrospection::Method::inputArgs
78     A list of the method's input arguments.
79 */
80
81 /*!
82     \var QDBusIntrospection::Method::outputArgs
83     A list of the method's output arguments (i.e., return values).
84 */
85
86 /*!
87     \var QDBusIntrospection::Method::annotations
88     The annotations associated with the method. Each annotation is a pair of strings, where the key
89     is of the same format as a D-Bus interface name. The value is arbitrary.
90 */
91
92 /*!
93     \fn QDBusIntrospection::Method::operator==(const Method &other) const
94     Compares this object against \a other and return true if they are the same.
95 */
96
97 /*!
98     \class QDBusIntrospection::Signal
99     \brief Information about one signal.
100
101     This struct represents one signal discovered through introspection. A signal is composed of
102     its \a name, its output arguments, and, optionally, annotations.
103 */
104
105 /*!
106     \var QDBusIntrospection::Signal::name
107     The signal's name.
108 */
109
110 /*!
111     \var QDBusIntrospection::Signal::outputArgs
112     A list of the signal's arguments.
113 */
114
115 /*!
116     \var QDBusIntrospection::Signal::annotations
117     The annotations associated with the signal. Each annotation is a pair of strings, where the key
118     is of the same format as a D-Bus interface name. The value is arbitrary.
119 */
120
121 /*!
122     \fn QDBusIntrospection::Signal::operator==(const Signal& other) const
123     Compares this object against \a other and return true if they are the same.
124 */
125
126 /*!
127     \class QDBusIntrospection::Property
128     \brief Information about one property.
129
130     This struct represents one property discovered through introspection. A property is composed of
131     its \a name, its \a type, its \a access rights, and, optionally, annotations.
132 */
133
134 /*!
135     \var QDBusIntrospection::Property::name
136     The property's name.
137 */
138
139 /*!
140     \var QDBusIntrospection::Property::type
141     The property's type.
142 */
143
144 /*!
145     \enum QDBusIntrospection::Property::Access
146     The possible access rights for a property:
147     \value Read
148     \value Write
149     \value ReadWrite
150 */
151
152 /*!
153     \var QDBusIntrospection::Property::access
154     The property's access rights.
155 */
156
157 /*!
158     \var QDBusIntrospection::Property::annotations
159     The annotations associated with the property. Each annotation is a pair of strings, where the key
160     is of the same format as a D-Bus interface name. The value is arbitrary.
161 */
162
163 /*!
164     \fn QDBusIntrospection::Property::operator==(const Property &other) const
165     Compares this object against \a other and return true if they are the same.
166 */
167
168 /*!
169     \class QDBusIntrospection::Interface
170     \brief Information about one interface on the bus.
171
172     Each interface on D-Bus has an unique \a name, identifying where that interface was defined.
173     Interfaces may have annotations, methods, signals and properties, but none are mandatory.
174 */
175
176 /*!
177     \var QDBusIntrospection::Interface::name
178     The interface's name.
179 */
180
181 /*!
182     \var QDBusIntrospection::Interface::introspection
183     The XML document fragment describing this interface.
184
185     If parsed again through parseInterface, the object returned should have the same contents as
186     this object.
187 */
188
189 /*!
190     \var QDBusIntrospection::Interface::annotations
191     The annotations associated with the interface. Each annotation is a pair of strings, where the key
192     is of the same format as a D-Bus interface name. The value is arbitrary.
193 */
194
195 /*!
196     \var QDBusIntrospection::Interface::methods
197     The methods available in this interface. Note that method names are not unique (i.e., methods
198     can be overloaded with multiple arguments types).
199 */
200
201 /*!
202     \var QDBusIntrospection::Interface::signals_
203     The signals available in this interface. Note that signal names are not unique (i.e., signals
204     can be overloaded with multiple argument types).
205
206     This member is called "signals_" because "signals" is a reserved keyword in Qt.
207 */
208
209 /*!
210     \var QDBusIntrospection::Interface::properties
211     The properties available in this interface. Property names are unique.
212 */
213
214 /*!
215     \fn QDBusIntrospection::Interface::operator==(const Interface &other) const
216     Compares this object against \a other and return true if they are the same.
217
218     Note that two interfaces are considered to be the same if they have the same name. The internal
219     structures in the objects are not compared.
220 */
221
222 /*!
223     \class QDBusIntrospection::Object
224     \brief Information about one object on the bus.
225
226     An object on the D-Bus bus is represented by its service and path on the service but, unlike
227     interfaces, objects are mutable. That is, their contents can change with time. Therefore,
228     while the (service, path) pair uniquely identifies an object, the information contained in
229     this struct may no longer represent the object.
230
231     An object can contain interfaces and child (sub) objects.
232 */
233
234 /*!
235     \var QDBusIntrospection::Object::service
236     The object's service name.
237
238     \sa parseObject(), parseObjectTree()
239 */
240
241 /*!
242     \var QDBusIntrospection::Object::path
243     The object's path on the service. This is an absolute path.
244
245     \sa parseObject(), parseObjectTree()
246 */
247
248 /*!
249     \var QDBusIntrospection::Object::introspection
250     The XML document fragment describing this object, its interfaces and sub-objects at the time
251     of the parsing.
252
253     The result of parseObject with this XML data should be the same as the Object struct.
254 */
255
256 /*!
257     \var QDBusIntrospection::Object::interfaces
258     The list of interface names in this object.
259 */
260
261 /*!
262     \var QDBusIntrospection::Object::childObjects
263     The list of child object names in this object. Note that this is a relative name, not an
264     absolute path. To obtain the absolute path, concatenate with \l
265     {QDBusIntrospection::Object::path}{path}.
266 */
267
268 /*!
269     \class QDBusIntrospection::ObjectTree
270     \brief Complete information about one object node and its descendency.
271     
272     This struct contains the same data as QDBusIntrospection::Object, plus the actual data for the
273     interfaces and child (sub) objects that was available in the XML document.
274 */
275
276 /*!
277     \var QDBusIntrospection::ObjectTree::interfaceData
278     A map of interfaces and their names.
279 */
280
281 /*!
282     \var QDBusIntrospection::ObjectTree::childObjectData
283     A map of object paths and their data. The map key contains the relative path to the object.
284
285     Note this map contains only the child notes that do have information about the sub-object's
286     contents. If the XML data did not contain the information, only the object name will be listed
287     in childObjects, but not in childObjectData.
288 */
289
290 /*!
291     \typedef QDBusIntrospection::Annotations
292     Contains a QMap of an annotation pair. The annotation's name is stored in the QMap key and
293     must be unique. The annotation's value is stored in the QMap's value and is arbitrary.
294 */
295
296 /*!
297     \typedef QDBusIntrospection::Arguments
298     Contains a list of arguments to either a Method or a Signal. The arguments' order is important.
299 */
300
301 /*!
302     \typedef QDBusIntrospection::Methods
303     Contains a QMap of methods and their names. The method's name is stored in the map's key and
304     is not necessarily unique. The order in which multiple methods with the same name are stored
305     in this map is undefined.
306 */
307
308 /*!
309     \typedef QDBusIntrospection::Signals
310     Contains a QMap of signals and their names. The signal's name is stored in the map's key and
311     is not necessarily unique. The order in which multiple signals with the same name are stored
312     in this map is undefined.
313 */
314
315 /*!
316     \typedef QDBusIntrospection::Properties
317     Contains a QMap of properties and their names. Each property must have a unique name.
318 */
319
320 /*!
321     \typedef QDBusIntrospection::Interfaces
322     Contains a QMap of interfaces and their names. Each interface has a unique name.
323 */
324
325 /*!
326     \typedef QDBusIntrospection::Objects
327     Contains a QMap of objects and their paths relative to their immediate parent.
328
329     \sa parseObjectTree()
330 */
331
332 /*!
333     Parses the XML document fragment (given by \a xml) containing one interface.
334
335     The first element tag in this XML data must be either \<node\> or \<interface\>. If it is
336     \<node\>, then the \<interface\> tag must be a child tag of the \<node\> one.
337
338     If there are multiple interfaces in this XML data, it is undefined which one will be
339     returned.
340 */
341 QDBusIntrospection::Interface
342 QDBusIntrospection::parseInterface(const QString &xml)
343 {
344     // be lazy
345     Interfaces ifs = parseInterfaces(xml);
346     if (ifs.isEmpty())
347         return Interface();
348
349     // return the first in map order (probably alphabetical order)
350     return *ifs.constBegin().value();
351 }
352
353 /*!
354     Parses the XML document fragment (given by \a xml) containing several interfaces.
355
356     If the first element tag in this document fragment is \<node\>, the interfaces parsed will
357     be those found as child elements of the \<node\> tag.
358 */
359 QDBusIntrospection::Interfaces
360 QDBusIntrospection::parseInterfaces(const QString &xml)
361 {
362     QString null;
363     QDBusXmlParser parser(null, null, xml);
364     return parser.interfaces();
365 }
366
367 /*!
368     Parses the XML document fragment (given by \a xml) containing one object, found at the service
369     \a service and path \a path.
370
371     The first element tag in this document must be \<node\>. If that tag does not contain
372     a name attribute, the \a path argument will be used to determine the path of this
373     object node.
374
375     This function does not parse the interfaces contained in the node, nor sub-object's contents.
376     It will only list their names. If you need to know their contents, use parseObjectTree.
377 */
378 QDBusIntrospection::Object
379 QDBusIntrospection::parseObject(const QString &xml, const QString &service, const QString &path)
380 {
381     QDBusXmlParser parser(service, path, xml);
382     QSharedDataPointer<QDBusIntrospection::Object> retval = parser.object();
383     if (!retval)
384         return QDBusIntrospection::Object();
385     return *retval;
386 }
387
388 /*!
389     Parses the XML document fragment (given by \a xml) containing one object node and returns all
390     the information about the interfaces and sub-objects, found at the service \a service and path
391     \a path.
392
393     The Objects map returned will contain the absolute path names in the key.
394 */
395 QDBusIntrospection::ObjectTree
396 QDBusIntrospection::parseObjectTree(const QString &xml, const QString &service, const QString &path)
397 {
398     QDBusXmlParser parser(service, path, xml);
399     QSharedDataPointer<QDBusIntrospection::ObjectTree> retval = parser.objectTree();
400     if (!retval)
401         return QDBusIntrospection::ObjectTree();
402     return *retval;
403 }