This repository has been archived on 2026-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
2019-01-07 23:28:55 +01:00

246 lines
13 KiB
C++

#include "ruletemplates.h"
#include "ruletemplate.h"
#include "eventdescriptortemplate.h"
#include "ruleactiontemplate.h"
#include "stateevaluatortemplate.h"
#include "ruleactionparamtemplate.h"
#include "types/ruleactionparam.h"
#include "types/ruleactionparams.h"
#include <QDebug>
#include <QDir>
#include <QJsonDocument>
#include <QMetaEnum>
RuleTemplates::RuleTemplates(QObject *parent) : QAbstractListModel(parent)
{
RuleTemplate* t;
EventDescriptorTemplate* evt;
ParamDescriptor* evpt;
StateEvaluatorTemplate* set;
RuleActionTemplate* rat;
RuleActionTemplate* reat; // exit
RuleActionParamTemplate* rapt;
RuleActionParamTemplates* rapts;
QDir ruleTemplatesDir(":/ruletemplates");
foreach (const QString &templateFile, ruleTemplatesDir.entryList({"*.json"})) {
qDebug() << "Loading rule template:" << ruleTemplatesDir.absoluteFilePath(templateFile);
QFile f(ruleTemplatesDir.absoluteFilePath(templateFile));
if (!f.open(QFile::ReadOnly)) {
qWarning() << "Cannot open rule template file for reading:" << ruleTemplatesDir.absoluteFilePath(templateFile);
continue;
}
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(f.readAll(), &error);
f.close();
if (error.error != QJsonParseError::NoError) {
qWarning() << "Error reading rule template json from file:" << ruleTemplatesDir.absoluteFilePath(templateFile) << error.offset << error.errorString();
continue;
}
foreach (const QVariant &ruleTemplateVariant, jsonDoc.toVariant().toMap().value("templates").toList()) {
QVariantMap ruleTemplate = ruleTemplateVariant.toMap();
// RuleTemplate base
t = new RuleTemplate(ruleTemplate.value("interfaceName").toString(), ruleTemplate.value("description").toString(), ruleTemplate.value("ruleNameTemplate").toString(), this);
// EventDescriptorTemplate
foreach (const QVariant &eventDescriptorVariant, ruleTemplate.value("eventDescriptorTemplates").toList()) {
QVariantMap eventDescriptorTemplate = eventDescriptorVariant.toMap();
evt = new EventDescriptorTemplate(
eventDescriptorTemplate.value("interfaceName").toString(),
eventDescriptorTemplate.value("interfaceEvent").toString(),
eventDescriptorTemplate.value("selectionId").toInt(),
EventDescriptorTemplate::SelectionModeDevice);
foreach (const QVariant &eventDescriptorParamVariant, eventDescriptorTemplate.value("params").toList()) {
QVariantMap eventDescriptorParamTemplate = eventDescriptorParamVariant.toMap();
evpt = new ParamDescriptor();
evpt->setParamName(eventDescriptorParamTemplate.value("name").toString());
if (eventDescriptorParamTemplate.contains("value")) {
evpt->setValue(eventDescriptorParamTemplate.value("value"));
if (!eventDescriptorParamTemplate.contains("operator")) {
qWarning() << "BROKEN Template: Operator missing for event descriptor template" << qUtf8Printable(QJsonDocument::fromVariant(eventDescriptorParamTemplate).toJson(QJsonDocument::Indented));
} else {
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
evpt->setOperatorType(static_cast<ParamDescriptor::ValueOperator>(operatorEnum.keyToValue(eventDescriptorParamTemplate.value("operator").toByteArray().data())));
}
}
evt->paramDescriptors()->addParamDescriptor(evpt);
}
t->eventDescriptorTemplates()->addEventDescriptorTemplate(evt);
}
// StateEvaluatorTemplate
if (ruleTemplate.contains("stateEvaluatorTemplate")) {
QVariantMap stateEvaluatorTemplate = ruleTemplate.value("stateEvaluatorTemplate").toMap();
QVariantMap stateDescriptorTemplate = stateEvaluatorTemplate.value("stateDescriptorTemplate").toMap();
QMetaEnum selectionModeEnum = QMetaEnum::fromType<StateDescriptorTemplate::SelectionMode>();
QMetaEnum operatorEnum = QMetaEnum::fromType<StateDescriptorTemplate::ValueOperator>();
set = new StateEvaluatorTemplate(
new StateDescriptorTemplate(
stateDescriptorTemplate.value("interfaceName").toString(),
stateDescriptorTemplate.value("interfaceState").toString(),
stateDescriptorTemplate.value("selectionId").toInt(),
static_cast<StateDescriptorTemplate::SelectionMode>(selectionModeEnum.keyToValue(stateDescriptorTemplate.value("selectionMode", "SelectionModeAny").toByteArray().data())),
static_cast<StateDescriptorTemplate::ValueOperator>(operatorEnum.keyToValue(stateDescriptorTemplate.value("operator").toByteArray().data())),
stateDescriptorTemplate.value("value")));
t->setStateEvaluatorTemplate(set);
// TODO: Child evaluators not supported yet
}
// RuleActionTemplates
foreach (const QVariant &ruleActionVariant, ruleTemplate.value("ruleActionTemplates").toList()) {
QVariantMap ruleActionTemplate = ruleActionVariant.toMap();
rapts = new RuleActionParamTemplates();
foreach (const QVariant &ruleActionParamVariant, ruleActionTemplate.value("params").toList()) {
QVariantMap ruleActionParamTemplate = ruleActionParamVariant.toMap();
QString paramName = ruleActionParamTemplate.value("name").toString();
if (ruleActionParamTemplate.contains("value")) {
QVariant paramValue = ruleActionParamTemplate.value("value");
rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, paramValue));
} else if (ruleActionParamTemplate.contains("eventInterface") && ruleActionParamTemplate.contains("eventName") && ruleActionParamTemplate.contains("eventParamName")) {
QString eventInterface = ruleActionParamTemplate.value("eventInterface").toString();
QString eventName = ruleActionParamTemplate.value("eventName").toString();
QString eventParamName = ruleActionParamTemplate.value("eventParamName").toString();
rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, eventInterface, eventName, eventParamName));
} else {
qWarning() << "Invalid rule action param name on rule template:" << paramName;
}
}
QMetaEnum selectionModeEnum = QMetaEnum::fromType<RuleActionTemplate::SelectionMode>();
rat = new RuleActionTemplate(
ruleActionTemplate.value("interfaceName").toString(),
ruleActionTemplate.value("interfaceAction").toString(),
ruleActionTemplate.value("selectionId").toInt(),
static_cast<RuleActionTemplate::SelectionMode>(selectionModeEnum.keyToValue(ruleActionTemplate.value("selectionMode", "SelectionModeDevice").toByteArray().data())),
rapts);
t->ruleActionTemplates()->addRuleActionTemplate(rat);
}
// RuleExitActionTemplates
foreach (const QVariant &ruleActionVariant, ruleTemplate.value("ruleExitActionTemplates").toList()) {
QVariantMap ruleActionTemplate = ruleActionVariant.toMap();
rapts = new RuleActionParamTemplates();
foreach (const QVariant &ruleActionParamVariant, ruleActionTemplate.value("params").toList()) {
QVariantMap ruleActionParamTemplate = ruleActionParamVariant.toMap();
QString paramName = ruleActionParamTemplate.value("name").toString();
if (ruleActionParamTemplate.contains("value")) {
QVariant paramValue = ruleActionParamTemplate.value("value");
rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, paramValue));
} else if (ruleActionParamTemplate.contains("eventInterface") && ruleActionParamTemplate.contains("eventName") && ruleActionParamTemplate.contains("eventParamName")) {
QString eventInterface = ruleActionParamTemplate.value("eventInterface").toString();
QString eventName = ruleActionParamTemplate.value("eventName").toString();
QString eventParamName = ruleActionParamTemplate.value("eventParamName").toString();
rapts->addRuleActionParamTemplate(new RuleActionParamTemplate(paramName, eventInterface, eventName, eventParamName));
} else {
qWarning() << "Invalid rule exit action param name on rule template:" << paramName;
}
}
QMetaEnum selectionModeEnum = QMetaEnum::fromType<RuleActionTemplate::SelectionMode>();
rat = new RuleActionTemplate(
ruleActionTemplate.value("interfaceName").toString(),
ruleActionTemplate.value("interfaceAction").toString(),
ruleActionTemplate.value("selectionId").toInt(),
static_cast<RuleActionTemplate::SelectionMode>(selectionModeEnum.keyToValue(ruleActionTemplate.value("selectionMode", "SelectionModeDevice").toByteArray().data())),
rapts);
t->ruleExitActionTemplates()->addRuleActionTemplate(rat);
}
m_list.append(t);
}
// qDebug() << "Loaded" << m_list.count() << "rule templates";
}
}
int RuleTemplates::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_list.count();
}
QVariant RuleTemplates::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleDescription:
return m_list.at(index.row())->description();
}
return QVariant();
}
QHash<int, QByteArray> RuleTemplates::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleDescription, "description");
return roles;
}
RuleTemplate *RuleTemplates::get(int index) const
{
if (index < 0 || index >= m_list.count()) {
return nullptr;
}
return m_list.at(index);
}
bool RuleTemplatesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
if (!m_ruleTemplates) {
return false;
}
RuleTemplate *t = m_ruleTemplates->get(source_row);
// qDebug() << "Checking interface" << t->description() << t->interfaceName() << "for usage with:" << m_filterInterfaceNames;
if (!m_filterInterfaceNames.isEmpty()) {
if (!m_filterInterfaceNames.contains(t->interfaceName())) {
return false;
}
// bool found = false;
// for (int i = 0; i < t->eventDescriptorTemplates()->rowCount(); i++) {
// if (m_filterInterfaceNames.contains(t->eventDescriptorTemplates()->get(i)->interfaceName())) {
// found = true;
// break;
// }
// }
// if (!found && t->stateEvaluatorTemplate() && stateEvaluatorTemplateContainsInterface(t->stateEvaluatorTemplate(), m_filterInterfaceNames)) {
// found = true;
// }
// if (!found) {
// for (int i = 0; i < t->ruleActionTemplates()->rowCount(); i++) {
// if (m_filterInterfaceNames.contains(t->ruleActionTemplates()->get(i)->interfaceName())) {
// found = true;
// break;
// }
// }
// }
// if (!found) {
// for (int i = 0; i < t->ruleExitActionTemplates()->rowCount(); i++) {
// if (m_filterInterfaceNames.contains(t->ruleExitActionTemplates()->get(i)->interfaceName())) {
// found = true;
// break;
// }
// }
// }
// if (!found) {
// return false;
// }
}
return true;
}
bool RuleTemplatesFilterModel::stateEvaluatorTemplateContainsInterface(StateEvaluatorTemplate *stateEvaluatorTemplate, const QStringList &interfaceNames) const
{
if (interfaceNames.contains(stateEvaluatorTemplate->stateDescriptorTemplate()->interfaceName())) {
return true;
}
for (int i = 0; i < stateEvaluatorTemplate->childEvaluatorTemplates()->rowCount(); i++) {
if (stateEvaluatorTemplateContainsInterface(stateEvaluatorTemplate->childEvaluatorTemplates()->get(i), interfaceNames)) {
return true;
}
}
return false;
}