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
00031
00032
00033
00034
00035
00043
00044
00045 #include <cstdio>
00046 #include <iostream>
00047
00048 #include <memory>
00049 #include <algorithm>
00050
00051 #include "../OpenTracker.h"
00052
00053
00054 #include "../tool/XMLSelection.h"
00055
00056 #ifdef USE_XERCES
00057 #include <xercesc/dom/DOM.hpp>
00058 #include <xercesc/util/XMLString.hpp>
00059 #include <xercesc/util/XMLUniDefs.hpp>
00060 #endif //USE_XERCES
00061
00062 #include "Node.h"
00063 #include "StringTable.h"
00064 #include "Context.h"
00065
00066
00067
00068 #ifdef USE_XERCES
00069 #define ELEMENT(a) ((XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *)a)
00070 XERCES_CPP_NAMESPACE_USE
00071 #endif //USE_XERCES
00072
00073 #ifdef USE_TINYXML
00074 #define ELEMENT(a) ((TiXmlElement*)a)
00075 #endif //USE_TINYXML
00076
00077 namespace ot {
00078
00079
00080
00081
00082 extern const std::string empty("");
00083
00084 #ifdef USE_XERCES
00085 const XMLCh ud_node[] = { chLatin_n, chLatin_o, chLatin_d, chLatin_e, chNull };
00086 #endif //USE_XERCES
00087
00088
00089
00090 Node::Node() : name("")
00091 {
00092 parent = NULL;
00093 }
00094
00095
00096
00097 Node::~Node()
00098 {
00099 references.clear();
00100 if( parent != NULL )
00101 {
00102 #ifdef USE_XERCES
00103 try {
00104 ELEMENT(parent)->release();
00105 }
00106 catch(DOMException &)
00107 {
00108 }
00109 #endif //USE_XERCES
00110
00111 #ifdef USE_TINYXML
00112 delete ELEMENT(parent);
00113 #endif //USE_TINYXML
00114 }
00115 }
00116
00117
00118
00119 void Node::setParent( void * parElement )
00120 {
00121 #ifdef USE_XERCES
00122 parent = parElement;
00123 ELEMENT(parent)->setUserData( ud_node, this, NULL );
00124 char * temp = XMLString::transcode(ELEMENT(parent)->getLocalName());
00125 type = temp;
00126 XMLString::release( &temp );
00127 #endif //USE_XERCES
00128
00129 #ifdef USE_TINYXML
00130 parent = parElement;
00131 ELEMENT(parent)->SetUserData(this);
00132 const char* temp = ELEMENT(parent)->Value();
00133 type = temp;
00134 #endif //USE_TINYXML
00135 }
00136
00137
00138
00139 void Node::addReference( Node * reference )
00140 {
00141 references.push_back( reference );
00142 }
00143
00144
00145
00146 void Node::removeReference( Node * reference )
00147 {
00148 NodeVector::iterator result = std::find( references.begin(), references.end(),
00149 reference );
00150 if( result != references.end())
00151 {
00152 references.erase( result );
00153 }
00154 }
00155
00156
00157
00158 Node * Node::getParent()
00159 {
00160 #ifdef USE_XERCES
00161 DOMNode * parentElement = ELEMENT(parent)->getParentNode();
00162 if( parentElement != 0 )
00163 {
00164 return (Node *)parentElement->getUserData(ud_node);
00165 }
00166 return NULL;
00167 #endif //USE_XERCES
00168
00169 #ifdef USE_TINYXML
00170 TiXmlNode * parentElement = ELEMENT(parent)->Parent();
00171 if( parentElement != 0 )
00172 {
00173 return (Node *)parentElement->GetUserData();
00174 }
00175 return NULL;
00176 #endif //USE_TINYXML
00177 }
00178
00179
00180
00181 Context * Node::getContext() const
00182 {
00183 #ifdef USE_XERCES
00184 DOMDocument * doc = ELEMENT(parent)->getOwnerDocument();
00185 if( doc != 0)
00186 {
00187 return (Context *)doc->getUserData(ud_node);
00188 }
00189 return NULL;
00190 #endif //USE_XERCES
00191
00192 #ifdef USE_TINYXML
00193 TiXmlDocument * doc = ELEMENT(parent)->GetDocument();
00194 if( doc != 0)
00195 {
00196 return (Context *)doc->GetUserData();
00197 }
00198 return NULL;
00199 #endif //USE_TINYXML
00200 }
00201
00202
00203
00204 unsigned int Node::countChildren()
00205 {
00206 #ifdef USE_XERCES
00207 DOMNode * node = ELEMENT(parent)->getFirstChild();
00208 unsigned int count = 0;
00209 while( node != NULL )
00210 {
00211 Node * myNode = (Node *)node->getUserData(ud_node);
00212 if( myNode != NULL )
00213 {
00214 if( myNode->isNodePort() == 0 )
00215 count ++;
00216 }
00217 node = node->getNextSibling();
00218 }
00219 return count;
00220 #endif //USE_XERCES
00221
00222 #ifdef USE_TINYXML
00223 TiXmlNode * node = ELEMENT(parent)->FirstChild();
00224 unsigned int count = 0;
00225 while( node != NULL )
00226 {
00227 Node * myNode = (Node *)node->GetUserData();
00228 if( myNode != NULL )
00229 {
00230 if( myNode->isNodePort() == 0 )
00231 count ++;
00232 }
00233 node = node->NextSibling();
00234 }
00235 return count;
00236 #endif //USE_TINYXML
00237 }
00238
00239
00240
00241 Node::error Node::addChild(Node & child)
00242 {
00243 #ifdef USE_XERCES
00244 try {
00245 ELEMENT(parent)->appendChild( ELEMENT(child.parent));
00246 }
00247 catch( DOMException e )
00248 {
00249 return GRAPH_CONSTRAINT;
00250 }
00251 return OK;
00252 #endif //USE_XERCES
00253
00254 #ifdef USE_TINYXML
00255 ELEMENT(parent)->InsertEndChild( *ELEMENT(child.parent));
00256 return OK;
00257 #endif //USE_TINYXML
00258 }
00259
00260
00261
00262 Node::error Node::removeChild(Node & child)
00263 {
00264 #ifdef USE_XERCES
00265 try {
00266 ELEMENT(parent)->removeChild( ELEMENT(child.parent));
00267 }
00268 catch( DOMException e )
00269 {
00270 return NOT_FOUND;
00271 }
00272 return OK;
00273 #endif //USE_XERCES
00274
00275 #ifdef USE_TINYXML
00276 ELEMENT(parent)->RemoveChild( ELEMENT(child.parent));
00277 return OK;
00278 #endif //USE_TINYXML
00279 }
00280
00281
00282
00283 Node * Node::getChild( unsigned int index )
00284 {
00285 #ifdef USE_XERCES
00286 Node * myNode = NULL;
00287 DOMNode * node = ELEMENT(parent)->getFirstChild();
00288 while( node != NULL )
00289 {
00290 myNode = (Node *)node->getUserData(ud_node);
00291 if( myNode != NULL )
00292 if( myNode->isNodePort() == 0 )
00293 if( index == 0 )
00294 return myNode;
00295 else
00296 index--;
00297 node = node->getNextSibling();
00298 }
00299 return NULL;
00300 #endif //USE_XERCES
00301
00302 #ifdef USE_TINYXML
00303 Node * myNode = NULL;
00304 TiXmlNode * node = ELEMENT(parent)->FirstChild();
00305 while( node != NULL )
00306 {
00307 myNode = (Node *)node->GetUserData();
00308 if( myNode != NULL )
00309 if( myNode->isNodePort() == 0 )
00310 if( index == 0 )
00311 return myNode;
00312 else
00313 index--;
00314 node = node->NextSibling();
00315 }
00316 return NULL;
00317 #endif //USE_TINYXML
00318 }
00319
00320
00321
00322 unsigned int Node::countPorts()
00323 {
00324 #ifdef USE_XERCES
00325 Node * myNode = NULL;
00326 unsigned int count = 0;
00327 DOMNode * node = ELEMENT(parent)->getFirstChild();
00328 while( node != NULL )
00329 {
00330 myNode = (Node *)node->getUserData(ud_node);
00331 if( myNode != NULL )
00332 if( myNode->isNodePort() == 1 )
00333 count++;
00334 node = node->getNextSibling();
00335 }
00336 return count;
00337 #endif //USE_XERCES
00338
00339 #ifdef USE_TINYXML
00340 Node * myNode = NULL;
00341 unsigned int count = 0;
00342 TiXmlNode * node = ELEMENT(parent)->FirstChild();
00343 while( node != NULL )
00344 {
00345 myNode = (Node *)node->GetUserData();
00346 if( myNode != NULL )
00347 if( myNode->isNodePort() == 1 )
00348 count++;
00349 node = node->NextSibling();
00350 }
00351 return count;
00352 #endif //USE_TINYXML
00353 }
00354
00355
00356
00357 NodePort * Node::getPort( const std::string & name, unsigned int index )
00358 {
00359 #ifdef USE_XERCES
00360 XMLCh * temp = XMLString::transcode( name.c_str());
00361 XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00362 DOMNodeList * list = ELEMENT(parent)->getElementsByTagNameNS( xmlspace, temp );
00363 XMLString::release( &temp );
00364 XMLString::release( &xmlspace );
00365 if( list->getLength() > index )
00366 {
00367 DOMElement * portElement = (DOMElement *) list->item(index);
00368 Node * port = (Node *)portElement->getUserData(ud_node);
00369 if( port != NULL )
00370 if( port->isNodePort() == 1 )
00371 return (NodePort *)port;
00372 }
00373 return NULL;
00374 #endif //USE_XERCES
00375
00376 #ifdef USE_TINYXML
00377 const char* temp = name.c_str();
00378 const char* xmlspace = getContext()->getRootNamespace().c_str();
00379 TiXmlNode * currentNode = NULL;
00380
00381 while(currentNode = ELEMENT(parent)->IterateChildren(temp, currentNode))
00382 {
00383 Node * port = (Node *)currentNode->GetUserData();
00384 if( port != NULL )
00385 if( port->isNodePort() == 1 )
00386
00387
00388 if( index == 0 )
00389 return (NodePort *) port;
00390 else
00391 index--;
00392
00393 }
00394
00395 return NULL;
00396 #endif //USE_TINYXML
00397 }
00398
00399
00400
00401 NodePort * Node::getPort( unsigned int index )
00402 {
00403 #ifdef USE_XERCES
00404 Node * myNode = NULL;
00405 DOMNode * node = ELEMENT(parent)->getFirstChild();
00406 while( NULL != node )
00407 {
00408 myNode = (Node *)node->getUserData(ud_node);
00409 if( myNode != NULL )
00410 if( myNode->isNodePort() == 1 )
00411 if( index == 0 )
00412 return (NodePort *) myNode;
00413 else
00414 index--;
00415 node = node->getNextSibling();
00416 }
00417 return NULL;
00418 #endif //USE_XERCES
00419
00420 #ifdef USE_TINYXML
00421 Node * myNode = NULL;
00422 TiXmlNode * node = ELEMENT(parent)->FirstChild();
00423 while( NULL != node )
00424 {
00425 myNode = (Node *)node->GetUserData();
00426 if( myNode != NULL )
00427 if( myNode->isNodePort() == 1 )
00428 if( index == 0 )
00429 return (NodePort *) myNode;
00430 else
00431 index--;
00432 node = node->NextSibling();
00433 }
00434 return NULL;
00435 #endif //USE_TINYXML
00436 }
00437
00438
00439
00440 Node::error Node::addPort( const std::string & name )
00441 {
00442 #ifdef USE_XERCES
00443 XMLCh * temp = XMLString::transcode( name.c_str());
00444 XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00445 DOMNodeList * list = ELEMENT(parent)->getElementsByTagNameNS( xmlspace, temp );
00446 XMLString::release( &temp );
00447 XMLString::release( &xmlspace );
00448 if( list->getLength() > 0 )
00449 {
00450 return GRAPH_CONSTRAINT;
00451 }
00452 DOMDocument * doc = ELEMENT(parent)->getOwnerDocument();
00453 Context * context = (Context *)doc->getUserData( ud_node );
00454 StringTable table;
00455 Node * node = context->createNode( name, table);
00456 if( node == NULL )
00457 return GRAPH_CONSTRAINT;
00458 return addChild( *node );
00459 #endif //USE_XERCES
00460
00461 #ifdef USE_TINYXML
00462 const char* temp = name.c_str();
00463 const char* xmlspace = getContext()->getRootNamespace().c_str();
00464 TiXmlNode * currentNode = NULL;
00465
00466 if(ELEMENT(parent)->FirstChild(temp))
00467 return GRAPH_CONSTRAINT;
00468
00469 TiXmlDocument * doc = ELEMENT(parent)->GetDocument();
00470 Context * context = (Context *)doc->GetUserData();
00471 StringTable table;
00472 Node * node = context->createNode( name, table);
00473 if( node == NULL )
00474 return GRAPH_CONSTRAINT;
00475 return addChild( *node );
00476 #endif //USE_TINYXML
00477 }
00478
00479
00480
00481 Node::error Node::removePort( const std::string & name )
00482 {
00483 #ifdef USE_XERCES
00484 NodePort * port = getPort( name );
00485 if( port == NULL )
00486 return NOT_FOUND;
00487 return removePort( *port );
00488 #endif //USE_XERCES
00489
00490 #ifdef USE_TINYXML
00491 NodePort * port = getPort( name );
00492 if( port == NULL )
00493 return NOT_FOUND;
00494 return removePort( *port );
00495 #endif //USE_TINYXML
00496 }
00497
00498
00499
00500 Node::error Node::removePort( unsigned int index )
00501 {
00502 #ifdef USE_XERCES
00503 NodePort * port = getPort( index );
00504 if( port == NULL )
00505 return NOT_FOUND;
00506 return removePort( *port );
00507 #endif //USE_XERCES
00508
00509 #ifdef USE_TINYXML
00510 NodePort * port = getPort( index );
00511 if( port == NULL )
00512 return NOT_FOUND;
00513 return removePort( *port );
00514 #endif //USE_TINYXML
00515 }
00516
00517 Node::error Node::removePort( NodePort & port)
00518 {
00519 return removeChild((Node &) port );
00520 }
00521
00522
00523
00524 void Node::updateObservers( Event &data )
00525 {
00526 #ifdef USE_XERCES
00527 if( isEventGenerator() == 1 || isNodePort() == 1 )
00528 {
00529 DOMNode * parentElement = ELEMENT(parent)->getParentNode();
00530 if( NULL != parentElement )
00531 {
00532 ((Node *)parentElement->getUserData( ud_node ))->onEventGenerated( data, *this );
00533 }
00534 for( NodeVector::iterator it = references.begin(); it != references.end(); it++ )
00535 {
00536 (*it)->onEventGenerated( data, *this );
00537 }
00538 }
00539 #endif //USE_XERCES
00540
00541 #ifdef USE_TINYXML
00542 if( isEventGenerator() == 1 || isNodePort() == 1 )
00543 {
00544 TiXmlNode * parentElement = ELEMENT(parent)->Parent();
00545 if( NULL != parentElement )
00546 {
00547 ((Node *)parentElement->GetUserData())->onEventGenerated( data, *this );
00548 }
00549 for( NodeVector::iterator it = references.begin(); it != references.end(); it++ )
00550 {
00551 (*it)->onEventGenerated( data, *this );
00552 }
00553 }
00554 #endif //USE_TINYXML
00555 }
00556
00557
00558
00559 const std::string Node::get( const std::string & key ) const
00560 {
00561 #ifdef USE_XERCES
00562 XMLCh * temp = XMLString::transcode( key.c_str() );
00563 XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00564 const XMLCh * res = ELEMENT(parent)->getAttributeNS( xmlspace, temp );
00565 XMLString::release( &temp );
00566 XMLString::release( &xmlspace );
00567 char * cres = XMLString::transcode( res );
00568 std::string result( cres );
00569 XMLString::release( &cres );
00570 return result;
00571 #endif //USE_XERCES
00572
00573 #ifdef USE_TINYXML
00574 const char* temp = key.c_str();
00575 const char* xmlspace = getContext()->getRootNamespace().c_str();
00576 const char* res = ELEMENT(parent)->Attribute(temp);
00577 return std::string( res );
00578 #endif //USE_TINYXML
00579 }
00580
00581
00582
00583 void Node::put( const std::string & key, const std::string & value )
00584 {
00585 #ifdef USE_XERCES
00586 XMLCh * tempKey = XMLString::transcode( key.c_str() );
00587 XMLCh * tempValue = XMLString::transcode( value.c_str());
00588 XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00589 ELEMENT(parent)->setAttributeNS( xmlspace, tempKey, tempValue );
00590 XMLString::release( & tempKey );
00591 XMLString::release( & tempValue );
00592 XMLString::release( & xmlspace );
00593 #endif //USE_XERCES
00594
00595 #ifdef USE_TINYXML
00596 const char* tempKey = key.c_str();
00597 const char* tempValue = value.c_str();
00598 const char* xmlspace = getContext()->getRootNamespace().c_str();
00599 ELEMENT(parent)->SetAttribute( tempKey, tempValue);
00600 #endif //USE_TINYXML
00601 }
00602
00603
00604
00605 void Node::remove( const std::string & key )
00606 {
00607 #ifdef USE_XERCES
00608 XMLCh * tempKey = XMLString::transcode( key.c_str() );
00609 XMLCh * xmlspace = XMLString::transcode(getContext()->getRootNamespace().c_str());
00610 ELEMENT(parent)->removeAttributeNS( xmlspace, tempKey );
00611 XMLString::release( & tempKey );
00612 XMLString::release( & xmlspace );
00613 #endif //USE_XERCES
00614
00615 #ifdef USE_TINYXML
00616 const char* tempKey = key.c_str();
00617 const char* xmlspace = getContext()->getRootNamespace().c_str();
00618 ELEMENT(parent)->RemoveAttribute( tempKey );
00619 #endif //USE_TINYXML
00620 }
00621
00622
00623
00624 void Node::put(const std::string & key, const int value)
00625 {
00626 char buffer[20];
00627
00628 sprintf( buffer, "%i", value );
00629 put( key, buffer );
00630 }
00631
00632 void Node::put(const std::string & key, const float value)
00633 {
00634 char buffer[20];
00635
00636 sprintf( buffer, "%f", value );
00637 put( key, buffer );
00638 }
00639
00640 void Node::put(const std::string & key, const double value)
00641 {
00642 char buffer[30];
00643
00644 sprintf( buffer, "%lf", value );
00645 put( key, buffer );
00646 }
00647
00648 void Node::put(const std::string & key, const int * value, int len)
00649 {
00650 char buffer[20];
00651 std::string strvalue;
00652
00653 sprintf(buffer, "%i", value[0] );
00654 strvalue.append(buffer);
00655 for( int i = 1; i < len; i++ )
00656 {
00657 sprintf(buffer, " %i", value[i] );
00658 strvalue.append(buffer);
00659 }
00660 put( key, strvalue );
00661 }
00662
00663 void Node::put(const std::string & key, const float * value, int len)
00664 {
00665 char buffer[20];
00666 std::string strvalue;
00667
00668 sprintf(buffer, "%f", value[0] );
00669 strvalue.append(buffer);
00670 for( int i = 1; i < len; i++ )
00671 {
00672 sprintf(buffer, " %f", value[i] );
00673 strvalue.append(buffer);
00674 }
00675 put( key, strvalue );
00676 }
00677
00678 void Node::put(const std::string & key, const double * value, int len)
00679 {
00680 char buffer[20];
00681 std::string strvalue;
00682
00683 sprintf(buffer, "%lf", value[0] );
00684 strvalue.append(buffer);
00685 for( int i = 1; i < len; i++ )
00686 {
00687 sprintf(buffer, " %lf", value[i] );
00688 strvalue.append(buffer);
00689 }
00690 put( key, strvalue );
00691 }
00692
00693 int Node::get(const std::string & key, int * value, int len ) const
00694 {
00695 std::string data = get( key );
00696 const char * start = data.c_str();
00697 char * end = (char *)start;
00698 int count = 0;
00699 value[count++] = strtol( start, &end, 0 );
00700 while( end != start && count < len){
00701 start = end;
00702 value[count++] = strtol( start, &end, 0 );
00703 }
00704 return count;
00705 }
00706
00707 int Node::get(const std::string & key, float * value, int len ) const
00708 {
00709 std::string data = get( key );
00710 const char * start = data.c_str();
00711 char * end = (char *)start;
00712 int count = 0;
00713 value[count++] = (float)strtod( start, &end );
00714 while( end != start && count < len){
00715 start = end;
00716 value[count++] = (float)strtod( start, &end );
00717 }
00718 return count;
00719 }
00720
00721 int Node::get(const std::string & key, double * value, int len ) const
00722 {
00723 std::string data = get( key );
00724 const char * start = data.c_str();
00725 char * end = (char *)start;
00726 int count = 0;
00727 value[count++] = strtod( start, &end );
00728 while( end != start && count < len){
00729 start = end;
00730 value[count++] = strtod( start, &end );
00731 }
00732 return count;
00733 }
00734
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751