00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "AML/AMLUtilities.hpp"
00025
00026 using namespace std;
00027 using namespace BasicUtilities;
00028
00029
00030
00031
00032 AttributeID::AttributeID() : name(), value() {};
00033 AttributeID::AttributeID(string _name, string _value) : name(_name), value(_value) {};
00034
00035
00036
00037
00038 void NodeID::addAttribute (string name, string value) {
00039
00040 attribute.push_back(AttributeID(name, value));
00041
00042 }
00043
00044
00045
00046
00047 bool NodeID::operator== (const NodeID& n) const {
00048
00049 if (name != n.name) return false;
00050
00051 if (attribute.size() != n.attribute.size()) return false;
00052
00053 AttributeIDVecCIter in = n.attribute.begin();
00054 for (AttributeIDVecCIter ax = attribute.begin(); ax != attribute.end(); ax++) {
00055 if (ax->name != in->name || ax->value != in->value) return false;
00056 in++;
00057 }
00058
00059 return true;
00060
00061 }
00062
00063
00064
00065
00066 bool NodeID::operator== (UAPNode* u) {
00067
00068 if (name != "" && name != u->getName()) return false;
00069
00070 for (AttributeIDVecCIter ax = attribute.begin(); ax != attribute.end(); ax++) {
00071 if (!u->getAttribute(ax->name)) return false;
00072 if (ax->value != "" && u->getAttributeString(ax->name) != ax->value) return false;
00073 }
00074
00075 return true;
00076
00077 }
00078
00079
00080
00081
00082 UAPNode* NodeID::getChild(UAPNode* parent, bool create) {
00083
00084
00085
00086 UAPNode* child = NULL;
00087 NodeVec children = parent->getChildrenByName(name);
00088 for (NodeVecCIter in = children.begin(); in != children.end(); in++) {
00089 child = *in;
00090 for (AttributeIDVecCIter ai = attribute.begin(); ai != attribute.end(); ai++) {
00091 if (child->getAttributeString(ai->name) != ai->value) {
00092 child = NULL;
00093 break;
00094 }
00095 }
00096 if (child) break;
00097 }
00098
00099
00100
00101 if (create && !child) {
00102 child = parent->addChild(name);
00103 for (AttributeIDVecCIter ai = attribute.begin(); ai != attribute.end(); ai++)
00104 child->addAttribute(ai->name, ai->value);
00105 }
00106
00107 return child;
00108
00109 }
00110
00111
00112
00113
00114 bool operator== (const NodeIDVec& x, const NodeIDVec& y) {
00115
00116 if (x.size() != y.size()) return false;
00117
00118 NodeIDVecCIter iy = y.begin();
00119 for (NodeIDVecCIter ix = x.begin(); ix != x.end(); ix++) {
00120 if (!(*ix == *iy)) return false;
00121 iy++;
00122 }
00123
00124 return true;
00125
00126 }
00127
00128
00129
00130
00131 Twig::Twig(string twig_str, bool has_ele_name) {
00132 fromString(twig_str, has_ele_name);
00133 }
00134
00135
00136
00137
00138 Twig::Twig() : name(), target_attribute(), nodeid_vec(), has_brackets(false) {
00139 prefix.clear();
00140 }
00141
00142
00143
00144
00145 bool Twig::fromString (string twig_str, bool has_ele_name) {
00146
00147 nodeid_vec.clear();
00148 name = "";
00149 prefix.clear();
00150 target_attribute = "";
00151 has_brackets = false;
00152
00153 bool ok;
00154 StrList words = break_line_into_words (twig_str, ok);
00155 if (!ok) return false;
00156 if (words.size() == 0) return true;
00157
00158
00159
00160
00161
00162
00163
00164
00165 StrListIter ix_b1 = words.end(), ix_b2 = words.end();
00166 for (StrListIter is = words.begin(); is != words.end(); is++) {
00167 if (*is == "(") break;
00168 if (*is == "=") break;
00169 if (*is == "[") {
00170 if (ix_b1 != words.end()) return false;
00171 ix_b1 = is;
00172 }
00173 if (*is == "]") {
00174 if (ix_b1 == words.end()) return false;
00175 ix_b2 = is;
00176 break;
00177 }
00178 }
00179
00180 if (ix_b2 != words.end() && ix_b2 != --words.end()) return false;
00181
00182
00183
00184
00185
00186
00187 StrList ele_words, attrib_words;
00188 if (ix_b1 != words.end()) {
00189 has_brackets = true;
00190 ele_words = list_copy (words.begin(), ix_b1);
00191 attrib_words = list_copy(ix_b1, ix_b2);
00192 attrib_words.pop_front();
00193 } else if (element_val(words, 1) == "." || element_val(words, 2) == ".") {
00194 ele_words = words;
00195 } else {
00196 attrib_words = words;
00197 }
00198
00199
00200
00201
00202 if (!ele_words.empty() && ele_words.front() == ".") {
00203 prefix.push_back("");
00204 str_pop (ele_words);
00205 }
00206
00207 while (true) {
00208 if (ele_words.empty()) break;
00209 if (ele_words.size() == 1) {
00210 name = ele_words.front();
00211 break;
00212 }
00213 prefix.push_back(str_pop(ele_words));
00214 if (str_pop (ele_words) != ".") return false;
00215 }
00216
00217
00218
00219 StrListIter i_at = rfind (attrib_words, "@");
00220 StrListIter i_p = rfind (attrib_words, ")");
00221
00222
00223
00224 if (has_ele_name && ix_b1 == words.end() && i_at == attrib_words.end() &&
00225 i_p == attrib_words.end() && prefix.empty()) {
00226 while (attrib_words.size() != 0) name += str_pop(attrib_words);
00227 return true;
00228 }
00229
00230
00231
00232 if (i_at != attrib_words.end()) {
00233 for (StrListIter ix = i_at; ix != attrib_words.end(); ix++) {
00234 if (ix == i_at) continue;
00235 target_attribute += *ix;
00236 if (*ix == ")") {
00237 cout << "error: Twig";
00238 throw;
00239 }
00240 }
00241 attrib_words.erase(i_at, attrib_words.end());
00242 }
00243
00244
00245
00246
00247
00248 while (true) {
00249
00250
00251
00252 if (attrib_words.empty()) return true;
00253 string word = str_pop(attrib_words);
00254
00255
00256
00257 NodeID node1;
00258 if (word != "(") {
00259 node1.name = word;
00260 if (attrib_words.empty()) {
00261 nodeid_vec_push_back(node1, twig_str);
00262 return true;
00263 }
00264 word = str_pop (attrib_words);
00265 }
00266
00267 if (word != ":" && word != "(") return false;
00268
00269 if (word == "(") {
00270 while (true) {
00271 string attrib_name, value;
00272 word = str_pop (attrib_words);
00273 if (!isdigit(word[0]) && !isalpha(word[0]) && word != ")") return false;
00274 if (word == ")") break;
00275 attrib_name = word;
00276 word = str_pop (attrib_words);
00277 if (word == "=") {
00278 word = str_pop (attrib_words);
00279 value = word;
00280 word = str_pop (attrib_words);
00281 }
00282 node1.addAttribute(attrib_name, value);
00283 if (word == ")") {
00284 if (attrib_words.empty()) {
00285 nodeid_vec_push_back(node1, twig_str);
00286 return true;
00287 }
00288 word = str_pop (attrib_words);
00289 break;
00290 }
00291 if (word != ",") return false;
00292 }
00293 }
00294
00295 nodeid_vec_push_back(node1, twig_str);
00296
00297 if (word != ":") return false;
00298
00299 }
00300
00301 }
00302
00303
00304
00305
00306 void Twig::nodeid_vec_push_back (NodeID& node, const string& twig_str) {
00307
00308
00309
00310 bool prefix_found;
00311 splitXMLName(node.name, node.xml_uri, node.xml_prefix, node.xml_local_name, prefix_found);
00312
00313
00314
00315 if (node.xml_uri == "") {
00316 for (NodeIDVecRIter in = nodeid_vec.rbegin(); in != nodeid_vec.rend(); in++) {
00317 if (in->xml_prefix == node.xml_prefix) {
00318 node.xml_uri = in->xml_uri;
00319 nodeid_vec.push_back(node);
00320 return;
00321 }
00322 }
00323 if (!prefix_found) {
00324 nodeid_vec.push_back(node);
00325 return;
00326 }
00327 cout << "Twig::nodeid_vec_push_back: No elder found with matching XML prefix for: "
00328 << twig_str << endl;
00329 throw;
00330 }
00331
00332
00333
00334
00335 if (node.xml_uri != "" && !prefix_found) {
00336 for (NodeIDVecRIter in = nodeid_vec.rbegin(); in != nodeid_vec.rend(); in++) {
00337 if (in->xml_uri == node.xml_uri) {
00338 node.xml_prefix = in->xml_prefix;
00339 nodeid_vec.push_back(node);
00340 return;
00341 }
00342 }
00343
00344 node.xml_prefix = "NOT DEFINED!";
00345 return;
00346 }
00347
00348
00349
00350 nodeid_vec.push_back(node);
00351 return;
00352
00353 }
00354
00355
00356
00357
00358 StrList Twig::break_line_into_words(string line, bool& ok) {
00359
00360
00361
00362
00363
00364 ok = false;
00365 StrList words;
00366 int ix_parens = 0, ix_square = 0;
00367
00368
00369
00370 while (true) {
00371
00372 size_t ix_not = line.find_first_not_of(' ');
00373 if (ix_not == string::npos) {
00374 if (ix_parens == 0 && ix_square == 0) ok = true;
00375 return words;
00376 }
00377 line.erase(0, ix_not);
00378
00379 size_t ix_d = line.find_first_of("[]@=,:()\'\" ");
00380
00381
00382
00383 if (ix_d == 0) {
00384 string ch0 = line.substr(0, 1);
00385 line.erase(0, 1);
00386 if (ch0 == "(") ix_parens++;
00387 if (ch0 == ")") ix_parens--;
00388 if (ch0 == "[") ix_square++;
00389 if (ch0 == "]") ix_square--;
00390
00391
00392 if (ch0 == "\'" || ch0 == "\"") {
00393 size_t ix_d2 = line.find_first_of(ch0);
00394 if (ix_d2 == string::npos) return words;
00395 words.push_back(line.substr(0, ix_d2));
00396 line.erase(0, ix_d2+1);
00397 continue;
00398 }
00399
00400 words.push_back(ch0);
00401
00402
00403
00404
00405 } else {
00406 words.push_back(line.substr(0, ix_d));
00407 line.erase(0, ix_d);
00408 }
00409
00410 }
00411
00412 }
00413
00414
00415
00416
00417 string NodeID::toString () const {
00418
00419 string attrib_str;
00420 for (AttributeIDVecCIter ai = attribute.begin(); ai != attribute.end(); ai++) {
00421 string value = ai->value;
00422 if (value.find_first_of(" ,():=") != string::npos) value = "\'" + value + "\'";
00423
00424 string name = ai->name;
00425 if (name.find_first_of(" ,():=") != string::npos) name = "\'" + name + "\'";
00426
00427 if (ai != attribute.begin()) attrib_str += ", ";
00428
00429 if (value == "")
00430 attrib_str += name;
00431 else
00432 attrib_str += name + "=" + value;
00433 }
00434
00435 string node_str = name;
00436 if (node_str.find_first_of(" ,():=") != string::npos) node_str = "\'" + node_str + "\'";
00437
00438 if (attrib_str != "") node_str = node_str + "(" + attrib_str + ")";
00439
00440 return node_str;
00441
00442 }
00443
00444
00445
00446
00447 string Twig::toNodeString (bool include_target_attrib) {
00448
00449 string twig_str = "";
00450
00451 for (NodeIDVecCIter ni = nodeid_vec.begin(); ni != nodeid_vec.end(); ni++) {
00452 twig_str = twig_str + ":" + ni->toString();
00453 }
00454
00455 twig_str.erase(0,1);
00456
00457 if (include_target_attrib) twig_str += "@" + target_attribute;
00458
00459 return twig_str;
00460
00461 }
00462
00463
00464
00465
00466 string Twig::toString () {
00467
00468 string twig_str = toNodeString();
00469
00470
00471
00472
00473 if (target_attribute != "") twig_str = twig_str + "@" + target_attribute;
00474
00475 if (name != "" || !prefix.empty()) {
00476
00477 twig_str = "[" + twig_str + "]";
00478
00479 if (name == "" && prefix.empty())
00480 twig_str = "*" + twig_str;
00481 else if (name == "" && !prefix.empty())
00482 twig_str = "%" + twig_str;
00483 else
00484 twig_str = name + twig_str;
00485
00486 for (StrListCIter is = prefix.begin(); is != prefix.end(); is++) {
00487 twig_str = *is + "." + twig_str;
00488 }
00489
00490 }
00491
00492 return twig_str;
00493
00494 }
00495
00496
00497
00498
00499 UAPNode* Twig::getLocalSubNode (UAPNode* root, bool create) {
00500
00501 UAPNode* this_node = root;
00502
00503 for (NodeIDVecIter ni = nodeid_vec.begin(); ni != nodeid_vec.end(); ni++) {
00504 this_node = ni->getChild(this_node, create);
00505 if (!this_node) return NULL;
00506 }
00507
00508 return this_node;
00509
00510 }
00511
00512
00513
00514
00515 UAPNode* Twig::getLocalSubNode (UAPNode* root, string twig_str, bool create) {
00516
00517 Twig twig;
00518 if (!twig.fromString(twig_str)) return NULL;
00519 return twig.getLocalSubNode(root, create);
00520
00521 }
00522
00523
00524
00525
00526 NodeVec Twig::getSubNodes (UAPNode* root, string twig_str) {
00527
00528 Twig twig;
00529 NodeVec n_node;
00530 if (!twig.fromString(twig_str)) return n_node;
00531 return twig.getSubNodes(root);
00532
00533 }
00534
00535
00536
00537
00538 NodeVec Twig::getSubNodes (UAPNode* root) {
00539
00540
00541
00542
00543 NodeIDVec id_vec = nodeid_vec;
00544
00545 NodeID node0;
00546
00547 if (name == "") {
00548 node0 = id_vec.front();
00549 id_vec.erase(id_vec.begin());
00550 } else {
00551 node0.addAttribute("name", name);
00552 }
00553
00554
00555
00556 NodeVec node_vec;
00557 get_sub_nodes (root, node0, id_vec, node_vec);
00558 return node_vec;
00559
00560 }
00561
00562
00563
00564
00565 void Twig::get_sub_nodes (UAPNode* root,
00566 NodeID node0, NodeIDVec id_vec, NodeVec& node_vec) {
00567
00568 if (node0 == root) {
00569 Twig twig;
00570 twig.nodeid_vec = id_vec;
00571 twig.get_local_sub_nodes(root, id_vec, node_vec);
00572 }
00573
00574 NodeVec children = root->getChildren();
00575 for (NodeVecCIter in = children.begin(); in != children.end(); in++) {
00576 get_sub_nodes (*in, node0, id_vec, node_vec);
00577 }
00578
00579 return;
00580
00581 }
00582
00583
00584
00585
00586 void Twig::get_local_sub_nodes (UAPNode* root,
00587 NodeIDVec id_vec, NodeVec& node_vec) {
00588
00589 if (id_vec.empty()) {
00590 node_vec.push_back(root);
00591 return;
00592 }
00593
00594 NodeID node0 = id_vec.front();
00595 id_vec.erase(id_vec.begin());
00596
00597 NodeVec children = root->getChildren();
00598 for (NodeVecIter ni = children.begin(); ni != children.end(); ni++) {
00599 UAPNode* child = *ni;
00600 if (!(node0 == child)) continue;
00601 if (id_vec.empty())
00602 node_vec.push_back(child);
00603 else
00604 get_local_sub_nodes (child, id_vec, node_vec);
00605 }
00606
00607 return;
00608
00609 }
00610
00611
00612
00613
00614 UAPNode* Twig::getSubNode (UAPNode* root) {
00615
00616
00617
00618 NodeIDVec id_vec = nodeid_vec;
00619
00620 NodeID node0;
00621
00622 if (name == "") {
00623 node0 = id_vec.front();
00624 id_vec.erase(id_vec.begin());
00625 } else {
00626 node0.addAttribute("name", name);
00627 }
00628
00629
00630
00631 return get_sub_node (root, node0, id_vec);
00632
00633 }
00634
00635
00636
00637
00638 UAPNode* Twig::get_sub_node (UAPNode* root, NodeID node0, NodeIDVec id_vec) {
00639
00640 if (node0 == root) {
00641 Twig twig;
00642 twig.nodeid_vec = id_vec;
00643 UAPNode* node = twig.getLocalSubNode(root);
00644 if (node) return node;
00645 }
00646
00647 NodeVec children = root->getChildren();
00648 for (NodeVecCIter in = children.begin(); in != children.end(); in++) {
00649 UAPNode* child = *in;
00650 UAPNode* node = get_sub_node (child, node0, id_vec);
00651 if (node) return node;
00652 }
00653
00654 return NULL;
00655
00656 }
00657
00658
00659
00660
00661 bool Twig::matchNameAndPrefix (UAPNode* named_node) {
00662
00663
00664
00665 string node_name = named_node->getAttributeString("name");
00666 if (node_name == "") return false;
00667 if (name == "") return false;
00668
00669 if (!matchName (name, node_name)) return false;
00670
00671
00672
00673 if (prefix.empty()) return true;
00674
00675
00676
00677 string node_prefix_str = named_node->getAttributeString("prefix");
00678 StrList node_prefix;
00679
00680 for (size_t ix = node_prefix_str.find('.'); ix != string::npos;
00681 ix = node_prefix_str.find('.')) {
00682 node_prefix.push_back(node_prefix_str.substr(0, ix));
00683 node_prefix_str = node_prefix_str.substr(ix+1);
00684 }
00685 node_prefix.push_back(node_prefix_str);
00686
00687
00688
00689 return matchPrefix (prefix, prefix.begin(), node_prefix, node_prefix.begin());
00690
00691 }
00692
00693
00694
00695
00696 bool Twig::matchName (string twig_name, string node_name) {
00697
00698 if (twig_name.empty() && node_name.empty()) return true;
00699
00700
00701
00702 if (twig_name[0] == '*') {
00703 if (twig_name.size() == 1) return true;
00704 if (matchName (twig_name.substr(1), node_name)) return true;
00705 if (node_name.size() < 2) return false;
00706 return matchName(twig_name, node_name.substr(1));
00707 }
00708
00709 if (twig_name.empty() || node_name.empty()) return false;
00710
00711
00712
00713 if (twig_name[0] != '?' && twig_name[0] != node_name[0]) return false;
00714 if (twig_name.size() == 1) {
00715 if (node_name.size() == 1) return true;
00716 else return false;
00717 }
00718
00719
00720
00721
00722 if (node_name.size() == 1)
00723 return (twig_name.find_first_not_of('*', 1) == string::npos);
00724 else
00725 return matchName(twig_name.substr(1), node_name.substr(1));
00726
00727 }
00728
00729
00730
00731
00732 bool Twig::matchPrefix (StrList& twig_prefix, StrListCIter twig_iter,
00733 StrList& node_prefix, StrListCIter node_iter) {
00734
00735
00736
00737 string node0 = *node_iter;
00738 string twig0 = *twig_iter;
00739
00740 StrListCIter node1_iter = node_iter;
00741 node1_iter++;
00742 bool node0_is_last = (node1_iter == node_prefix.end());
00743
00744 StrListCIter twig1_iter = twig_iter;
00745 twig1_iter++;
00746 bool twig0_is_last = (twig1_iter == twig_prefix.end());
00747
00748
00749
00750
00751 if (twig0 == ".") {
00752 if (twig0_is_last) return true;
00753 if (matchPrefix (twig_prefix, twig1_iter, node_prefix, node_iter));
00754 if (node0_is_last) return false;
00755 return (matchPrefix (twig_prefix, twig_iter, node_prefix, node1_iter));
00756 }
00757
00758
00759
00760 if (!matchName (twig0, node0)) return false;
00761
00762 if (twig0_is_last) {
00763 if (node0_is_last) return true;
00764 else return false;
00765 }
00766
00767 if (node0_is_last) {
00768 for (twig1_iter++; twig1_iter != twig_prefix.end(); twig1_iter++) {
00769 if (*twig1_iter != ".") return false;
00770 }
00771 return true;
00772 } else
00773 return matchPrefix (twig_prefix, twig1_iter, node_prefix, node1_iter);
00774
00775 }
00776
00777
00778
00779
00780 bool Twig::operator== (Twig t) {
00781
00782 if (!(nodeid_vec == t.nodeid_vec)) return false;
00783 if (!(name == t.name)) return false;
00784 if (prefix.size() != t.prefix.size()) return false;
00785
00786 StrListCIter it = t.prefix.begin();
00787 for (StrListCIter is = prefix.begin(); is != prefix.end(); is++) {
00788 if (is != it) return false;
00789 it++;
00790 }
00791
00792 return (target_attribute == t.target_attribute);
00793
00794 }
00795