#include "serialListReader.h" #include <iostream> #include <limits> #include <stdexcept> #include <unistd.h> #include <QtXml/QDomDocument> #include <QtXml/QDomNode> #include <QtXml/QDomNodeList> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply> #include <QtCore/QUrl> #include <QtNetwork/QNetworkAccessManager> serialListReader::serialListReader( bool debug ) : networkManager ( new QNetworkAccessManager ( this ) ) { _debug = debug; getAndProcessData(); } void serialListReader::getAndProcessData() { try { getApdListFromNetwork(); verifyHttpResponse(); getDataFromReply(); verifyDataFormat(); verifyQuerySuccess(); getApdNodeList(); readyToReadData = true; } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; readyToReadData = false; } } void serialListReader::getApdListFromNetwork() { if ( _debug ) std::cout << "Initiating network request to " << fullApdListApiUrl << std::endl; replyWithFullList = networkManager->get ( QNetworkRequest ( QUrl ( fullApdListApiUrl.c_str() ) ) ); connect ( replyWithFullList, SIGNAL ( finished() ), &_waitForNetwork, SLOT ( quit() ) ); _waitForNetwork.exec(); if ( _debug ) std::cout << "Done, received reply." << std::endl; } void serialListReader::verifyHttpResponse() { if ( replyWithFullList->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() != 200 ) { const QString exceptionMsg = QString::fromUtf8 ( "HTTP error while invoking Production DB Web API: The server returned HTTP status code %1." ).arg ( replyWithFullList->attribute ( QNetworkRequest::HttpStatusCodeAttribute ).toInt() ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void serialListReader::getDataFromReply() { QString errorMsg; int errorLine; int errorColumn; documentFromNetworkReply = new QDomDocument(); if ( _debug ) std::cout << "Setting content of network reply to QDomDocument, verifying response..." << std::endl; if ( !documentFromNetworkReply->setContent ( replyWithFullList, &errorMsg, &errorLine, &errorColumn ) ) { const QString exceptionMsg = QString::fromUtf8 ( "Error in parsing data" ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void serialListReader::verifyDataFormat() { if ( documentFromNetworkReply->documentElement().nodeName() != QString::fromUtf8 ( "productiondb" ) || documentFromNetworkReply->documentElement().firstChild().nodeName() != QString::fromUtf8 ( "request" ) ) throw std::runtime_error ( "APD data has invalid format." ); QDomNode requestResult = documentFromNetworkReply->documentElement().firstChild(); if ( !requestResult.attributes().contains ( QString::fromUtf8 ( "successful" ) ) || !requestResult.attributes().contains ( QString::fromUtf8 ( "error_number" ) ) ) throw std::runtime_error ( "APD data has invalid format." ); } void serialListReader::verifyQuerySuccess() { QDomNode requestResult = documentFromNetworkReply->documentElement().firstChild(); if ( requestResult.attributes().namedItem ( QString::fromUtf8 ( "successful" ) ).nodeValue() != QString::fromUtf8 ( "true" ) ) { const QString exceptionMsg = QString::fromUtf8 ( "Server reports error %1 when querying data" ); throw std::runtime_error ( exceptionMsg.toUtf8().constData() ); } } void serialListReader::getApdNodeList() { nodeListApds = new QDomNodeList( documentFromNetworkReply->documentElement().elementsByTagName ( QString::fromUtf8 ( "apd" ) ) ); if ( _debug ) std::cout << "Got " << nodeListApds->length() << " APDs!" << std::endl; } std::vector<std::string> serialListReader::getListOfSerials() { try { return getSerialListIfDataCanBeRead(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; std::vector<std::string> serialList; serialList.clear(); return serialList; } } std::vector<std::string> serialListReader::getSerialListIfDataCanBeRead() { if (!readyToReadData) throw std::runtime_error ( "No data loaded that can be read!" ); std::vector<std::string> serialList = getSerialListFromNodeList(); if ( _debug ) std::cout << "Returning serial list with " << serialList.size() << " entries!" << std::endl; return serialList; } std::vector<std::string> serialListReader::getSerialListFromNodeList() { std::vector<std::string> serialList; serialList.clear(); for ( int i = 0; i < nodeListApds->length(); i++ ) { QDomNode apdNode = nodeListApds->item ( i ); std::string serial = apdNode.attributes().namedItem ( QString::fromUtf8 ( "serial" ) ).nodeValue().toStdString(); serialList.push_back(serial); } return serialList; }