11#include <QtCore/QJsonDocument>
12#include <QtCore/QJsonArray>
13#include <QtCore/QRegularExpression>
14#include <QtCore/QRegularExpressionMatch>
20 :
CompInfo(COMP_METADATA_TYPE_PARAMETER, compId_, vehicle_, parent)
27 qCDebug(CompInfoParamLog) <<
"setJson: metadataJsonFileName" << metadataJsonFileName;
29 if (metadataJsonFileName.isEmpty()) {
36 QJsonDocument jsonDoc;
38 _noJsonMetadata =
false;
41 qCWarning(CompInfoParamLog) <<
"Metadata json file open failed: compid:" <<
compId <<
errorString;
44 QJsonObject jsonObj = jsonDoc.object();
46 QList<JsonHelper::KeyValidateInfo> keyInfoList = {
48 { _jsonParametersKey, QJsonValue::Array,
true },
51 qCWarning(CompInfoParamLog) <<
"Metadata json validation failed: compid:" <<
compId <<
errorString;
57 qCWarning(CompInfoParamLog) <<
"Metadata json unsupported version" << version;
61 QJsonArray rgParameters = jsonObj[_jsonParametersKey].toArray();
62 for (QJsonValue parameterValue: rgParameters) {
63 QMap<QString, QString> emptyDefineMap;
65 if (!parameterValue.isObject()) {
66 qCWarning(CompInfoParamLog) <<
"Metadata json read failed: compid:" <<
compId <<
"parameters array contains non-object";
72 if (newMetaData->
name().contains(_indexedNameTag)) {
73 _indexedNameMetaDataList.append(RegexFactMetaDataPair_t(newMetaData->
name(), newMetaData));
75 _nameToMetaDataMap[newMetaData->
name()] = newMetaData;
84 if (_noJsonMetadata) {
85 QObject* opaqueMetaData = _getOpaqueParameterMetaData();
92 if (_nameToMetaDataMap.contains(name)) {
93 factMetaData = _nameToMetaDataMap[name];
96 for (
int i=0; i<_indexedNameMetaDataList.count(); i++) {
97 const RegexFactMetaDataPair_t& pair = _indexedNameMetaDataList[i];
99 QString indexedName = pair.first;
100 const QString indexedRegex(
"(\\d+)");
101 indexedName.replace(_indexedNameTag, indexedRegex);
103 const QRegularExpression regex(indexedName);
104 const QRegularExpressionMatch match = regex.match(name);
106 const QStringList captured = match.capturedTexts();
107 if (captured.count() == 2) {
112 shortDescription.replace(_indexedNameTag, captured[1]);
115 longDescription.replace(_indexedNameTag, captured[1]);
122 int i = name.indexOf(
"_");
124 factMetaData->
setGroup(name.left(i));
126 if (
compId != MAV_COMP_ID_AUTOPILOT1) {
130 _nameToMetaDataMap[name] = factMetaData;
137FirmwarePlugin* CompInfoParam::_anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT firmwareType)
141 MAV_TYPE anySupportedVehicleType;
142 if (!supportedClasses.isEmpty()) {
145 anySupportedVehicleType = MAV_TYPE_GENERIC;
150QString CompInfoParam::_parameterMetaDataFile(
Vehicle* vehicle, MAV_AUTOPILOT firmwareType,
int& majorVersion,
int& minorVersion)
152 bool cacheHit =
false;
153 int wantedMajorVersion = 1;
154 FirmwarePlugin* fwPlugin = _anyVehicleTypeFirmwarePlugin(firmwareType);
156 if (firmwareType != MAV_AUTOPILOT_PX4) {
161 QDir cacheDir = QFileInfo(settings.fileName()).dir();
164 int cacheMinorVersion = 0;
165 int cacheMajorVersion = 0;
166 QFile cacheFile(cacheDir.filePath(QString(
"%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType).arg(wantedMajorVersion)));
167 if (cacheFile.exists()) {
169 if (wantedMajorVersion != cacheMajorVersion) {
170 qWarning() <<
"Parameter meta data cache corruption:" << cacheFile.fileName() <<
"major version does not match file name" <<
"actual:excepted" << cacheMajorVersion << wantedMajorVersion;
172 qCDebug(CompInfoParamLog) <<
"Direct cache hit on file:major:minor" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion;
179 const QString wildcard = QString(
"%1.%2.*.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType);
180 const QStringList cacheHits = cacheDir.entryList(QStringList(wildcard), QDir::Files, QDir::Name);
183 int cacheHitIndex = -1;
184 cacheMajorVersion = -1;
186 const QString pattern = QString(
"%1\\.%2\\.(\\d*)\\.xml").arg(_cachedMetaDataFilePrefix).arg(firmwareType);
187 const QRegularExpression regex(pattern);
188 for (
int i = 0; i < cacheHits.count(); i++) {
189 const QRegularExpressionMatch match = regex.match(cacheHits[i]);
190 if (match.hasMatch() && match.lastCapturedIndex() == 0) {
191 const int matchedMajorVersion = match.captured(1).toInt();
192 if ((matchedMajorVersion > cacheMajorVersion) && (matchedMajorVersion < wantedMajorVersion)) {
193 cacheMajorVersion = matchedMajorVersion;
199 if (cacheHitIndex != -1) {
201 int cacheFileMajorVersion;
202 cacheFile.setFileName(cacheDir.filePath(cacheHits[cacheHitIndex]));
204 if (cacheFileMajorVersion != cacheMajorVersion) {
205 qWarning() <<
"Parameter meta data cache corruption:" << cacheFile.fileName() <<
"major version does not match file name" <<
"actual:excepted" << cacheFileMajorVersion << cacheMajorVersion;
208 qCDebug(CompInfoParamLog) <<
"Indirect cache hit on file:major:minor:want" << cacheFile.fileName() << cacheMajorVersion << cacheMinorVersion << wantedMajorVersion;
214 int internalMinorVersion, internalMajorVersion;
217 qCDebug(CompInfoParamLog) <<
"Internal metadata file:major:minor" << internalMetaDataFile << internalMajorVersion << internalMinorVersion;
220 if (internalMajorVersion == wantedMajorVersion) {
221 if (cacheMajorVersion == wantedMajorVersion) {
223 cacheHit = cacheMinorVersion > internalMinorVersion;
229 if (cacheMajorVersion == wantedMajorVersion) {
239 QString metaDataFile;
240 if (cacheHit && !
qgcApp()->runningUnitTests()) {
241 majorVersion = cacheMajorVersion;
242 minorVersion = cacheMinorVersion;
243 metaDataFile = cacheFile.fileName();
245 majorVersion = internalMajorVersion;
246 minorVersion = internalMinorVersion;
247 metaDataFile = internalMetaDataFile;
249 qCDebug(CompInfoParamLog) <<
"_parameterMetaDataFile returning file:major:minor" << metaDataFile << majorVersion << minorVersion;
257 FirmwarePlugin* plugin = _anyVehicleTypeFirmwarePlugin(MAV_AUTOPILOT_PX4);
259 int newMajorVersion, newMinorVersion;
261 if (newMajorVersion != 1) {
263 qgcApp()->showAppMessage(tr(
"Internal Error: Parameter MetaData major must be 1"));
265 qCDebug(CompInfoParamLog) <<
"ParameterManager::cacheMetaDataFile file:major;minor" << metaDataFile << newMajorVersion << newMinorVersion;
268 int cacheMajorVersion, cacheMinorVersion;
269 QString cacheHit = _parameterMetaDataFile(
nullptr, MAV_AUTOPILOT_PX4, cacheMajorVersion, cacheMinorVersion);
270 qCDebug(CompInfoParamLog) <<
"ParameterManager::cacheMetaDataFile cacheHit file:firmware:major;minor" << cacheHit << cacheMajorVersion << cacheMinorVersion;
272 bool cacheNewFile =
false;
273 if (cacheHit.isEmpty()) {
276 }
else if (cacheMajorVersion == newMajorVersion) {
280 if (newMinorVersion >= cacheMinorVersion) {
282 QFile::remove(cacheHit);
293 QDir cacheDir = QFileInfo(settings.fileName()).dir();
294 QFile cacheFile(cacheDir.filePath(QString(
"%1.%2.%3.xml").arg(_cachedMetaDataFilePrefix).arg(MAV_AUTOPILOT_PX4).arg(newMajorVersion)));
295 qCDebug(CompInfoParamLog) <<
"ParameterManager::cacheMetaDataFile caching file:" << cacheFile.fileName();
296 QFile newFile(metaDataFile);
297 newFile.copy(cacheFile.fileName());
301QObject* CompInfoParam::_getOpaqueParameterMetaData(
void)
303 if (!_noJsonMetadata) {
304 qWarning() <<
"CompInfoParam::_getOpaqueParameterMetaData _noJsonMetadata == false";
307 if (!_opaqueParameterMetaData &&
compId == MAV_COMP_ID_AUTOPILOT1) {
309 int majorVersion, minorVersion;
311 qCDebug(CompInfoParamLog) <<
"Loading meta data the old way file" << metaDataFile;
315 return _opaqueParameterMetaData;
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void setJson(const QString &metadataJsonFileName) override
static void _cachePX4MetaDataFile(const QString &metaDataFile)
FactMetaData * factMetaDataForName(const QString &name, FactMetaData::ValueType_t valueType)
Base class for all CompInfo types.
FirmwarePlugin * firmwarePluginForAutopilot(MAV_AUTOPILOT firmwareType, MAV_TYPE vehicleType)
QList< QGCMAVLink::VehicleClass_t > supportedVehicleClasses(QGCMAVLink::FirmwareClass_t firmwareClass)
Returns the list of supported vehicle types for the specified firmware.
static FirmwarePluginManager * instance()
virtual QString _internalParameterMetaDataFile(const Vehicle *) const
virtual FactMetaData * _getMetaDataForFact(QObject *, const QString &, FactMetaData::ValueType_t, MAV_TYPE) const
virtual void _getParameterMetaDataVersionInfo(const QString &metaDataFile, int &majorVersion, int &minorVersion) const
virtual QObject * _loadParameterMetaData(const QString &)
static MAV_TYPE vehicleClassToMavType(VehicleClass_t vehicleClass)
static FirmwareClass_t firmwareClass(MAV_AUTOPILOT autopilot)
MAV_TYPE vehicleType() const
FirmwarePlugin * firmwarePlugin()
Provides access to the Firmware Plugin for this Vehicle.
MAV_AUTOPILOT firmwareType() const
constexpr const char * jsonVersionKey
bool validateKeys(const QJsonObject &jsonObject, const QList< KeyValidateInfo > &keyInfo, QString &errorString)
bool isJsonFile(const QByteArray &bytes, QJsonDocument &jsonDoc, QString &errorString)
Determines whether an in-memory byte buffer contains parseable JSON content.