damaris-backends/core/job_receiver.cpp
2015-11-17 11:55:55 +00:00

179 lines
6.1 KiB
C++

/* **************************************************************************
Author: Achim Gaedke
Created: June 2004
****************************************************************************/
#include "job_receiver.h"
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMException.hpp>
job_receiver::job_receiver(std::string the_jobfilenamepattern) {
try {
xercesc::XMLPlatformUtils::Initialize();
}
catch (const xercesc::XMLException& toCatch) {
char* ini_error=xercesc::XMLString::transcode(toCatch.getMessage());
job_exception new_exception(std::string("xerces initialisation error: ")+ini_error);
xercesc::XMLString::release(&ini_error);
throw new_exception;
}
jobfilename=NULL;
setFilenamePattern(the_jobfilenamepattern);
parser=new xercesc::XercesDOMParser();
if (parser==NULL) {
delete jobfilename;
throw job_exception("could not allocate parser");
}
parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
parser->setDoNamespaces(true);
errHandler = (xercesc::ErrorHandler*) new xercesc::HandlerBase();
parser->setErrorHandler(errHandler);
}
void job_receiver::setFilenamePattern(const std::string& filenamepattern) {
if (jobfilename!=NULL) delete jobfilename;
jobfilenamepattern=filenamepattern;
jobfilenamesize=filenamepattern.size()+20;
jobfilename=new char[jobfilenamesize];
if (jobfilename==NULL) throw job_exception("could not allocate memory for filename");
}
job* job_receiver::receive(size_t no) {
snprintf(jobfilename,jobfilenamesize+20,jobfilenamepattern.c_str(),no);
job* new_job=receive(std::string(jobfilename));
if (new_job->no()!=no) fprintf(stderr, "expected job number %" SIZETPRINTFLETTER " and specified number %" SIZETPRINTFLETTER " are different\n", no, new_job->no() );
new_job->job_no=no;
return new_job;
}
job* job_receiver::receive(const std::string& filename) {
try {
parser->parse(filename.c_str());
}
catch(const xercesc::XMLException& toCatch) {
char* message = xercesc::XMLString::transcode(toCatch.getMessage());
job_exception je(std::string("XML error: ")+message);
xercesc::XMLString::release(&message);
throw je;
}
catch(const xercesc::DOMException& toCatch) {
char* message = xercesc::XMLString::transcode(toCatch.msg);
job_exception je(std::string("XML DOM error: ")+message);
xercesc::XMLString::release(&message);
throw je;
}
catch(const xercesc::SAXParseException& toCatch) {
// more verbose for parser errors
char* message = xercesc::XMLString::transcode(toCatch.getMessage());
job_exception je(std::string("XML SAX Parser error: ")+message);
char location[100];
snprintf(location,sizeof(location),", line %ld column %ld",(long int) toCatch.getLineNumber(),(long int)toCatch.getColumnNumber());
je.append(location);
xercesc::XMLString::release(&message);
throw je;
}
catch(const xercesc::SAXException& toCatch) {
char* message = xercesc::XMLString::transcode(toCatch.getMessage());
job_exception je(std::string("XML SAX error: ")+message);
xercesc::XMLString::release(&message);
throw je;
}
// extract root element, root attributes and root name
xercesc::DOMDocument* doc=parser->getDocument();
if (doc==NULL) throw job_exception("xml job document not found");
xercesc::DOMElement* rootelement=doc->getDocumentElement();
if (rootelement==NULL) throw job_exception("xml job root document not found");
char* docname=xercesc::XMLString::transcode(rootelement->getNodeName());
xercesc::DOMNamedNodeMap* rootattrs=rootelement->getAttributes();
// check the job number
XMLCh* docnoname=xercesc::XMLString::transcode("no");
xercesc::DOMNode* jobno_attr=rootattrs->getNamedItem(docnoname);
xercesc::XMLString::release(&docnoname);
if (jobno_attr==NULL) {
docnoname=xercesc::XMLString::transcode("no");
jobno_attr=rootattrs->getNamedItem(docnoname);
xercesc::XMLString::release(&docnoname);
}
size_t no=0;
if (jobno_attr==NULL) fprintf(stderr,"Warning: job %" SIZETPRINTFLETTER ": root element has no job number\n",no);
else {
char* docno=xercesc::XMLString::transcode(jobno_attr->getNodeValue());
no=strtoul(docno,NULL,0);
xercesc::XMLString::release(&docno);
}
job* this_job=NULL;
// determine the job type by name
if (strcasecmp(docname,"quit")==0) {
this_job=new quit_job(no);
}
else if (strcasecmp(docname,"nop")==0) {
this_job=new do_nothing_job(no);
}
else if (strcasecmp(docname,"pause")==0) {
this_job=new pause_job(no);
} /* pause */
else if (strcasecmp(docname,"restart")==0) {
this_job=new restart_job(no);
} /* restart */
else if (strcasecmp(docname,"wait")==0) {
this_job=new wait_job(no,rootattrs);
} /* wait */
else if (strcasecmp(docname,"experiment")==0) {
try {
this_job=new experiment(no, rootelement);
}
catch (const xercesc::DOMException& de) {
char* domerrmsg=xercesc::XMLString::transcode(de.msg);
char domerrno[5];
snprintf(domerrno,5,"%d",de.code);
job_exception je("sorry, something happend while parsing experiment job: ");
je.append(domerrmsg);
je.append(", code ");
je.append(domerrno);
xercesc::XMLString::release(&domerrmsg);
// cleanup missing
throw je;
}
}
else if (strcasecmp(docname,"configuration")==0) {
try {
this_job=new configuration(no, rootelement);
}
catch (const xercesc::DOMException& de) {
char* domerrmsg=xercesc::XMLString::transcode(de.msg);
char domerrno[5];
snprintf(domerrno,5,"%d",de.code);
job_exception je("sorry, something happend while parsing configuration job: ");
je.append(domerrmsg);
je.append(", code ");
je.append(domerrno);
xercesc::XMLString::release(&domerrmsg);
// cleanup missing
throw je;
}
}
xercesc::XMLString::release(&docname);
parser->reset();
parser->resetDocument();
parser->resetDocumentPool();
return this_job;
}
job_receiver::~job_receiver() {
delete jobfilename;
delete errHandler;
delete parser;
xercesc::XMLPlatformUtils::Terminate();
}