forked from qt-creator/qt-creator
Android: Make SDK package parsing logic generic
Task-number: QTCREATORBUG-18978 Change-Id: I7e643842d6378a172fcfe5984cec931621ff9c41 Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
@@ -131,6 +131,17 @@ private:
|
|||||||
*/
|
*/
|
||||||
class SdkManagerOutputParser
|
class SdkManagerOutputParser
|
||||||
{
|
{
|
||||||
|
class GenericPackageData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool isValid() const { return !revision.isNull() && !description.isNull(); }
|
||||||
|
QStringList headerParts;
|
||||||
|
QVersionNumber revision;
|
||||||
|
QString description;
|
||||||
|
Utils::FileName installedLocation;
|
||||||
|
QMap<QString, QString> extraData;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum MarkerTag
|
enum MarkerTag
|
||||||
{
|
{
|
||||||
@@ -152,6 +163,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void compilePackageAssociations();
|
void compilePackageAssociations();
|
||||||
void parsePackageData(MarkerTag packageMarker, const QStringList &data);
|
void parsePackageData(MarkerTag packageMarker, const QStringList &data);
|
||||||
|
bool parseAbstractData(GenericPackageData &output, const QStringList &input, int minParts,
|
||||||
|
const QString &logStrTag, QStringList extraKeys = QStringList()) const;
|
||||||
AndroidSdkPackage *parsePlatform(const QStringList &data) const;
|
AndroidSdkPackage *parsePlatform(const QStringList &data) const;
|
||||||
QPair<SystemImage *, int> parseSystemImage(const QStringList &data) const;
|
QPair<SystemImage *, int> parseSystemImage(const QStringList &data) const;
|
||||||
MarkerTag parseMarkers(const QString &line);
|
MarkerTag parseMarkers(const QString &line);
|
||||||
@@ -319,11 +332,15 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt
|
|||||||
return; // For now, only interested in installed packages.
|
return; // For now, only interested in installed packages.
|
||||||
|
|
||||||
AndroidSdkPackage *package = nullptr;
|
AndroidSdkPackage *package = nullptr;
|
||||||
|
auto createPackage = [&](std::function<AndroidSdkPackage *(SdkManagerOutputParser *,
|
||||||
|
const QStringList &)> creator) {
|
||||||
|
if ((package = creator(this, data)))
|
||||||
|
m_packages.append(package);
|
||||||
|
};
|
||||||
|
|
||||||
switch (packageMarker) {
|
switch (packageMarker) {
|
||||||
case MarkerTag::PlatformMarker:
|
case MarkerTag::PlatformMarker:
|
||||||
package = parsePlatform(data);
|
createPackage(&SdkManagerOutputParser::parsePlatform);
|
||||||
if (package)
|
|
||||||
m_packages.append(package);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MarkerTag::SystemImageMarker:
|
case MarkerTag::SystemImageMarker:
|
||||||
@@ -332,8 +349,6 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt
|
|||||||
if (result.first) {
|
if (result.first) {
|
||||||
m_systemImages[result.first] = result.second;
|
m_systemImages[result.first] = result.second;
|
||||||
package = result.first;
|
package = result.first;
|
||||||
} else {
|
|
||||||
qCDebug(sdkManagerLog) << "System Image: Parsing failed: " << data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -359,99 +374,81 @@ void SdkManagerOutputParser::parsePackageData(MarkerTag packageMarker, const QSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SdkManagerOutputParser::parseAbstractData(SdkManagerOutputParser::GenericPackageData &output,
|
||||||
|
const QStringList &input, int minParts,
|
||||||
|
const QString &logStrTag,
|
||||||
|
QStringList extraKeys) const
|
||||||
|
{
|
||||||
|
if (input.isEmpty()) {
|
||||||
|
qCDebug(sdkManagerLog) << logStrTag + ": Empty input";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.headerParts = input.at(0).split(';');
|
||||||
|
if (output.headerParts.count() < minParts) {
|
||||||
|
qCDebug(sdkManagerLog) << logStrTag + "%1: Unexpected header:" << input;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
extraKeys << installLocationKey << revisionKey << descriptionKey;
|
||||||
|
foreach (QString line, input) {
|
||||||
|
QString value;
|
||||||
|
for (auto key: extraKeys) {
|
||||||
|
if (valueForKey(key, line, &value)) {
|
||||||
|
if (key == installLocationKey)
|
||||||
|
output.installedLocation = Utils::FileName::fromString(value);
|
||||||
|
else if (key == revisionKey)
|
||||||
|
output.revision = QVersionNumber::fromString(value);
|
||||||
|
else if (key == descriptionKey)
|
||||||
|
output.description = value;
|
||||||
|
else
|
||||||
|
output.extraData[key] = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
AndroidSdkPackage *SdkManagerOutputParser::parsePlatform(const QStringList &data) const
|
AndroidSdkPackage *SdkManagerOutputParser::parsePlatform(const QStringList &data) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!data.isEmpty(), qCDebug(sdkManagerLog) << "Platform: Empty input"; return nullptr);
|
|
||||||
|
|
||||||
QStringList parts = data.at(0).split(';');
|
|
||||||
QTC_ASSERT(parts.count() >= 2,
|
|
||||||
qCDebug(sdkManagerLog) << "Platform: Unexpected header:"<< data; return nullptr);
|
|
||||||
|
|
||||||
int apiLevel = platformNameToApiLevel(parts.at(1));
|
|
||||||
if (apiLevel == -1) {
|
|
||||||
qCDebug(sdkManagerLog) << "Platform: Can not parse api level:"<< data;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVersionNumber revision;
|
|
||||||
QString description;
|
|
||||||
Utils::FileName installedLocation;
|
|
||||||
foreach (QString line, data) {
|
|
||||||
QString value;
|
|
||||||
if (valueForKey(installLocationKey, line, &value)) {
|
|
||||||
installedLocation = Utils::FileName::fromString(value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueForKey(revisionKey, line, &value)) {
|
|
||||||
revision = QVersionNumber::fromString(value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueForKey(descriptionKey, line, &value)) {
|
|
||||||
description = value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SdkPlatform *platform = nullptr;
|
SdkPlatform *platform = nullptr;
|
||||||
if (!revision.isNull() && apiLevel != -1) {
|
GenericPackageData packageData;
|
||||||
platform = new SdkPlatform(revision, data.at(0), apiLevel);
|
if (parseAbstractData(packageData, data, 2, "Platform")) {
|
||||||
platform->setDescriptionText(description);
|
int apiLevel = platformNameToApiLevel(packageData.headerParts.at(1));
|
||||||
platform->setInstalledLocation(installedLocation);
|
if (apiLevel == -1) {
|
||||||
|
qCDebug(sdkManagerLog) << "Platform: Can not parse api level:"<< data;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
platform = new SdkPlatform(packageData.revision, data.at(0), apiLevel);
|
||||||
|
platform->setDescriptionText(packageData.description);
|
||||||
|
platform->setInstalledLocation(packageData.installedLocation);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(sdkManagerLog) << "Platform: Parsing failed. Minimum required data unavailable:"
|
qCDebug(sdkManagerLog) << "Platform: Parsing failed. Minimum required data unavailable:"
|
||||||
<< data;
|
<< data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return platform;
|
return platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<SystemImage *, int> SdkManagerOutputParser::parseSystemImage(const QStringList &data) const
|
QPair<SystemImage *, int> SdkManagerOutputParser::parseSystemImage(const QStringList &data) const
|
||||||
{
|
{
|
||||||
QPair <SystemImage *, int> result(nullptr, -1);
|
QPair <SystemImage *, int> result(nullptr, -1);
|
||||||
QTC_ASSERT(!data.isEmpty(),
|
GenericPackageData packageData;
|
||||||
qCDebug(sdkManagerLog) << "System Image: Empty input"; return result);
|
if (parseAbstractData(packageData, data, 4, "System-image")) {
|
||||||
|
int apiLevel = platformNameToApiLevel(packageData.headerParts.at(1));
|
||||||
QStringList parts = data.at(0).split(';');
|
if (apiLevel == -1) {
|
||||||
QTC_ASSERT(parts.count() >= 4,
|
qCDebug(sdkManagerLog) << "System-image: Can not parse api level:"<< data;
|
||||||
qCDebug(sdkManagerLog) << "System Image: Unexpected header:" << data; return result);
|
return result;
|
||||||
|
|
||||||
int apiLevel = platformNameToApiLevel(parts.at(1));
|
|
||||||
if (apiLevel == -1) {
|
|
||||||
qCDebug(sdkManagerLog) << "System Image: Can not parse api level:"<< data;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVersionNumber revision;
|
|
||||||
QString description;
|
|
||||||
Utils::FileName installedLocation;
|
|
||||||
foreach (QString line, data) {
|
|
||||||
QString value;
|
|
||||||
if (valueForKey(installLocationKey, line, &value)) {
|
|
||||||
installedLocation = Utils::FileName::fromString(value);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
auto image = new SystemImage(packageData.revision, data.at(0),
|
||||||
if (valueForKey(revisionKey, line, &value)) {
|
packageData.headerParts.at(3));
|
||||||
revision = QVersionNumber::fromString(value);
|
image->setInstalledLocation(packageData.installedLocation);
|
||||||
continue;
|
image->setDisplayText(packageData.description);
|
||||||
}
|
image->setDescriptionText(packageData.description);
|
||||||
|
|
||||||
if (valueForKey(descriptionKey, line, &value)) {
|
|
||||||
description = value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!revision.isNull()) {
|
|
||||||
auto image = new SystemImage(revision, data.at(0), parts.at(3));
|
|
||||||
image->setInstalledLocation(installedLocation);
|
|
||||||
image->setDisplayText(description);
|
|
||||||
image->setDescriptionText(description);
|
|
||||||
result = qMakePair(image, apiLevel);
|
result = qMakePair(image, apiLevel);
|
||||||
} else {
|
} else {
|
||||||
qCDebug(sdkManagerLog) << "System Image: Can not parse: "<< data;
|
qCDebug(sdkManagerLog) << "System-image: Minimum required data unavailable: "<< data;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user