00001
00002
00003
00004
00005
00006
00007
00008 #ifndef TAOCONSTRUCTOR_H_
00009 #define TAOCONSTRUCTOR_H_
00010
00011 #include <iostream>
00012 #include <fstream>
00013 #include <stdlib.h>
00014 #include <vector>
00015 #include <map>
00016 #include <set>
00017 #include <deque>
00018
00019 #include "Container.h"
00020
00021 using namespace std;
00022
00023
00024
00025
00026
00027
00028 namespace {
00029
00030 string xmlTag(string tagName) { return "<" + tagName + " />"; }
00031 string xmlTagOpen(string tagName) { return "<" + tagName + ">"; }
00032 string xmlTagClose(string tagName) { return "</" + tagName + ">"; }
00033
00034 string xmlTag(string tagName, string attrName, string attrValue) {
00035 return "<" + tagName + " " + attrName + "=\"" + attrValue + "\" />";
00036 }
00037
00038 string xmlTag(string tagName, string attrName1, string attrValue1, string attrName2, string attrValue2) {
00039 return "<" + tagName + " " + attrName1 + "=\"" + attrValue1 + "\" " + attrName2 + "=\"" + attrValue2 + "\" />";
00040 }
00041
00042 string xmlTag(string tagName, string attrName1, string attrValue1, string attrName2, string attrValue2, string attrName3, string attrValue3) {
00043 return "<" + tagName + " " + attrName1 + "=\"" + attrValue1 + "\" " + attrName2 + "=\"" + attrValue2 + "\" " + attrName3 + "=\"" + attrValue3 + "\" />";
00044 }
00045
00046 string xmlTagOpen(string tagName, string attrName, string attrValue) {
00047 return "<" + tagName + " " + attrName + "=\"" + attrValue + "\">";
00048 }
00049
00050 string xmlTagOpen(string tagName, string attrName1, string attrValue1, string attrName2, string attrValue2) {
00051 return "<" + tagName + " " + attrName1 + "=\"" + attrValue1 + "\" " + attrName2 + "=\"" + attrValue2 + "\">";
00052 }
00053
00054 string xmlTagOpen(string tagName, string attrName1, string attrValue1, string attrName2, string attrValue2, string attrName3, string attrValue3) {
00055 return "<" + tagName + " " + attrName1 + "=\"" + attrValue1 + "\" " + attrName2 + "=\"" + attrValue2 + "\"" + " " + attrName3 + "=\"" + attrValue3 + "\">";
00056 }
00057
00058 string xmlCData(string data) {
00059 return "<![CDATA[" + data + "]]>";
00060 }
00061
00062 ostream& tabbedWrite(ostream& stream, int depth, string text) {
00063 stream << string(depth * 4, ' ') << text << endl;
00064 return stream;
00065 }
00066
00067 class XmlTagScopped
00068 {
00069 public:
00070 XmlTagScopped(ostream& stream, int depth, string tagName,
00071 string attrName1 = "", string attrValue1 = "",
00072 string attrName2 = "", string attrValue2 = "",
00073 string attrName3 = "", string attrValue3 = "")
00074 : _stream(stream), _depth(depth), _tagName(tagName)
00075 {
00076 if (attrName1 == "" && attrName2 == "" && attrName3 == "")
00077 tabbedWrite(_stream, _depth, xmlTagOpen(_tagName));
00078 else if (attrName2 == "" && attrName3 == "")
00079 tabbedWrite(_stream, _depth, xmlTagOpen(_tagName, attrName1, attrValue1));
00080 else if (attrName3 == "")
00081 tabbedWrite(_stream, _depth, xmlTagOpen(_tagName, attrName1, attrValue1, attrName2, attrValue2));
00082 else
00083 tabbedWrite(_stream, _depth, xmlTagOpen(_tagName, attrName1, attrValue1, attrName2, attrValue2, attrName3, attrValue3));
00084 }
00085
00086 ~XmlTagScopped() {
00087 tabbedWrite(_stream, _depth, xmlTagClose(_tagName));
00088 }
00089
00090 private:
00091 ostream& _stream;
00092 int _depth;
00093 string _tagName;
00094 };
00095
00096 }
00097
00098
00099 namespace tao_constructor {
00100
00101
00102
00103
00104
00105
00106 class IXmlWritable {
00107 public:
00108 virtual ~IXmlWritable() { }
00109 virtual void writeXml(ostream& stream, int depth) = 0;
00110 };
00111
00112
00113 class ITAOConstructor {
00114 public:
00115 ITAOConstructor() { }
00116 virtual ~ITAOConstructor() { }
00117 virtual void writeXmlTao(string sourceTao, string targetTao, string parentId, ostream& stream, int depth) = 0;
00118 virtual string getBehId(string taoName, string behName) = 0;
00119 };
00120
00121
00122 class Element {
00123 public:
00124 mutable ITAOConstructor* lib;
00125 mutable string tab;
00126 mutable string id;
00127 Element(ITAOConstructor* constructor = 0) : lib(constructor) { }
00128 };
00129
00130
00131
00132
00133
00134
00135
00136 class Next : public Element, public IXmlWritable {
00137 public:
00138 string protocol;
00139 vector<string> next_ops;
00140 string taoName;
00141
00142 Next(string parent, string parentTao, ITAOConstructor * constructor = 0)
00143 : Element(constructor), taoName(parentTao)
00144 {
00145 id = parent;
00146 }
00147
00148 void writeXml(ostream& stream, int depth) {
00149 if (protocol == "")
00150 return;
00151
00152 XmlTagScopped xml(stream, depth, "tao_next", "id", getId(), "protocol", protocol);
00153
00154 for (int i = 0; i < next_ops.size(); ++i) {
00155 tabbedWrite(stream, depth + 1, xmlTag("tao_next_op", "id", getId() + "/" + next_ops[i], "name", lib->getBehId(taoName, next_ops[i])));
00156 }
00157 }
00158
00159 string getId() const {
00160
00161 return id + "";
00162 }
00163 };
00164
00165 class Alloc : public Element, public IXmlWritable {
00166 public:
00167 string protocol;
00168 vector<string> roles;
00169 string taoName;
00170
00171 Alloc(string parent, string parentTao, ITAOConstructor* constructor = 0)
00172 : Element(constructor), taoName(parentTao)
00173 {
00174 id = parent;
00175 }
00176
00177 void writeXml(ostream& stream, int depth) {
00178 if (protocol == "" && roles.size() == 0)
00179 return;
00180
00181 XmlTagScopped xml(stream, depth, "tao_allocate", "id", getId(), "protocol", protocol);
00182
00183 for (int i = 0; i < roles.size(); ++i) {
00184 string targetTaoName = roles[i];
00185
00186
00187 lib->writeXmlTao(taoName, targetTaoName, getId(), stream, depth + 1);
00188 }
00189 }
00190
00191 string getId() const {
00192
00193 return id + "";
00194 }
00195 };
00196
00197 class Beh : public Element, public IXmlWritable {
00198 public:
00199 string name;
00200
00201 string start;
00202 string stop;
00203
00204 vector<string> task_calls;
00205
00206 Alloc alloc;
00207 Next next;
00208
00209 string taoName;
00210
00211 Beh(string parent, string behName, string parentTao, ITAOConstructor* constructor)
00212 : name(behName),
00213 Element(constructor), alloc(getId(parent, name), parentTao, constructor),
00214 next(getId(parent, name), parentTao, constructor), taoName(parentTao) {
00215
00216 id = parent;
00217 }
00218
00219 void writeXml(ostream& stream, int depth) {
00220 XmlTagScopped xml(stream, depth, "tao_plan", "id", getId(), "name", name);
00221
00222 {
00223 XmlTagScopped xml(stream, depth + 1, "tao_start_condition", "id", getId() + "/start" );
00224 tabbedWrite(stream, depth + 2, xmlCData(start));
00225 }
00226
00227 {
00228 XmlTagScopped xml(stream, depth + 1, "tao_stop_condition", "id", getId() + "/stop");
00229 tabbedWrite(stream, depth + 2, xmlCData(stop));
00230 }
00231
00232 for (size_t i = 0; i < task_calls.size(); i++)
00233 tabbedWrite(stream, depth + 1, xmlTag("tao_call_task", "id", getId() + "/call_task_" + task_calls[i] , "task", task_calls[i]));
00234
00235 alloc.writeXml(stream, depth + 1);
00236
00237 next.writeXml(stream, depth + 1);
00238 }
00239
00240 string getId(string parent, string name) {
00241
00242 return parent + "/" + name;
00243 }
00244
00245 string getId() const {
00246
00247 return id + "/" + name;
00248 }
00249 };
00250
00251 class TAO : public Element, public IXmlWritable {
00252 public:
00253
00254 string name;
00255 std::string start;
00256 std::vector<Beh> behs;
00257 std::deque<Beh> stack;
00258
00259 TAO(ITAOConstructor* constructor = 0) : Element(constructor) {
00260
00261 }
00262
00263 void createBeh(string name = "") {
00264 stack.push_back(Beh(getId(), name, getName(), lib));
00265 }
00266
00267 void add() {
00268 behs.push_back(currentBeh());
00269 drop();
00270 }
00271
00272 void drop() {
00273 stack.pop_back();
00274 }
00275
00276 Beh& currentBeh() {
00277 return stack.back();
00278 }
00279
00280 virtual string getName() {
00281 return name;
00282 }
00283
00284 virtual void writeXml(ostream& stream, int depth) {
00285 XmlTagScopped xml(stream, depth, "tao", "id", getId(), "name", name, "start", lib->getBehId( id != "" ? getId() : name, start));
00286 {
00287 {
00288 XmlTagScopped xml(stream, depth + 1, "tao_plans", "id", getId() + "/plans");
00289
00290 for (int i = 0; i < behs.size(); i++)
00291 behs[i].writeXml(stream, depth + 2);
00292 }
00293 }
00294 }
00295
00296 void updateId(string newId, string newName) {
00297
00298 name = newName;
00299 id = newId;
00300
00301 for (int i = 0; i < this->behs.size(); ++i) {
00302 this->behs[i].id = getId();
00303 this->behs[i].taoName = getId();
00304 this->behs[i].next.id = this->behs[i].getId();
00305 this->behs[i].next.taoName = getId();
00306 this->behs[i].alloc.id = this->behs[i].getId();
00307 this->behs[i].alloc.taoName = getId();
00308 }
00309
00310 }
00311
00312 std::string getId() const {
00313 return id + "/" + name;
00314 }
00315 };
00316
00317
00318 class TAOConstructor : public ITAOConstructor {
00319 public:
00320
00321 typedef map<std::string, TAO> TaosMap;
00322
00323 TaosMap taos;
00324 deque<TAO> stack;
00325 Container* trees;
00326 stringstream& errors;
00327 string filename;
00328
00329 TAOConstructor(std::stringstream& errors, std::string filename)
00330 : trees(0), errors(errors), filename(filename)
00331 { }
00332
00333 void create() {
00334 stack.push_back(TAO(this));
00335 }
00336
00337 void add() {
00338 taos[currentTao().name] = currentTao();
00339 drop();
00340 }
00341
00342 void drop() {
00343 stack.pop_back();
00344 }
00345
00346 TAO& currentTao() {
00347 return stack.back();
00348 }
00349
00350 virtual string getBehId(string taoName, string behName) {
00351 if (taos.count(taoName) > 0) {
00352 for (int i = 0; i < taos[taoName].behs.size(); ++i) {
00353 if (taos[taoName].behs[i].name == behName)
00354 return taos[taoName].behs[i].getId();
00355 }
00356 }
00357
00358 if (subTaos.count(taoName) > 0) {
00359 for (int i = 0; i < subTaos[taoName].behs.size(); ++i) {
00360 if (subTaos[taoName].behs[i].name == behName)
00361 return subTaos[taoName].behs[i].getId();
00362 }
00363 }
00364
00365 return behName;
00366 }
00367
00368 string getOnlyTaoName(string fullName) {
00369 if (fullName[0] == '/')
00370 for (int i = fullName.size() - 1; i >= 0; i--)
00371 if (fullName[i] == '/')
00372 return string(&fullName.c_str()[i + 1]);
00373
00374 return fullName;
00375 }
00376
00377 void writeXmlTao(string sourceTao, string targetTao, string parentId, ostream& stream, int depth) {
00378
00379 if (isLoopReference(getOnlyTaoName(sourceTao), getOnlyTaoName(targetTao))) {
00380 tabbedWrite(stream, depth, xmlTag("tao_ref", "name", targetTao));
00381 return;
00382 }
00383
00384 if (taos.count(targetTao) > 0) {
00385 referencedTaos[sourceTao].insert(targetTao);
00386
00387 TAO tao = taos[targetTao];
00388 tao.updateId(parentId, targetTao);
00389 subTaos[tao.getId()] = tao;
00390 subTaos[tao.getId()].writeXml(stream, depth);
00391 }
00392 else
00393 tabbedWrite(stream, depth, xmlTag("tao_not_found", "name", targetTao));
00394 }
00395
00396 void writeXml(ostream& stream) {
00397 TaosMap::iterator it;
00398
00399 for(it = taos.begin(); it != taos.end(); ++it) {
00400 it->second.writeXml(stream, 0);
00401 }
00402 }
00403
00404 private:
00405
00406 map<string, set<string> > referencedTaos;
00407 TaosMap subTaos;
00408 bool isLoopReference(string sourceTao, string targetTao) {
00409 bool result = referencedTaos[targetTao].count(sourceTao) > 0;
00410 return result;
00411 }
00412 };
00413
00414 ostream& saveXml(ostream& stream, TAOConstructor& constructor);
00415 void saveXml(string directory, TAOConstructor& constructor);
00416
00417 }
00418
00419 #endif