Skip to content
Snippets Groups Projects
serialListReader.cxx 4.59 KiB
Newer Older
Jan Reher's avatar
Jan Reher committed
#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 ) ) {
Jan Reher's avatar
Jan Reher committed
  _debug = debug;
Jan Reher's avatar
Jan Reher committed
}

void serialListReader::getAndProcessData() {
Jan Reher's avatar
Jan Reher committed
  try {
    getApdListFromNetwork();
    verifyHttpResponse();
    getDataFromReply();
    verifyDataFormat();
    verifyQuerySuccess();
    getApdNodeList();
    readyToReadData = true;
  }
  catch ( std::exception& e ) {
    std::cerr << e.what() << std::endl;
    readyToReadData = false;
  }
}
Jan Reher's avatar
Jan Reher committed

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();
Jan Reher's avatar
Jan Reher committed
  }
  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;
}