2
* Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved.
4
* Author: Tuomo Penttinen <tp@herqq.org>
6
* This file is part of Herqq UPnP (HUPnP) library.
8
* Herqq UPnP is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU Lesser General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
13
* Herqq UPnP 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 Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public License
19
* along with Herqq UPnP. If not, see <http://www.gnu.org/licenses/>.
22
#ifndef HDDOC_PARSER_P_H_
23
#define HDDOC_PARSER_P_H_
28
// This file is not part of public API and it should
29
// never be included in client code. The contents of this file may
30
// change or the file may be removed without of notice.
33
#include "../general/hupnp_defs.h"
34
#include "../general/hupnp_fwd.h"
35
#include "../general/hupnp_global.h"
36
#include "../dataelements/hserviceid.h"
37
#include "../dataelements/hactioninfo.h"
38
#include "../dataelements/hserviceinfo.h"
39
#include "../dataelements/hstatevariableinfo.h"
41
#include "../devicemodel/hactionarguments.h"
42
#include "../devicemodel/hactions_setupdata.h"
44
#include <QtCore/QUrl>
45
#include <QtCore/QSet>
46
#include <QtCore/QList>
47
#include <QtCore/QString>
61
enum DocumentErrorTypes
64
InvalidDeviceDescriptionError,
65
InvalidServiceDescriptionError
69
// The class that creates the HUPnP's device model from description files
73
H_DISABLE_COPY(HDocParser)
77
QList<QUrl> parseIconList(
78
const QDomElement& iconListElement);
80
bool parseActionArguments(
81
const QDomElement& argListElement,
82
const QHash<QString, HStateVariableInfo>&,
83
QVector<HActionArgument>* inArgs,
84
QVector<HActionArgument>* outArgs,
87
HStateVariableInfo parseStateVariableInfo_str(
89
const QVariant& defValue,
90
const QDomElement& svElement,
91
HStateVariableInfo::EventingType,
92
HInclusionRequirement);
94
HStateVariableInfo parseStateVariableInfo_numeric(
96
const QVariant& defValue,
97
const QDomElement& svElement,
98
HStateVariableInfo::EventingType,
99
HInclusionRequirement,
100
HUpnpDataTypes::DataType dataTypeEnumValue);
104
const QByteArray m_loggingIdentifier;
105
HValidityCheckLevel m_cLevel;
106
QString m_lastErrorDescription;
107
DocumentErrorTypes m_lastError;
111
HDocParser(const QByteArray& loggingIdentifier, HValidityCheckLevel);
113
inline QString lastErrorDescription() const { return m_lastErrorDescription; }
114
inline DocumentErrorTypes lastError() const { return m_lastError; }
116
bool parseRoot(const QString& doc, QDomDocument*, QDomElement*);
117
qint32 readConfigId(const QDomElement&);
118
bool parseDeviceInfo(const QDomElement&, HDeviceInfo*);
119
bool parseServiceInfo(const QDomElement& serviceDefinition, HServiceInfo*);
121
bool parseServiceDescription(
122
const QString& docStr,
124
QDomElement* stateVarElement,
125
QDomElement* actionElement);
127
bool parseStateVariable(
128
const QDomElement& stateVariableElement,
129
HStateVariableInfo*);
131
bool parseActionInfo(
132
const QDomElement& actionElement,
133
const QHash<QString, HStateVariableInfo>&,
136
bool verifySpecVersion(const QDomElement&, QString* err = 0);
142
class HDeviceValidator
146
QString m_lastErrorDescription;
147
DocumentErrorTypes m_lastError;
151
inline QString lastErrorDescription() const { return m_lastErrorDescription; }
152
inline DocumentErrorTypes lastError() const { return m_lastError; }
154
template<typename Device, typename Service>
155
bool validateRootDevice(Device* device)
157
class DeviceValidator
161
QSet<QString> eventUrls;
162
QSet<QString> controlUrls;
163
QSet<QString> scpdUrls;
164
QSet<QString> iconUrls;
165
QSet<HServiceId> serviceIds;
169
QString m_lastErrorDescription;
170
DocumentErrorTypes m_lastError;
172
bool validateIcons(Device* device)
174
QList<QUrl> icons = device->info().icons();
176
for (qint32 i = 0; i < icons.size(); ++i)
178
QString iconUrl = icons.at(i).toString();
180
if (iconUrls.contains(iconUrl))
182
m_lastError = InvalidDeviceDescriptionError;
183
m_lastErrorDescription = QString(
184
"Multiple icons have the same URL [%1] within a device tree. "
185
"Icon URLs MUST be unique within a device tree.").arg(
192
iconUrls.insert(iconUrl);
199
bool validateService(Service* service)
201
const HServiceId& serviceId = service->info().serviceId();
203
if (serviceIds.contains(serviceId))
205
m_lastError = InvalidDeviceDescriptionError;
206
m_lastErrorDescription = QString(
207
"ServiceId [%1] encountered more than once. "
208
"ServiceIDs MUST be unique within a device tree.").arg(
209
serviceId.toString());
215
serviceIds.insert(serviceId);
218
QString eventUrl = service->info().eventSubUrl().toString();
219
if (!eventUrl.isEmpty())
221
if (eventUrls.contains(eventUrl))
223
m_lastError = InvalidDeviceDescriptionError;
224
m_lastErrorDescription = QString(
225
"EventSubUrl [%1] encountered more than once."
226
"EventSubUrls MUST be unique within a device tree.").arg(eventUrl);
232
eventUrls.insert(eventUrl);
236
QString scpdUrl = service->info().scpdUrl().toString();
237
if (scpdUrls.contains(scpdUrl))
239
m_lastError = InvalidDeviceDescriptionError;
240
m_lastErrorDescription = QString(
241
"ScpdUrl [%1] encountered more than once."
242
"ScpdUrls MUST be unique within a device tree.").arg(eventUrl);
248
scpdUrls.insert(eventUrl);
251
QString controlUrl = service->info().controlUrl().toString();
252
if (controlUrls.contains(controlUrl))
254
m_lastError = InvalidDeviceDescriptionError;
255
m_lastErrorDescription = QString(
256
"ControlUrl [%1] encountered more than once. "
257
"ControlUrls MUST be unique within a device tree.").arg(controlUrl);
263
controlUrls.insert(controlUrl);
269
bool validateDevice(Device* device)
271
if (!validateIcons(device))
276
QList<Service*> services = device->services();
277
for(qint32 i = 0; i < services.size(); ++i)
279
Service* service = services[i];
280
if (!validateService(service))
286
QList<Device*> devices = device->embeddedDevices();
287
for(qint32 i = 0; i < devices.size(); ++i)
289
if (!validateDevice(devices[i]))
299
DeviceValidator validator;
300
if (!validator.validateDevice(device))
302
m_lastError = validator.m_lastError;
303
m_lastErrorDescription = validator.m_lastErrorDescription;
310
bool validate(const HStateVariableInfo& setupInfo,
311
const HStateVariableInfo&)
313
if (!setupInfo.isValid())
315
// The setup information was not defined, which means that no
316
// further validation should be run.
323
bool validate(const HActionSetup& setupInfo, const HActionInfo& createdInfo)
325
if (!setupInfo.isValid())
327
// The setup information was not defined, which means that no
328
// further validation should be run.
334
// the setup info does not necessarily contain information about the
335
// action arguments, which is fine and it just means that the arguments
336
// should not be validated.
338
if (!setupInfo.inputArguments().isEmpty())
340
b = setupInfo.inputArguments() != createdInfo.inputArguments();
345
m_lastError = InvalidServiceDescriptionError;
346
m_lastErrorDescription =
347
"Invalid input arguments provided. Remember to check the "
348
"order in which they are defined.";
353
if (!setupInfo.outputArguments().isEmpty())
355
b = setupInfo.outputArguments() != createdInfo.outputArguments();
360
m_lastError = InvalidServiceDescriptionError;
361
m_lastErrorDescription =
362
"Invalid output arguments provided. Remember to check the "
363
"order in which they are defined.";
373
#endif /* HDDOC_PARSER_P_H_ */