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
#include "hdevicemodel_validator.h"
23
#include "hdevicemodel_validator_p.h"
24
#include "hdevicemodel_infoprovider.h"
26
#include "client/hclientaction.h"
27
#include "client/hclientdevice.h"
28
#include "client/hclientservice.h"
29
#include "client/hclientstatevariable.h"
31
#include "server/hserveraction.h"
32
#include "server/hserverdevice.h"
33
#include "server/hserverservice.h"
34
#include "server/hserverstatevariable.h"
36
#include "../dataelements/hactioninfo.h"
37
#include "../dataelements/hdeviceinfo.h"
38
#include "../dataelements/hserviceinfo.h"
39
#include "../dataelements/hstatevariableinfo.h"
41
#include "hactionarguments.h"
42
#include "hactions_setupdata.h"
43
#include "hdevices_setupdata.h"
44
#include "hservices_setupdata.h"
45
#include "hstatevariables_setupdata.h"
47
#include <QtCore/QSet>
55
/*******************************************************************************
56
* HDeviceModelValidatorPrivate
57
******************************************************************************/
58
HDeviceModelValidatorPrivate::HDeviceModelValidatorPrivate() :
59
m_lastErrorDescription(), m_infoProvider(0)
63
template<typename Device, typename Service, typename Action, typename StateVariable>
64
HDeviceModelValidator::ValidationResult
65
HDeviceModelValidatorPrivate::validateDevice(Device* device)
67
const HDeviceInfo& deviceInfo = device->info();
69
qint32 deviceVersion = deviceInfo.deviceType().version();
71
HServicesSetupData servicesSetupData =
72
m_infoProvider->servicesSetupData(deviceInfo);
74
foreach(const HServiceId& srvId, servicesSetupData.serviceIds())
76
HServiceSetup serviceSetup = servicesSetupData.get(srvId);
78
if (deviceVersion >= serviceSetup.version())
80
Service* service = device->serviceById(srvId);
83
if (serviceSetup.inclusionRequirement() == InclusionMandatory)
85
m_lastErrorDescription =
86
QString("Mandatory service [%1] is missing").arg(
89
return HDeviceModelValidator::MandatoryServiceMissing;
94
HDeviceModelValidator::ValidationResult res =
95
validateService<Service, Action, StateVariable>(service);
97
if (res != HDeviceModelValidator::ValidationSucceeded)
105
HDevicesSetupData embDevSetupData =
106
m_infoProvider->embedddedDevicesSetupData(deviceInfo);
108
foreach(const HResourceType& devType, embDevSetupData.deviceTypes())
110
HDeviceSetup deviceSetup = embDevSetupData.get(devType);
112
if (deviceVersion >= deviceSetup.version())
114
QList<Device*> devices = device->embeddedDevicesByType(devType);
115
if (devices.isEmpty() &&
116
deviceSetup.inclusionRequirement() == InclusionMandatory)
118
m_lastErrorDescription =
119
QString("Mandatory device [%1] is missing").arg(
122
return HDeviceModelValidator::MandatoryDeviceMissing;
125
foreach(Device* device, devices)
127
HDeviceModelValidator::ValidationResult res =
128
validateDevice<Device, Service, Action, StateVariable>(device);
130
if (res != HDeviceModelValidator::ValidationSucceeded)
138
return HDeviceModelValidator::ValidationSucceeded;
141
template<typename Service, typename Action, typename StateVariable>
142
HDeviceModelValidator::ValidationResult
143
HDeviceModelValidatorPrivate::validateService(Service* service)
145
const HServiceInfo& serviceInfo = service->info();
146
const HDeviceInfo& deviceInfo = service->parentDevice()->info();
148
qint32 serviceVersion = serviceInfo.serviceType().version();
150
HActionsSetupData actionSetupData =
151
m_infoProvider->actionsSetupData(serviceInfo, deviceInfo);
153
// All the action setup elements will be checked. If there exists an action,
154
// but the info provider does not return an action setup information of it,
155
// the action is considered valid.
157
foreach(const QString& actionName, actionSetupData.names())
159
HActionSetup actionSetup = actionSetupData.get(actionName);
161
if (serviceVersion >= actionSetup.version())
163
// Validate only if the version of the service is equal or greater
164
// to the version defined in the setup data. If the service version
165
// is smaller then the action was not defined in that version at all,
166
// but that is not an error. This only means that when interacting with
167
// this service version, this action should never be called.
169
// However, this version check is just an extra sanity check, since a
170
// properly functioning "info provider" should check the version of
171
// the provided service info and return information considering that.
173
const Action* action = service->actions().value(actionName);
177
if (actionSetup.inclusionRequirement() == InclusionMandatory)
179
m_lastErrorDescription =
180
QString("Mandatory action [%1] is missing").arg(
183
return HDeviceModelValidator::MandatoryActionMissing;
188
HDeviceModelValidator::ValidationResult res =
189
validateAction(action, actionSetup);
191
if (res != HDeviceModelValidator::ValidationSucceeded)
193
m_lastErrorDescription =
194
QString("Action [%1] failed validation: %2").arg(
195
actionName, m_lastErrorDescription);
203
HStateVariablesSetupData svData =
204
m_infoProvider->stateVariablesSetupData(serviceInfo, deviceInfo);
206
foreach(const QString& svName, svData.names())
208
HStateVariableInfo svInfo = svData.get(svName);
210
if (serviceVersion >= svInfo.version())
212
const StateVariable* stateVar =
213
service->stateVariables().value(svName);
217
if (svInfo.inclusionRequirement() == InclusionMandatory)
219
m_lastErrorDescription =
220
QString("Mandatory state variable [%1] is missing").arg(
223
return HDeviceModelValidator::MandatoryStateVariableMissing;
228
HDeviceModelValidator::ValidationResult res =
229
validateStateVariable(stateVar, svInfo);
231
if (res != HDeviceModelValidator::ValidationSucceeded)
233
m_lastErrorDescription =
234
QString("State Variable [%1] failed validation: %2").arg(
235
svName, m_lastErrorDescription);
243
return HDeviceModelValidator::ValidationSucceeded;
246
template<typename Action>
247
HDeviceModelValidator::ValidationResult
248
HDeviceModelValidatorPrivate::validateAction(
249
Action* action, const HActionSetup& actionSetup)
251
HActionArguments inArgs = action->info().inputArguments();
252
HActionArguments outArgs = action->info().outputArguments();
254
HActionArguments inArgsSetup = actionSetup.inputArguments();
255
HActionArguments outArgsSetup = actionSetup.outputArguments();
257
foreach(const QString& argName, inArgsSetup.names())
259
HActionArgument argSetup = inArgsSetup.get(argName);
260
HActionArgument arg = inArgs.get(argName);
264
m_lastErrorDescription =
265
QString("Mandatory action argument [%1] is missing").arg(
268
return HDeviceModelValidator::MandatoryActionArgumentMissing;
270
else if (arg.dataType() != argSetup.dataType())
272
m_lastErrorDescription =
273
QString("Invalid data type specified in action argument [%1]").arg(
276
return HDeviceModelValidator::InvalidArgumentDefinition;
280
foreach(const QString& argName, outArgsSetup.names())
282
HActionArgument argSetup = outArgsSetup.get(argName);
283
HActionArgument arg = outArgs.get(argName);
287
m_lastErrorDescription =
288
QString("Mandatory action argument [%1] is missing").arg(
291
return HDeviceModelValidator::MandatoryActionArgumentMissing;
293
else if (arg.dataType() != argSetup.dataType())
295
m_lastErrorDescription =
296
QString("Invalid data type specified in action argument [%1]").arg(
299
return HDeviceModelValidator::InvalidArgumentDefinition;
303
return HDeviceModelValidator::ValidationSucceeded;
306
template<typename Action>
307
HDeviceModelValidator::ValidationResult
308
HDeviceModelValidatorPrivate::validateAction(Action* action)
310
Q_ASSERT_X(action, "", "Null pointer provided");
312
const HServiceInfo& serviceInfo = action->parentService()->info();
313
const HDeviceInfo& deviceInfo =
314
action->parentService()->parentDevice()->info();
316
HActionsSetupData actionSetupData =
317
m_infoProvider->actionsSetupData(serviceInfo, deviceInfo);
319
HActionSetup actionSetup = actionSetupData.get(action->info().name());
321
return actionSetup.isValid() ?
322
validateAction(action, actionSetup) :
323
HDeviceModelValidator::ValidationSucceeded;
326
template<typename StateVariable>
327
HDeviceModelValidator::ValidationResult
328
HDeviceModelValidatorPrivate::validateStateVariable(
329
StateVariable* stateVar, const HStateVariableInfo& svInfo)
331
if (stateVar->info().dataType() != svInfo.dataType())
333
m_lastErrorDescription =
334
QString("Invalid data type specified. Was [%1], expected [%2].").arg(
335
HUpnpDataTypes::toString(stateVar->info().dataType()),
336
HUpnpDataTypes::toString(svInfo.dataType()));
338
return HDeviceModelValidator::InvalidStateVariableDefinition;
341
return HDeviceModelValidator::ValidationSucceeded;
344
template<typename StateVariable>
345
HDeviceModelValidator::ValidationResult
346
HDeviceModelValidatorPrivate::validateStateVariable(
347
StateVariable* stateVar)
349
Q_ASSERT_X(stateVar, "", "Null pointer provided");
351
const HServiceInfo& serviceInfo = stateVar->parentService()->info();
352
const HDeviceInfo& deviceInfo =
353
stateVar->parentService()->parentDevice()->info();
355
HStateVariablesSetupData svSetupData =
356
m_infoProvider->stateVariablesSetupData(serviceInfo, deviceInfo);
358
HStateVariableInfo svInfo = svSetupData.get(stateVar->info().name());
360
return svInfo.isValid() ?
361
validateStateVariable(stateVar, svInfo) :
362
HDeviceModelValidator::ValidationSucceeded;
365
/*******************************************************************************
366
* HDeviceModelValidator
367
******************************************************************************/
368
HDeviceModelValidator::HDeviceModelValidator() :
369
h_ptr(new HDeviceModelValidatorPrivate())
373
HDeviceModelValidator::~HDeviceModelValidator()
378
void HDeviceModelValidator::setInfoProvider(
379
const HDeviceModelInfoProvider& provider)
381
h_ptr->m_infoProvider.reset(provider.clone());
384
const HDeviceModelInfoProvider* HDeviceModelValidator::infoProvider() const
386
return h_ptr->m_infoProvider.data();
389
HDeviceModelValidator::ValidationResult
390
HDeviceModelValidator::validateDevice(HClientDevice* device)
394
return InfoProviderMissing;
397
return h_ptr->validateDevice<
398
HClientDevice, HClientService, HClientAction, HClientStateVariable>(device);
401
HDeviceModelValidator::ValidationResult
402
HDeviceModelValidator::validateDevice(HServerDevice* device)
406
return InfoProviderMissing;
409
return h_ptr->validateDevice<
410
HServerDevice, HServerService, HServerAction, HServerStateVariable>(device);
413
HDeviceModelValidator::ValidationResult
414
HDeviceModelValidator::validateService(HClientService* service)
418
return InfoProviderMissing;
421
return h_ptr->validateService<HClientService, HClientAction, HClientStateVariable>(service);
424
HDeviceModelValidator::ValidationResult
425
HDeviceModelValidator::validateService(HServerService* service)
429
return InfoProviderMissing;
432
return h_ptr->validateService<HServerService, HServerAction, HServerStateVariable>(service);
435
HDeviceModelValidator::ValidationResult
436
HDeviceModelValidator::validateAction(HClientAction* action)
440
return HDeviceModelValidator::InfoProviderMissing;
443
return h_ptr->validateAction(action);
446
HDeviceModelValidator::ValidationResult
447
HDeviceModelValidator::validateAction(HServerAction* action)
451
return HDeviceModelValidator::InfoProviderMissing;
454
return h_ptr->validateAction(action);
457
HDeviceModelValidator::ValidationResult
458
HDeviceModelValidator::validateStateVariable(HClientStateVariable* stateVar)
462
return HDeviceModelValidator::InfoProviderMissing;
465
return h_ptr->validateStateVariable(stateVar);
468
HDeviceModelValidator::ValidationResult
469
HDeviceModelValidator::validateStateVariable(HServerStateVariable* stateVar)
473
return HDeviceModelValidator::InfoProviderMissing;
476
return h_ptr->validateStateVariable(stateVar);
479
QString HDeviceModelValidator::lastErrorDescription() const
481
return h_ptr->m_lastErrorDescription;