Commit 7fb6f77f authored by Volker Krause's avatar Volker Krause
Browse files

Prepare EFA parser for previous/next journey query support

parent 92ecfd08
Pipeline #75388 passed with stage
in 19 seconds
......@@ -8,7 +8,7 @@
</pa>
<pa>
<n>sessionID</n>
<v>0</v>
<v>123456789</v>
</pa>
</pas>
<msgs>
......
<?xml version="1.0" encoding="UTF-8"?>
<itdRequest version="10.3.9.39" language="de" lengthUnit="METER" sessionID="0" serverID="efa103.vgn.de" virtDir="vgnExt">
<itdRequest version="10.3.9.39" language="de" lengthUnit="METER" sessionID="123456789" serverID="efa103.vgn.de" virtDir="vgnExt">
<itdTripRequest requestID="0">
<itdItinerary>
<itdRouteList>
......
<?xml version="1.0" encoding="UTF-8"?>
<itdRequest language="de" lengthUnit="METER" sessionID="0" virtDir="vgnExt">
<itdRequest language="de" lengthUnit="METER" sessionID="123456789" virtDir="vgnExt">
<itdTripRequest requestID="0">
<itdMessage type="warning" module="BROKER" code="-10015" subType="itp-monomodal">itp</itdMessage>
<itdAddress name="" street="" place="" addressExt1="" addressExt2=""/>
......
<?xml version="1.0" encoding="UTF-8"?>
<itdRequest version="10.3.10.3" language="de" lengthUnit="METER">
<itdRequest version="10.3.10.3" language="de" lengthUnit="METER" sessionID="123456789">
<itdTripRequest requestID="0">
<itdItinerary>
<itdRouteList>
......
......@@ -204,6 +204,10 @@ private Q_SLOTS:
}
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.journeyQueryContext().isEmpty());
QCOMPARE(parser.journeyQueryContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.journeyQueryContext().requestId, QLatin1String("0"));
}
void testParseCompactTrips_data()
......@@ -234,6 +238,10 @@ private Q_SLOTS:
}
QVERIFY(!jsonRes.empty());
QCOMPARE(jsonRes, ref);
QVERIFY(!parser.journeyQueryContext().isEmpty());
QCOMPARE(parser.journeyQueryContext().sessionId, QLatin1String("123456789"));
QCOMPARE(parser.journeyQueryContext().requestId, QLatin1String("0"));
}
};
......
......@@ -79,7 +79,7 @@ Location EfaCompactParser::parseCompactSf(ScopedXmlStreamReader &&reader) const
return loc;
}
std::vector<Location> EfaCompactParser::parseStopFinderResponse(const QByteArray &data) const
std::vector<Location> EfaCompactParser::parseStopFinderResponse(const QByteArray &data)
{
std::vector<Location> res;
QXmlStreamReader xsr(data);
......@@ -190,7 +190,7 @@ Stopover EfaCompactParser::parseCompactDp(ScopedXmlStreamReader &&reader) const
return dep;
}
std::vector<Stopover> EfaCompactParser::parseDmResponse(const QByteArray &data) const
std::vector<Stopover> EfaCompactParser::parseDmResponse(const QByteArray &data)
{
std::vector<Stopover> res;
QXmlStreamReader xsr(data);
......@@ -401,14 +401,18 @@ Journey EfaCompactParser::parseCompactTp(ScopedXmlStreamReader &&reader) const
return jny;
}
std::vector<Journey> EfaCompactParser::parseTripResponse(const QByteArray &data) const
std::vector<Journey> EfaCompactParser::parseTripResponse(const QByteArray &data)
{
//qDebug().noquote() << data;
std::vector<Journey> res;
QXmlStreamReader xsr(data);
ScopedXmlStreamReader reader(xsr);
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("tp")) {
if (reader.name() == QLatin1String("pas")) {
const auto pas = parseKeyValueList(reader.subReader(), QLatin1String("pa"), QLatin1String("n"), QLatin1String("v"));
m_journeyContext.sessionId = pas.value(QLatin1String("sessionID"));
m_journeyContext.requestId = pas.value(QLatin1String("requestID"));
} else if (reader.name() == QLatin1String("tp")) {
res.push_back(parseCompactTp(reader.subReader()));
}
}
......
......@@ -19,9 +19,9 @@ class ScopedXmlStreamReader;
class KPUBLICTRANSPORT_EXPORT EfaCompactParser : public EfaParser
{
public:
std::vector<Location> parseStopFinderResponse(const QByteArray &data) const override;
std::vector<Stopover> parseDmResponse(const QByteArray &data) const override;
std::vector<Journey> parseTripResponse(const QByteArray &data) const override;
std::vector<Location> parseStopFinderResponse(const QByteArray &data) override;
std::vector<Stopover> parseDmResponse(const QByteArray &data) override;
std::vector<Journey> parseTripResponse(const QByteArray &data) override;
private:
Location parseCompactSf(ScopedXmlStreamReader &&reader) const;
......
......@@ -12,6 +12,12 @@
using namespace KPublicTransport;
bool EfaJourneyQueryContext::isEmpty()
{
return sessionId.isEmpty() || requestId.isEmpty() || sessionId == QLatin1String("0");
}
EfaParser::~EfaParser() = default;
void EfaParser::setLocationIdentifierType(const QString& locationIdentifierType)
......@@ -88,3 +94,28 @@ bool EfaParser::isDummyStopId(QStringView id)
{
return id == QLatin1String("99999997") || id == QLatin1String("99999998");
}
EfaJourneyQueryContext EfaParser::journeyQueryContext() const
{
return m_journeyContext;
}
QHash<QString, QString> EfaParser::parseKeyValueList(ScopedXmlStreamReader &&reader, QLatin1String elemName, QLatin1String keyName, QLatin1String valueName)
{
QHash<QString, QString> attrs;
while (reader.readNextSibling()) {
if (reader.name() == elemName) {
auto attrReader = reader.subReader();
QString name, value;
while (attrReader.readNextSibling()) {
if (attrReader.name() == keyName) {
name = attrReader.readElementText();
} else if (attrReader.name() == valueName) {
value = attrReader.readElementText();
}
}
attrs.insert(name, value);
}
}
return attrs;
}
......@@ -29,6 +29,18 @@ class Path;
class ScopedXmlStreamReader;
class Stopover;
/** Journey query context for previous/next queries.
* @internal only exported for unit tests
*/
class KPUBLICTRANSPORT_EXPORT EfaJourneyQueryContext
{
public:
QString sessionId;
QString requestId;
bool isEmpty();
};
/** Base class for parsers for responses from EFA services.
* @internal just exported for unit tests
*/
......@@ -42,9 +54,11 @@ public:
Reply::Error error() const;
QString errorMessage() const;
virtual std::vector<Location> parseStopFinderResponse(const QByteArray &data) const = 0;
virtual std::vector<Stopover> parseDmResponse(const QByteArray &data) const = 0;
virtual std::vector<Journey> parseTripResponse(const QByteArray &data) const = 0;
virtual std::vector<Location> parseStopFinderResponse(const QByteArray &data) = 0;
virtual std::vector<Stopover> parseDmResponse(const QByteArray &data) = 0;
virtual std::vector<Journey> parseTripResponse(const QByteArray &data) = 0;
EfaJourneyQueryContext journeyQueryContext() const;
protected:
/** convert "means of transport" type id to Line::Mode
......@@ -61,9 +75,13 @@ protected:
/** Returns @c true if the given stop id is a dummy value used for non-stops. */
static bool isDummyStopId(QStringView id);
/** Parses a key/value list structure. */
static QHash<QString, QString> parseKeyValueList(ScopedXmlStreamReader &&reader, QLatin1String elemName, QLatin1String keyName, QLatin1String valueName);
QString m_locationIdentifierType;
mutable QString m_errorMsg;
mutable Reply::Error m_error = Reply::NoError;
QString m_errorMsg;
Reply::Error m_error = Reply::NoError;
EfaJourneyQueryContext m_journeyContext;
};
}
......
......@@ -77,7 +77,7 @@ Location EfaXmlParser::parseOdvNameElem(ScopedXmlStreamReader &reader) const
return loc;
}
std::vector<Location> EfaXmlParser::parseStopFinderResponse(const QByteArray &data) const
std::vector<Location> EfaXmlParser::parseStopFinderResponse(const QByteArray &data)
{
std::vector<Location> res;
QXmlStreamReader xsr(data);
......@@ -176,7 +176,7 @@ Stopover EfaXmlParser::parseDmDeparture(ScopedXmlStreamReader &&reader) const
return dep;
}
std::vector<Stopover> EfaXmlParser::parseDmResponse(const QByteArray &data) const
std::vector<Stopover> EfaXmlParser::parseDmResponse(const QByteArray &data)
{
std::vector<Stopover> res;
QXmlStreamReader xsr(data);
......@@ -418,14 +418,18 @@ Journey EfaXmlParser::parseTripRoute(ScopedXmlStreamReader &&reader) const
return journey;
}
std::vector<Journey> EfaXmlParser::parseTripResponse(const QByteArray &data) const
std::vector<Journey> EfaXmlParser::parseTripResponse(const QByteArray &data)
{
//qDebug().noquote() << data;
std::vector<Journey> res;
QXmlStreamReader xsr(data);
ScopedXmlStreamReader reader(xsr);
while (reader.readNextElement()) {
if (reader.name() == QLatin1String("itdRoute")) {
if (reader.name() == QLatin1String("itdRequest")) {
m_journeyContext.sessionId = reader.attributes().value(QLatin1String("sessionID")).toString();
} else if (reader.name() == QLatin1String("itdTripRequest")) {
m_journeyContext.requestId = reader.attributes().value(QLatin1String("requestID")).toString();
} else if (reader.name() == QLatin1String("itdRoute")) {
res.push_back(parseTripRoute(reader.subReader()));
}
}
......@@ -541,20 +545,5 @@ Path EfaXmlParser::assemblePath(const std::vector<PathDescription> &descs, const
QHash<QString, QString> EfaXmlParser::parseGenericAttributeList(ScopedXmlStreamReader &&reader) const
{
QHash<QString, QString> attrs;
while (reader.readNextSibling()) {
if (reader.name() == QLatin1String("genAttrElem")) {
auto attrReader = reader.subReader();
QString name, value;
while (attrReader.readNextSibling()) {
if (attrReader.name() == QLatin1String("name")) {
name = attrReader.readElementText();
} else if (attrReader.name() == QLatin1String("value")) {
value = attrReader.readElementText();
}
}
attrs.insert(name, value);
}
}
return attrs;
return parseKeyValueList(std::move(reader), QLatin1String("genAttrElem"), QLatin1String("name"), QLatin1String("value"));
}
......@@ -25,9 +25,9 @@ class ScopedXmlStreamReader;
class KPUBLICTRANSPORT_EXPORT EfaXmlParser : public EfaParser
{
public:
std::vector<Location> parseStopFinderResponse(const QByteArray &data) const override;
std::vector<Stopover> parseDmResponse(const QByteArray &data) const override;
std::vector<Journey> parseTripResponse(const QByteArray &data) const override;
std::vector<Location> parseStopFinderResponse(const QByteArray &data) override;
std::vector<Stopover> parseDmResponse(const QByteArray &data) override;
std::vector<Journey> parseTripResponse(const QByteArray &data) override;
private:
void parseLocationCommon(Location &loc, const ScopedXmlStreamReader &reader) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment