UnitGenerator.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031
00032 #include "LoaderGenerator.hpp"
00033
00034 #include <fstream>
00035 #include <iostream>
00036 #include <string>
00037 #include <sstream>
00038 #include <algorithm>
00039
00040
00041
00042 #include <FilePathSearch.hpp>
00043
00044 #include <XmlDocument.hpp>
00045 #include <XmlElement.hpp>
00046 #include <XmlElementVector.hpp>
00047 #include <UnitFlowConfiguration.hpp>
00048
00049 #include <DeploymentConfiguration.hpp>
00050
00051 using namespace mermaid::mermaidloader;
00052
00053 using std::cerr;
00054 using std::cerr;
00055 using std::endl;
00056 using std::ofstream;
00057 using std::string;
00058 using std::stringstream;
00059
00060 using boost::shared_ptr;
00061
00062 using mermaid::support::system::FilePathSearch;
00063
00064 using mermaid::support::xml::XmlDocument;
00065 using mermaid::support::xml::XmlElement;
00066 using mermaid::support::xml::XmlElementVector;
00067
00068 using mermaid::support::unitgenerator::UnitFlowConfiguration;
00069
00070 #include <iostream>
00071
00072 int indent = 0;
00073 std::string getIndent()
00074 {
00075 stringstream s;
00076 for (int i = 0; i < indent; i++) {
00077 s << " ";
00078 }
00079 return s.str();
00080 }
00081
00082 int main (int argc, char **argv)
00083 {
00084
00085 if (argc < 3) {
00086 cerr << "MermaidLoader generator for ACE-based systems" << endl;
00087 cerr << "Usage:" << endl;
00088 cerr << argv[0] << " <configuration file> <flow-configuration-file> <output file> <search paths>" << endl;
00089 exit (1);
00090 }
00091
00092
00093 for (int i = 4; i < (argc); i++) {
00094 FilePathSearch::addSearchPath (argv[i]);
00095 }
00096
00097
00098 FilePathSearch::addSearchPath ("./config");
00099 FilePathSearch::addSearchPath ("./build/config");
00100 FilePathSearch::addSearchPath ("./");
00101 char * mermaid_dir = getenv ("MERMAID_DIR");
00102 if (mermaid_dir != 0) {
00103 FilePathSearch::addSearchPath (string (mermaid_dir) + "/config");
00104 }
00105
00106 FilePathSearch::addSearchPath ("/");
00107
00108
00109 string configFileName = string (argv[1]);
00110 string flowConfigFileName = string (argv[2]);
00111 string outputFileName = string (argv[3]);
00112
00113
00114 ofstream outputFile;
00115 outputFile.open (outputFileName.c_str());
00116
00117 if (outputFile.is_open() == false) {
00118 cerr << "Failed to open file: \"" << outputFileName << "\"" << endl;
00119 exit (1);
00120 }
00121
00122 shared_ptr<XmlDocument> configXmlDoc = shared_ptr<XmlDocument> (new XmlDocument());
00123 configXmlDoc->parseFile (configFileName);
00124
00125 DeploymentConfiguration configuration;
00126 configuration.loadConfiguration (configXmlDoc);
00127
00128 FileSearchPathList fspl = configuration.getFileSearchPathList();
00129 DataDescriptionFileList ddfl = configuration.getDataDescriptionFileList();
00130 ServiceTypeDescriptionFileList stdfl = configuration.getServiceTypeDescriptionFileList();
00131 EntityDescriptionFileList edfl = configuration.getEntityDescriptionFileList();
00132 ActiveObjectConfigurationNameMap aocnm = configuration.getActiveObjectConfigurationNameMap();
00133 ActiveObjectConfigurationServiceMap aocsm = configuration.getActiveObjectConfigurationServiceMap();
00134 ServiceDeploymentConfigurationNameMap scnm = configuration.getServiceDeploymentConfigurationNameMap();
00135
00136
00137 shared_ptr<XmlDocument> flowConfigXmlDoc = shared_ptr<XmlDocument> (new XmlDocument());
00138 flowConfigXmlDoc->parseFile (flowConfigFileName, false);
00139 UnitFlowConfiguration flowConfiguration;
00140 flowConfiguration.loadConfiguration (flowConfigXmlDoc);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 shared_ptr<XmlDocument> templateXmlDoc = shared_ptr<XmlDocument> (new XmlDocument());
00153 templateXmlDoc->parseFile ("unitgenerator-ace.xml", false);
00154
00155
00156 stringstream code;
00157
00158
00159 shared_ptr<XmlElement> templateRoot = templateXmlDoc->getRootElement();
00160 XmlElementVector templateChildren = templateRoot->getChildrenElements();
00161 shared_ptr<XmlElement> fileHeaderElement = templateChildren.getFirstElementWithName ("file-header");
00162 shared_ptr<XmlElement> includesElement = templateChildren.getFirstElementWithName ("includes");
00163 shared_ptr<XmlElement> serviceIncludeHeaderElement = templateChildren.getFirstElementWithName ("service-include-header");
00164 shared_ptr<XmlElement> serviceIncludeFooterElement = templateChildren.getFirstElementWithName ("service-include-footer");
00165 shared_ptr<XmlElement> usesElement = templateChildren.getFirstElementWithName ("uses");
00166 shared_ptr<XmlElement> serviceUsingHeaderElement = templateChildren.getFirstElementWithName ("service-using-header");
00167 shared_ptr<XmlElement> serviceUsingFooterElement = templateChildren.getFirstElementWithName ("service-using-footer");
00168 shared_ptr<XmlElement> mainHeaderElement = templateChildren.getFirstElementWithName ("main-header");
00169 shared_ptr<XmlElement> filePathHeaderElement = templateChildren.getFirstElementWithName ("file-path-header");
00170 shared_ptr<XmlElement> filePathFooterElement = templateChildren.getFirstElementWithName ("file-path-footer");
00171 shared_ptr<XmlElement> dataDescriptionLoadHeaderElement = templateChildren.getFirstElementWithName ("data-description-load-header");
00172 shared_ptr<XmlElement> dataDescriptionLoadFooterElement = templateChildren.getFirstElementWithName ("data-description-load-footer");
00173 shared_ptr<XmlElement> serviceTypeLoadHeaderElement = templateChildren.getFirstElementWithName ("service-type-load-header");
00174 shared_ptr<XmlElement> serviceTypeLoadFooterElement = templateChildren.getFirstElementWithName ("service-type-load-footer");
00175 shared_ptr<XmlElement> entityDescriptionLoadHeaderElement = templateChildren.getFirstElementWithName ("entity-description-load-header");
00176 shared_ptr<XmlElement> entityDescriptionLoadFooterElement = templateChildren.getFirstElementWithName ("entity-description-load-footer");
00177 shared_ptr<XmlElement> aoEntityRepositoryHeaderElement = templateChildren.getFirstElementWithName ("ao-entity-repository-header");
00178 shared_ptr<XmlElement> aoEntityRepositoryFooterElement = templateChildren.getFirstElementWithName ("ao-entity-repository-footer");
00179 shared_ptr<XmlElement> mainFooterElement = templateChildren.getFirstElementWithName ("main-footer");
00180 shared_ptr<XmlElement> fileFooterElement = templateChildren.getFirstElementWithName ("file-footer");
00181
00182
00183
00184
00185 code << (string) (*fileHeaderElement->getFirstNonBlankCharData());
00186 code << (string) (*includesElement->getFirstNonBlankCharData());
00187
00188
00189 {
00190 code << endl << getIndent() << "// Service Includes" << endl;
00191
00192 ServiceDeploymentConfigurationNameMap::iterator siit;
00193
00194 for (siit = scnm.begin(); siit != scnm.end(); siit++) {
00195 shared_ptr<ServiceDeploymentConfiguration> sc = (*siit).second;
00196 code << (string) (*serviceIncludeHeaderElement->getFirstNonBlankCharData());
00197 code << sc->getServiceHeaderFilename();
00198 code << (string) (*serviceIncludeFooterElement->getFirstNonBlankCharData());
00199 }
00200 }
00201
00202 code << (string) (*usesElement->getFirstNonBlankCharData());
00203
00204
00205 {
00206 code << endl << getIndent() << "// Service uses" << endl;
00207
00208 ServiceDeploymentConfigurationNameMap::iterator siit;
00209
00210 for (siit = scnm.begin(); siit != scnm.end(); siit++) {
00211 shared_ptr<ServiceDeploymentConfiguration> sc = (*siit).second;
00212 code << (string) (*serviceUsingHeaderElement->getFirstNonBlankCharData());
00213 code << sc->getServiceNamespace() << "::" << sc->getServiceClassName();
00214 code << (string) (*serviceUsingFooterElement->getFirstNonBlankCharData()) << std::endl;
00215 }
00216 }
00217
00218
00219 code << (string) (*mainHeaderElement->getFirstNonBlankCharData());
00220 indent++;
00221
00222
00223 {
00224 FileSearchPathList::iterator fpit;
00225
00226 code << endl << getIndent() << "//Setting file search paths" << endl;
00227
00228 for (fpit = fspl.begin(); fpit != fspl.end(); fpit++) {
00229 std::string path = *fpit;
00230 code << getIndent() << (string) (*filePathHeaderElement->getFirstNonBlankCharData());
00231 code << path;
00232 code << (string) (*filePathFooterElement->getFirstNonBlankCharData()) << endl;
00233 }
00234
00235
00236 code << getIndent() << (string) (*filePathHeaderElement->getFirstNonBlankCharData());
00237 code << "./";
00238 code << (string) (*filePathFooterElement->getFirstNonBlankCharData()) << " //Default file search path" << endl;
00239 }
00240
00241
00242 {
00243 DataDescriptionFileList::iterator ddit;
00244 vector<string> dddf;
00245 vector<string>::iterator sit;
00246
00247 dddf.push_back ("ping-tool-data-description-file.xml");
00248 #ifdef USE_COMM
00249 dddf.push_back ("comm-service-data-description-file.xml");
00250 #endif
00251
00252 code << endl << getIndent() << "//Load data description files" << endl;
00253
00254 code << endl << getIndent() << "//Loading default data description files" << endl;
00255 for (sit = dddf.begin(); sit != dddf.end(); sit++) {
00256 code << getIndent() << (string) (*dataDescriptionLoadHeaderElement->getFirstNonBlankCharData());
00257 code << *sit;
00258 code << (string) (*dataDescriptionLoadFooterElement->getFirstNonBlankCharData()) << endl;
00259 }
00260
00261 for (ddit = ddfl.begin(); ddit != ddfl.end(); ddit++) {
00262 std::string filename = *ddit;
00263
00264 if (std::find (dddf.begin(), dddf.end(), filename) == dddf.end()) {
00265 code << getIndent() << "//loading " << filename << endl;
00266 code << getIndent() << (string) (*dataDescriptionLoadHeaderElement->getFirstNonBlankCharData());
00267 code << filename;
00268 code << (string) (*dataDescriptionLoadFooterElement->getFirstNonBlankCharData()) << endl;
00269 }
00270 }
00271 }
00272
00273
00274 {
00275 ServiceTypeDescriptionFileList::iterator stit;
00276 vector<string> dsdf;
00277 vector<string>::iterator sit;
00278
00279 dsdf.push_back ("ping-tool-service-type-description-file.xml");
00280 #ifdef USE_COMM
00281 dsdf.push_back ("comm-service-type-description-file.xml");
00282 #endif
00283
00284 code << endl << getIndent() << "//Load service type description files" << endl;
00285
00286 code << endl << getIndent() << "//Loading default service type description files" << endl;
00287 for (sit = dsdf.begin(); sit != dsdf.end(); sit++) {
00288 code << getIndent() << (string) (*serviceTypeLoadHeaderElement->getFirstNonBlankCharData());
00289 code << *sit;
00290 code << (string) (*serviceTypeLoadFooterElement->getFirstNonBlankCharData()) << endl;
00291 }
00292
00293 for (stit = stdfl.begin(); stit != stdfl.end(); stit++) {
00294 std::string filename = *stit;
00295
00296 if (std::find (dsdf.begin(), dsdf.end(), filename) == dsdf.end()) {
00297 code << getIndent() << "//loading " << filename << endl;
00298 code << getIndent() << (string) (*serviceTypeLoadHeaderElement->getFirstNonBlankCharData());
00299 code << filename;
00300 code << (string) (*serviceTypeLoadFooterElement->getFirstNonBlankCharData()) << endl;
00301 }
00302 }
00303 }
00304
00305
00306 {
00307 EntityDescriptionFileList::iterator edit;
00308
00309 code << endl << getIndent() << "//Load entity description files" << endl;
00310
00311 for (edit = edfl.begin(); edit != edfl.end(); edit++) {
00312 std::string filename = *edit;
00313 code << getIndent() << "//loading " << filename << endl;
00314 code << getIndent() << (string) (*entityDescriptionLoadHeaderElement->getFirstNonBlankCharData());
00315 code << filename;
00316 code << (string) (*entityDescriptionLoadFooterElement->getFirstNonBlankCharData());
00317 }
00318 }
00319
00320
00321
00322
00323 code << getIndent() << "//setup search paths" << endl;
00324 code << getIndent() << "std::vector<std::string>::iterator pathIterator;" << endl;
00325 code << getIndent() << "for (pathIterator=pathVector.begin(); pathIterator!=pathVector.end(); pathIterator++)" << endl;
00326 code << getIndent() << "{" << endl;
00327 indent++;
00328 code << getIndent() << "std::string path = *pathIterator;" << endl;
00329 code << getIndent() << "std::cerr << \"Loading path: \" << path << std::endl;" << endl;
00330 code << getIndent() << "FilePathSearch::addSearchPath(path);" << endl;
00331 indent--;
00332 code << getIndent() << "}" << endl;
00333
00334
00335 code << getIndent() << "//load data descriptions" << endl;
00336 code << getIndent() << "std::vector<std::string>::iterator dataDescriptionIterator;" << endl;
00337 code << getIndent() << "for (dataDescriptionIterator=dataDescriptionVector.begin(); dataDescriptionIterator!=dataDescriptionVector.end(); dataDescriptionIterator++)" << endl;
00338 code << getIndent() << "{" << endl;
00339 indent++;
00340 code << getIndent() << "std::string dataDescriptionFile = *dataDescriptionIterator;" << endl;
00341 code << getIndent() << "std::cerr << \"Loading data type description file: \" << dataDescriptionFile << std::endl;" << endl;
00342 code << getIndent() << "shared_ptr<XmlDocument> dataDoc = shared_ptr<XmlDocument>(new XmlDocument());" << endl;
00343 code << getIndent() << "dataDoc->parseFile(dataDescriptionFile);" << endl;
00344 code << getIndent() << "DataFactory::loadDataDescription(dataDoc);" << endl;
00345 indent--;
00346 code << getIndent() << "}" << endl;
00347
00348
00349 code << getIndent() << "//load service type descriptions" << endl;
00350 code << getIndent() << "std::vector<std::string>::iterator serviceDescriptionIterator;" << endl;
00351 code << getIndent() << "for (serviceDescriptionIterator=serviceDescriptionVector.begin(); serviceDescriptionIterator!=serviceDescriptionVector.end(); serviceDescriptionIterator++)" << endl;
00352 code << getIndent() << "{" << endl;
00353 indent++;
00354 code << getIndent() << "std::string serviceDescriptionFile = *serviceDescriptionIterator;" << endl;
00355 code << getIndent() << "std::cerr << \"Loading service type description file: \" << serviceDescriptionFile << std::endl;" << endl;
00356 code << getIndent() << "shared_ptr<XmlDocument> docServiceType = shared_ptr<XmlDocument>(new XmlDocument());" << endl;
00357 code << getIndent() << "docServiceType->parseFile(serviceDescriptionFile);" << endl;
00358 code << getIndent() << "shared_ptr<XmlElement> serviceTypeDescriptionList = docServiceType->getRootElement();" << endl;
00359 code << getIndent() << "shared_ptr<ServiceTypeDescriptionRepository> serviceTypeDescriptionRepository = ServiceTypeDescriptionRepository::getInstance();" << endl;
00360 code << getIndent() << "ServiceTypeDescriptionFactory::populateServiceTypeDescriptionRepository(serviceTypeDescriptionRepository, serviceTypeDescriptionList);" << endl;
00361 indent--;
00362 code << getIndent() << "}" << endl;
00363
00364
00365 code << getIndent() << "//load entity descriptions" << endl;
00366 code << getIndent() << "std::vector<std::string>::iterator entityDescriptionIterator;" << endl;
00367 code << getIndent() << "for (entityDescriptionIterator=entityDescriptionVector.begin(); entityDescriptionIterator!=entityDescriptionVector.end(); entityDescriptionIterator++)" << endl;
00368 code << getIndent() << "{" << endl;
00369 indent++;
00370 code << getIndent() << "std::string entityDescriptionFile = *entityDescriptionIterator;" << endl;
00371 code << getIndent() << "std::cerr << \"Loading entity type description file: \" << entityDescriptionFile << std::endl;" << endl;
00372 code << getIndent() << "shared_ptr<XmlDocument> docEntityDescription = shared_ptr<XmlDocument>(new XmlDocument());" << endl;
00373 code << getIndent() << "docEntityDescription->parseFile(entityDescriptionFile);" << endl;
00374 code << getIndent() << "shared_ptr<XmlElement> entityDescriptionList = docEntityDescription->getRootElement();" << endl;
00375 code << getIndent() << "shared_ptr<EntityDescriptionRepository> entityDescriptionRepository = EntityDescriptionRepository::getInstance();" << endl;
00376 code << getIndent() << "shared_ptr<ServiceTypeDescriptionRepository> serviceTypeDescriptionRepository = ServiceTypeDescriptionRepository::getInstance();" << endl;
00377 code << getIndent() << "EntityDescriptionFactory::populateEntityDescriptionRepository(entityDescriptionRepository, entityDescriptionList, serviceTypeDescriptionRepository);" << endl;
00378 indent--;
00379 code << getIndent() << "}" << endl;
00380
00381
00382 {
00383
00384 ActiveObjectConfigurationNameMap::iterator aoit;
00385
00386 code << endl << getIndent() << "// Create ActiveObjects" << endl;
00387
00388 for (aoit = aocnm.begin(); aoit != aocnm.end(); aoit++) {
00389 shared_ptr<ActiveObjectConfiguration> aoc = (*aoit).second;
00390 code << getIndent() << "shared_ptr<ActiveObject> " << aoc->getName() << " = ActiveObjectManagerAce::getInstance()->createActiveObject();" << endl;
00391 }
00392
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 {
00410 code << endl << getIndent() << "// ActiveObjects start" << endl;
00411
00412 ActiveObjectConfigurationNameMap::iterator aoi;
00413
00414 for (aoi = aocnm.begin(); aoi != aocnm.end(); aoi++) {
00415 string aoName = (*aoi).first;
00416 code << getIndent() << aoName << "->start();" << endl;
00417 }
00418 }
00419
00420
00421 std::string entityRepositoryName = "aoEntityRepository";
00422 {
00423 code << endl << getIndent() << "// Create entity repository" << endl;
00424 code << getIndent() << (string) (*aoEntityRepositoryHeaderElement->getFirstNonBlankCharData());
00425 code << entityRepositoryName;
00426 code << (string) (*aoEntityRepositoryFooterElement->getFirstNonBlankCharData()) << endl;
00427
00428 }
00429
00430 code << endl << getIndent() << "map<string, shared_ptr<Service> > nameToServiceMap_;" << endl;
00431
00432 {
00433 ServiceDeploymentConfigurationNameMap::iterator sit;
00434
00435 code << endl << getIndent() << "// Create Services" << endl;
00436
00437 for (sit = scnm.begin(); sit != scnm.end(); sit++) {
00438 shared_ptr<ServiceDeploymentConfiguration> sc = (*sit).second;
00439 string serviceDescriptionXmlInstance = sc->getServiceInstanceName() + "Xml";
00440
00441 code << getIndent() << "{" << endl;
00442 indent++;
00443
00444
00445 code << getIndent() << "shared_ptr<XmlDocument> serviceConfigurationDocument(new XmlDocument());" << endl;
00446 code << getIndent() << "serviceConfigurationDocument->parseFile(\"" << sc->getServiceConfigurationFilename() << "\");" << endl;
00447 code << getIndent() << "shared_ptr<ServiceConfiguration> serviceConfiguration(new ServiceConfiguration(serviceConfigurationDocument));" << endl;
00448
00449 code << getIndent() << "shared_ptr<Task> build" << sc->getServiceClassName() << "((Task*)new UnitServiceBuildTask<" << sc->getServiceClassName() << ">(" << sc->getServiceActiveObjectName() << ", " << entityRepositoryName << ", \"" << sc->getServiceEntityName() << "\", \"" << sc->getServiceInstanceName() << "\", serviceConfiguration, nameToServiceMap_));" << endl;
00450
00451 code << getIndent() << sc->getServiceActiveObjectName() << "->addTask(build" << sc->getServiceClassName() << ");" << endl;
00452
00453 indent--;
00454 code << getIndent() << "}" << endl;
00455 }
00456
00457 }
00458
00459 code << endl << endl;
00460
00461 code << getIndent() << "// busy wait" << endl;
00462 code << getIndent() << "while (nameToServiceMap_.size() != " << scnm.size() << ")" << endl;
00463 indent++;
00464 code << getIndent() << ";" << endl << endl;
00465 indent--;
00466
00467
00468
00469
00470
00471
00472 {
00473 code << endl << getIndent() << "// Wait for ActiveObjects to stop" << endl;
00474 code << getIndent() << "ActiveObjectManagerAce::getInstance()->waitForActiveObjectsToStop();" << endl;
00475
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 code << (string) (*mainFooterElement->getFirstNonBlankCharData());
00495
00496 code << (string) (*fileFooterElement->getFirstNonBlankCharData());
00497
00498 outputFile << code.str() << endl;
00499 outputFile.close();
00500
00501 };
00502