Open
Graph Drawing
Framework

 v.2012.05
 

OgmlParser.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00044 #ifdef _MSC_VER
00045 #pragma once
00046 #endif
00047 
00048 //KK: Commented out the compound and constraint stuff using //o
00049 
00050 #ifndef OGDF_OGMLPARSER_H
00051 #define OGDF_OGMLPARSER_H
00052 
00053 #include <ogdf/fileformats/Ogml.h>
00054 #include <ogdf/fileformats/DinoXmlParser.h>
00055 #include <ogdf/basic/Hashing.h>
00056 #include <ogdf/basic/List.h>
00057 #include <ogdf/basic/String.h>
00058 // graph types
00059 #include <ogdf/cluster/ClusterGraph.h>
00060 //o#include <ogdf/CompoundGraph.h>
00061 // graph attributes
00062 #include <ogdf/basic/GraphAttributes.h>
00063 #include <ogdf/cluster/ClusterGraphAttributes.h>
00064 //o#include <ogdf/CompoundGraphAttributes.h>
00065 // constraints
00066 //o#include <ogdf/Constraints.h>
00067 // stdlib for converting strings to basic types
00068 #include <stdlib.h>
00069 #include <stdarg.h>
00070 #include <sstream>
00071 
00072 namespace ogdf {
00073     
00074     // struct definitions for mapping of templates  
00075     struct OgmlNodeTemplate{ 
00076         String m_id;
00077         int m_shapeType;
00078         double m_width;
00079         double m_height;
00080         String m_color;
00081         GraphAttributes::BrushPattern m_pattern;
00082         String m_patternColor;
00083         GraphAttributes::EdgeStyle m_lineType;
00084         double m_lineWidth;
00085         String m_lineColor;
00086         // nodeTemplate stores the graphical type
00087         // e.g. rectangle, ellipse, hexagon, ...
00088         String m_nodeTemplate;
00089         
00090         //Constructor:
00091         OgmlNodeTemplate(String id): m_id(id) {};
00092     };//struct OgmlNodeTemplate
00093     
00094     struct OgmlEdgeTemplate{
00095         String m_id;
00096         GraphAttributes::EdgeStyle m_lineType;
00097         double m_lineWidth;
00098         String m_color;
00099         int m_sourceType; // actually this is only a boolean value 0 or 1
00100         // ogdf doesn't support source-arrow-color and size
00101 //      String m_sourceColor;
00102 //      double m_sourceSize;
00103         int m_targetType; // actually this is only a boolean value 0 or 1
00104         // ogdf doesn't support target-arrow-color and size
00105 //      String m_targetColor;
00106 //      double m_targetSize;
00107         
00108         //Constructor:
00109         OgmlEdgeTemplate(String id): m_id(id) {};   
00110     };//struct OgmlEdgeTemplate
00111 
00112 
00113 //  struct OgmlLabelTemplate{
00114 //      String m_id;
00115 //  };//struct OgmlLabelTemplate
00116 
00117     struct OgmlSegment{
00118         DPoint point1, point2;
00119     };
00120     
00121     
00122     //
00123     // ---------- O g m l A t t r i b u t e V a l u e ------------------------
00124     //
00125     
00128     class OgmlAttributeValue {
00129         
00133         int id;
00134         
00135         public:
00136             //Construction
00137             OgmlAttributeValue() : id(av_any) {}
00138             OgmlAttributeValue(int id) {
00139                 if(id>=0 && id<ATT_VAL_NUM) this->id = id;
00140                 else id = av_any;
00141             }
00142             //Destruction
00143             ~OgmlAttributeValue() {}
00144             //Getter
00145             const int& getId() const { return id; }
00146             const String& getValue() const { return ogmlAttributeValueNames[id]; }      
00147             //Setter
00148             void setId(int id) {
00149                 if(id>=0 && id<ATT_VAL_NUM) this->id = id;
00150                 else id = av_any;
00151             }           
00152 
00153             
00154             /* Checks the type of the input given in string
00155              * and returns an OgmlAttributeValueId defined in Ogml.h
00156              */ 
00157             OgmlAttributeValueId getTypeOfString(const String& input) const {
00158                 
00159                 // |--------------------|
00160                 // | char | ascii-value |
00161                 // |--------------------|
00162                 // | '.'  |     46      |
00163                 // | '-'  |     45      |
00164                 // | '+'  |     43      |
00165                 // | '#'  |     35      |
00166                 
00167                 // bool values
00168                 bool isInt = true;
00169                 bool isNum = true;
00170                 bool isHex = true;
00171                 // value for point seperator
00172                 bool numPoint = false;  
00173                 
00174                 // input is a boolean value
00175                 if (input == "true" || input == "false" /*|| input == "0" || input == "1"*/)
00176                     return av_bool;
00177     
00178                 if (input.length() > 0){
00179                     char actChar = input[0];
00180                     int actCharInt = static_cast<int>(actChar); 
00181                     //check the first char
00182                     if (!isalnum(actChar)){
00183 
00184                         if ((actCharInt == 35)){
00185                             // support hex values with starting "#"
00186                             isInt = false;
00187                             isNum = false;
00188                         }
00189                         else
00190                             {
00191     
00192                             // (actChar != '-') and (actChar != '+')
00193                             if (!(actCharInt == 45) && !(actChar == 43)){
00194                                 isInt = isNum = false;
00195                             }
00196                             else
00197                             {
00198                                 // input[0] == '-' or '+'
00199                                 if (input.length() > 1){
00200                                     // 2nd char have to be a digit or xdigit
00201                                     actChar = input[1];
00202                                     actCharInt = static_cast<int>(actChar);
00203                                     if (!isdigit(actChar)){
00204                                         isInt = false;
00205                                         isNum = false;
00206                                         if (!isxdigit(actChar))
00207                                             return av_string;
00208                                     }
00209                                 }
00210                                 else
00211                                     return av_string;
00212                             } // else... (input[0] == '-')
00213                         }
00214                     }
00215                     else{               
00216                         if (!isdigit(actChar)){
00217                             isInt = false;  
00218                             isNum = false;
00219                         }
00220                         if (!isxdigit(actChar)){
00221                             isHex = false;
00222                         }
00223                     }
00224                     
00225                     // check every input char
00226                     // and set bool value to false if char-type is wrong
00227                     for(size_t it=1; ( (it<input.length()) && ((isInt) || (isNum) || (isHex)) ); it++)
00228                     {
00229                         actChar = input[it];
00230                         actCharInt = static_cast<int>(actChar);
00231                         
00232                         // actChar == '.'
00233                         if (actChar == 46){
00234                             isInt = false;
00235                             isHex = false;
00236                             if (!numPoint){
00237                                 numPoint = true;
00238                             }
00239                             else
00240                                 isNum = false;
00241                         }// if (actChar == '.')
00242                         else {
00243                             if (!(isdigit(actChar))){
00244                                 isInt = false;
00245                                 isNum = false;
00246                             }
00247                             if (!(isxdigit(actChar)))
00248                                 isHex = false;
00249                         }//else... (actChar != '.')
00250                     }//for
00251                 }//if (input.length() > 0)
00252                 else{
00253                     // input.length() == 0
00254                     return av_none; 
00255                 }
00256                 // return correct value
00257                 if (isInt) return av_int;
00258                 if (isNum) return av_num;
00259                 if (isHex) return av_hex;
00260                 // if all bool values are false return av_string
00261                 return av_string;
00262                 
00263             }//getTypeOfString
00264                     
00265                     
00278             int validValue(const String &attributeValue, 
00279                            const XmlTagObject* xmlTag,              //owns an attribute with attributeValue
00280                            Hashing<String, const XmlTagObject*>& ids) const  {  //hashtable with id-tagName pairs
00281                 
00282                 //get attribute value type of string
00283                 OgmlAttributeValueId stringType = getTypeOfString(attributeValue);
00284 
00285                 HashElement<String, const XmlTagObject*>* he;
00286                 
00287                 int valid = vs_attValueErr;
00288                 
00289                 switch(id) {
00290                     case av_any: {
00291                         valid = vs_valid;
00292                         break;
00293                     }
00294                     case av_int: {
00295                         if (stringType == av_int) valid = vs_valid;
00296                         break;
00297                     }
00298                     case av_num: {
00299                         if (stringType == av_num) valid = vs_valid;
00300                         if (stringType == av_int) valid = vs_valid;
00301                         break;
00302                     }
00303                     case av_bool: {
00304                         if (stringType == av_bool) valid = vs_valid;
00305                         break;
00306                     }
00307                     case av_string: {
00308                         valid = vs_valid;
00309                         break;
00310                     }
00311                     case av_hex: {
00312                         if (stringType == av_hex) valid = vs_valid;
00313                         if (stringType == av_int) valid = vs_valid;
00314                         break;
00315                     }
00316                     case av_oct: {
00317                         valid = vs_attValueErr;
00318                         break;
00319                     }
00320                     case av_id: {
00321                         //id mustn't exist
00322                         if( !(he = ids.lookup(attributeValue)) ) {
00323                             ids.fastInsert(attributeValue, xmlTag);
00324                             valid = vs_valid;
00325                         }
00326                         else valid = vs_idNotUnique;
00327                         break;
00328                     }
00329     
00330                      //attribute idRef of elements source, target, nodeRef, nodeStyle    
00331                     case av_nodeIdRef: {
00332                         //element exists && is tagname expected
00333                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_node]) ) valid = vs_valid;
00334                         else valid = vs_idRefErr;
00335                         break;  
00336                     }
00337                     //attribute idRef of elements edgeRef, edgeStyle
00338                     case av_edgeIdRef: {
00339                         //element exists && is tagname expected
00340                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_edge]) ) valid = vs_valid;
00341                         else valid = vs_idRefErr;
00342                         break;  
00343                     }
00344                     //attribute idRef of elements labelRef, labelStyle
00345                     case av_labelIdRef: {
00346                         //element exists && is tagname expected
00347                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_label]) ) valid = vs_valid;
00348                         else valid = vs_idRefErr;
00349                         break;  
00350                     }
00351                     //attribute idRef of element endpoint
00352                     case av_sourceIdRef: {
00353                         //element exists && is tagname expected
00354                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_source]) ) valid = vs_valid;
00355                         else valid = vs_idRefErr;
00356                         break;  
00357                     }
00358                     //attribute idRef of element endpoint
00359                     case av_targetIdRef: {
00360                         //element exists && is tagname expected
00361                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_target]) ) valid = vs_valid;
00362                         else valid = vs_idRefErr;
00363                         break;  
00364                     }
00365                     //attribute idRef of subelement template of element nodeStyle
00366                     case av_nodeStyleTemplateIdRef: {
00367                         //element exists && is tagname expected
00368                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_nodeStyleTemplate]) ) valid = vs_valid;
00369                         else valid = vs_idRefErr;
00370                         break;  
00371                     }
00372                     //attribute idRef of subelement template of element edgeStyle
00373                     case av_edgeStyleTemplateIdRef: {
00374                         //element exists && is tagname expected
00375                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_edgeStyleTemplate]) ) valid = vs_valid;
00376                         else valid = vs_idRefErr;
00377                         break;
00378                     }
00379                     //attribute idRef of subelement template of element labelStyle
00380                     case av_labelStyleTemplateIdRef: {
00381                         //element exists && is tagname expected
00382                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_labelStyleTemplate]) ) valid = vs_valid;
00383                         else valid = vs_idRefErr;
00384                         break;
00385                     }
00386                     case av_pointIdRef: {
00387                         //element exists && is tagname expected
00388                         if( (he = ids.lookup(attributeValue)) && (he->info()->getName() == ogmlTagNames[t_point]) ) valid = vs_valid;
00389                         else valid = vs_idRefErr;
00390                         break;
00391                     }
00392                     default: {
00393                         //Proof string for equality
00394                         if(getValue() == attributeValue) valid = vs_valid;
00395                         break;
00396                     }
00397                 }
00398                 
00399                 return valid;
00400             }
00401         
00402     };//class OgmlAttributeValue
00403     
00404     
00405     
00406     
00407     
00408     //
00409     // ---------- O g m l A t t r i b u t e ------------------------
00410     //
00411     
00414     class OgmlAttribute {
00415         
00419         int id;
00422         List<OgmlAttributeValue*> values;
00423         
00424         public:
00425 
00426             //Construction
00427             OgmlAttribute() : id(a_none), values() {}
00428             OgmlAttribute(int id) : values() {
00429                 if(id>=0 && id<ATT_NUM) this->id = id;
00430                 else this->id = a_none;
00431             }
00432             //Destruction
00433             ~OgmlAttribute() {}
00434             //Getter
00435             const int& getId() const { return id; }
00436             const String& getName() const { return ogmlAttributeNames[id]; }
00437             const List<OgmlAttributeValue*>& getValueList() const { return values; }
00438             
00439             //Setter
00440             void setId(int id) {
00441                 if(id>=0 && id<ATT_NUM) this->id = id;
00442                 else this->id = a_none;
00443             }
00444     
00451              void pushValues(Hashing<int, OgmlAttributeValue> &val, int key, ...) {
00452                 va_list argp;
00453                 int arg = key;
00454                 HashElement<int, OgmlAttributeValue>* he;
00455                 va_start(argp, key);
00456                 while(arg!=-1) {
00457                     if((he = val.lookup(arg))) values.pushBack( &(he->info()) );
00458                     arg = va_arg(argp,int);
00459                 }
00460                 va_end(argp);
00461             }
00462         
00465             void print(ostream &os) const {
00466                 ListConstIterator<OgmlAttributeValue*> it;
00467                 os << "\"" << getName() << "\"={ ";
00468                 for(it = values.begin(); it.valid(); it++) {
00469                     os << (**it).getValue() << " ";
00470                 }
00471                 os << "}\n";
00472             }
00473         
00480             int validAttribute(const XmlAttributeObject &xmlAttribute,
00481                                const XmlTagObject* xmlTag,
00482                                Hashing<String, const XmlTagObject*>& ids) const {
00483                                 
00484                 int valid = vs_expAttNotFound;
00485                 
00486                 if( xmlAttribute.getName() == getName() ) {
00487                     ListConstIterator<OgmlAttributeValue*> it;
00488                     for(it = values.begin(); it.valid(); it++) {
00489                         if ( (valid = (**it).validValue( xmlAttribute.getValue(), xmlTag, ids )) == vs_valid ) break;
00490                     }
00491                 }
00492                 
00493                 return valid;
00494             }
00495             
00496         
00497     };//class OgmlAttribute
00498     
00499     /* Overloaded <<-operator to print an attribute.
00500      */
00501     ostream& operator<<(ostream& os, const OgmlAttribute& oa);
00502     
00503     
00504     
00505     //
00506     // ---------- O g m l T a g ------------------------
00507     //
00508     
00511     class OgmlTag {
00512         
00516         int id;
00519         int minOccurs, maxOccurs;
00524         bool ignoreContent;
00527         List<OgmlAttribute*> compulsiveAttributes;  
00531         List<OgmlAttribute*> choiceAttributes;
00534         List<OgmlAttribute*> optionalAttributes;
00535         
00536         List<OgmlTag*> compulsiveTags;
00537         
00538         List<OgmlTag*> choiceTags;
00539         
00540         List<OgmlTag*> optionalTags;    
00541         
00542         
00543         void printOwnedTags(ostream &os, int mode) const {
00544         
00545             String s;
00546             const List<OgmlTag*> *list;
00547             
00548             switch(mode) {
00549                 case 0: {
00550                     list = &compulsiveTags;
00551                     s+="compulsive";
00552                     break;
00553                 }
00554                 case 1: {
00555                     list = &choiceTags;
00556                     s+="selectable";
00557                     break;
00558                 }
00559                 case 2: {
00560                     list = &optionalTags;
00561                     s+="optional";
00562                     break;
00563                 }
00564             }
00565             
00566             if(list->empty()) os << "Tag \"<" << getName() <<">\" doesn't include " << s << " tag(s).\n";
00567             else {
00568                 os << "Tag \"<" << getName() <<">\" includes the following " << s << " tag(s): \n";
00569                 ListConstIterator<OgmlTag*> currTag;
00570                 for(currTag = list->begin(); currTag.valid(); currTag++) os << "\t<" << (**currTag).getName() << ">\n";
00571             }
00572         }       
00573         
00574         void printOwnedAttributes(ostream &os, int mode) const {
00575 
00576             String s;
00577             const List<OgmlAttribute*> *list;
00578             
00579             switch(mode) {
00580                 case 0: {
00581                     list = &compulsiveAttributes;
00582                     s+="compulsive";
00583                     break;
00584                 }
00585                 case 1: {
00586                     list = &choiceAttributes;
00587                     s+="selectable";
00588                     break;
00589                 }
00590                 case 2: {
00591                     list = &optionalAttributes;
00592                     s+="optional";
00593                     break;
00594                 }
00595             }
00596             
00597             if(list->empty()) os << "Tag \"<" << getName() <<">\" doesn't include " << s << " attribute(s).\n";
00598             else {
00599                 cout << "Tag \"<" << getName() <<">\" includes the following " << s << " attribute(s): \n";
00600                 ListConstIterator<OgmlAttribute*> currAtt;
00601                 for(currAtt = list->begin(); currAtt.valid(); currAtt++) os << "\t"  << (**currAtt);
00602             }   
00603         }
00604         
00605         
00606         public:
00607             
00608             bool ownsCompulsiveTags() {
00609                 return !compulsiveTags.empty(); 
00610             }
00611             
00612             bool ownsChoiceTags() {
00613                 return !choiceTags.empty(); 
00614             }
00615             
00616             bool ownsOptionalTags() {
00617                 return !optionalTags.empty();   
00618             }
00619             
00620             const List<OgmlTag*>& getCompulsiveTags() const {return compulsiveTags;}
00621             
00622             const List<OgmlTag*>& getChoiceTags() const {return choiceTags;}
00623             
00624             const List<OgmlTag*>& getOptionalTags() const {return optionalTags;}
00625 
00626             
00627             const int& getMinOccurs() const { return minOccurs; }
00628             
00629             const int& getMaxOccurs() const { return maxOccurs; }
00630 
00631             const bool& ignoresContent() const { return ignoreContent; }
00632             
00633             void setMinOccurs(int occurs) { minOccurs = occurs; }
00634             
00635             void setMaxOccurs(int occurs) { maxOccurs = occurs; }
00636             
00637             void setIgnoreContent(bool ignore) { ignoreContent = ignore; }
00638             
00639             //Construction
00640             OgmlTag() : id(t_none), ignoreContent(0) { }
00641             OgmlTag(int id) : id(t_none), ignoreContent(0) {
00642                 if(id>=0 && id<TAG_NUM) this->id = id;
00643                 else id = a_none;
00644             }
00645             //Destruction
00646             ~OgmlTag() {}
00647             //Getter
00648             const int& getId() const { return id; }
00649             const String& getName() const { return ogmlTagNames[id]; }
00650             //Setter    
00651             void setId(int id){
00652                 if(id>=0 && id<TAG_NUM) this->id = id;
00653                 else id = a_none;
00654             }
00655             
00656             
00657             void printOwnedTags(ostream& os) const {
00658                 printOwnedTags(os, 0);
00659                 printOwnedTags(os, 1);
00660                 printOwnedTags(os, 2);
00661             }
00662             
00663             void printOwnedAttributes(ostream& os) const {
00664                 printOwnedAttributes(os, 0);
00665                 printOwnedAttributes(os, 1);
00666                 printOwnedAttributes(os, 2);
00667             }
00668             
00675             void pushAttributes(int mode, Hashing<int, OgmlAttribute> &attrib, int key, ...) {
00676                 
00677                 List<OgmlAttribute*>* list;
00678                 
00679                 if(mode==0) list = &compulsiveAttributes;
00680                 else if(mode==1) list = &choiceAttributes;
00681                 else list = &optionalAttributes;
00682                 
00683                 va_list argp;
00684                 int arg = key;
00685                 HashElement<int, OgmlAttribute>* he;
00686                 va_start(argp, key);
00687                 while(arg!=-1) {
00688                     if((he = attrib.lookup(arg))) (*list).pushBack( &(he->info()) );
00689                     arg = va_arg(argp,int);
00690                 }
00691                 va_end(argp);
00692             }
00693             
00700             void pushTags(int mode, Hashing<int, OgmlTag> &tag, int key, ...) {
00701                 
00702                 List<OgmlTag*>* list;
00703                 
00704                 if(mode==0) list = &compulsiveTags;
00705                 else if(mode==1) list = &choiceTags;
00706                 else list = &optionalTags;
00707                 
00708                 va_list argp;
00709                 int arg = key;
00710                 HashElement<int, OgmlTag>* he;
00711                 va_start(argp, key);
00712                 
00713                 while(arg!=-1) {
00714                     if((he = tag.lookup(arg))) (*list).pushBack( &(he->info()) );
00715                     arg = va_arg(argp,int);
00716                 }
00717                 va_end(argp);
00718             }
00719             
00726             int validTag(const XmlTagObject &o,
00727                           Hashing<String, const XmlTagObject*>& ids) const {
00728                 
00729                 int valid = vs_unexpTag;
00730                 
00731                 if( o.getName() == getName() ) {
00732                     
00733                     ListConstIterator<OgmlAttribute*> it;
00734                     XmlAttributeObject* att;
00735                     
00736                     //Tag requires attributes
00737                     if(!compulsiveAttributes.empty()) {
00738                                             
00739                         for(it = compulsiveAttributes.begin(); it.valid(); it++) {
00740                             //Att not found or invalid
00741                             if(!o.findXmlAttributeObjectByName((**it).getName(), att) ) return valid = vs_expAttNotFound;
00742                             if( (valid = (**it).validAttribute(*att, &o, ids) ) <0 ) return valid;
00743                             //Att is valid
00744                             att->setValid();
00745                         }
00746                         
00747                     }
00748                     
00749                     //Choice attributes
00750                     if(!choiceAttributes.empty()) {
00751                         
00752                         bool tookChoice = false;
00753                         
00754                         for(it = choiceAttributes.begin(); it.valid(); it++) {
00755                             //Choice att found
00756                             if( o.findXmlAttributeObjectByName((**it).getName(), att) ) {
00757                                 //Proof if valid
00758                                 if( (valid = (**it).validAttribute(*att, &o, ids)) <0 ) return valid;
00759                                 tookChoice = true;
00760                                 att->setValid();
00761                             }
00762                         }
00763                         
00764                         if(!tookChoice) return valid = vs_expAttNotFound;
00765                         
00766                     }
00767                     
00768                     if(!optionalAttributes.empty() && !o.isAttributeLess()) {
00769                         
00770                         //Check optional attributes
00771                         for(it = optionalAttributes.begin(); it.valid(); it++) {
00772                             if( o.findXmlAttributeObjectByName((**it).getName(), att) ) {
00773                                 if( (valid = (**it).validAttribute(*att, &o, ids)) <0 ) return valid;
00774                                 att->setValid();
00775                             }
00776                         }
00777                     }
00778 
00779                     //Are there still invalid attributes?
00780                     att = o.m_pFirstAttribute;
00781                     while(att) {
00782                         if(!att->valid()) return valid = vs_unexpAtt;
00783                         att = att->m_pNextAttribute;
00784                     }
00785                     
00786                     valid = vs_valid;
00787                 }
00788                 
00789                 return valid;
00790                 
00791             }
00792         
00793 
00794         
00795         
00796     };//class OgmlTag
00797     
00798     /* Overloaded <<-operator to print a tag.
00799      */
00800     ostream& operator<<(ostream& os, const OgmlTag& ot);
00801     
00802     
00803         
00804     //
00805     // ---------- O g m l P a r s e r ------------------------
00806     //
00807     
00810     class OgmlParser {
00811     
00812     private:
00815         static Hashing<int, OgmlTag> tags;
00816         
00819         static Hashing<int, OgmlAttribute> attributes;
00820         
00823         static Hashing<int, OgmlAttributeValue> attValues;
00824         
00827         static bool hashTablesBuilt;
00828         
00831         static void buildHashTables();
00832         
00835         mutable GraphType graphType;    
00836         
00839         Hashing<String, const XmlTagObject*> ids;
00840         
00848         int validate(const XmlTagObject *xmlTag, int ogmlTag);
00849         
00853         //bool validate(const char* fileName);
00856         void printValidityInfo(const OgmlTag &ot,
00857                                 const XmlTagObject &xto,
00858                                 int valStatus,
00859                                 int line);
00860     
00866         //bool getXmlTagObjectById(XmlTagObject *recTag, String id, XmlTagObject *&xmlTag);
00867 
00872         bool checkGraphType(const XmlTagObject *xmlTag) const;
00873     
00876         //bool isHierarchical(XmlTagObject *xmlTag);
00877         bool isGraphHierarchical(const XmlTagObject *xmlTag) const;
00878     
00881         bool isNodeHierarchical(const XmlTagObject *xmlTag) const; 
00882         
00883         GraphType getGraphType() { return graphType; };
00884     
00885     
00886     // id hash tables
00887         // required variables for building
00888         // hash table with id from file and node
00889         Hashing<String, node> m_nodes;
00890         Hashing<String, edge> m_edges;
00891         Hashing<String, cluster> m_clusters;
00892 //o     Hashing<String, compound> m_compounds;
00893         // hash table for bend-points
00894         Hashing<String, DPoint> points;
00895         
00896         // hash table for checking uniqueness of ids
00897         // (key:) int = id in the created graph
00898         // (info:) String = id in the ogml file
00899         Hashing<int, String> m_nodeIds;
00900         Hashing<int, String> m_edgeIds;
00901         Hashing<int, String> m_clusterIds;
00902 //o     Hashing<int, String> m_compoundIds;
00903         
00904     // build methods
00905         // build graph
00906         //  ignores nodes which have hierarchical structure
00907         bool buildGraph(Graph &G);
00908         
00909         // build clusterGraph
00910         bool buildCluster(
00911                     const XmlTagObject *rootTag, 
00912                     Graph &G, 
00913                     ClusterGraph &CG);
00914         
00915         // recursive part of buildCluster
00916         bool buildClusterRecursive(
00917                     const XmlTagObject *xmlTag, 
00918                     cluster parent, 
00919                     Graph &G, 
00920                     ClusterGraph &CG);              
00921 
00922         // builds graph
00923         //  does not ignore hierarchical nodes
00924 //o     bool buildGraphForCompounds(Graph &G);
00925 
00926         // build compoundGraph
00927 //o     bool buildCompound(
00928 //o                 XmlTagObject *rootTag, 
00929 //o                 Graph &G, 
00930 //o                 CompoundGraph &CG);
00931         
00932         // recursive part of buildCompound
00933 //o     bool buildCompoundRecursive(
00934 //o                 XmlTagObject *xmlTag, 
00935 //o                 compound parent, 
00936 //o                 Graph &G, 
00937 //o                 CompoundGraph &CG); 
00938 
00939         // big attributed graph building method
00940         bool buildAttributedClusterGraph(
00941                     Graph &G, 
00942                     ClusterGraphAttributes &CGA, 
00943                     const XmlTagObject *root);
00944 
00945         // 2nd big attributed graph building method
00946 //o     bool buildAttributedCompoundGraph(
00947 //o                 Graph &G, 
00948 //o                 CompoundGraphAttributes &CGA, 
00949 //o                 XmlTagObject *root);
00950         
00951         // method for setting labels of clusters
00952         bool setLabelsRecursive(
00953                     Graph &G, 
00954                     ClusterGraphAttributes &CGA, 
00955                     XmlTagObject *root);
00956 
00957         // method for setting labels of compounds
00958 //o     bool setLabelsRecursiveForCompounds(
00959 //o                 Graph &G, 
00960 //o                 CompoundGraphAttributes &CGA, 
00961 //o                 XmlTagObject *root);
00962         
00963         // constraints-builder
00964 //o     bool buildConstraints(
00965 //o                 Graph& G, 
00966 //o                 GraphConstraints &GC);
00967         
00968         // helping pointer for constraints-loading
00969         // this pointer is set in the building methods
00970         // so we don't have to traverse the tree in buildConstraints
00971         XmlTagObject* m_constraintsTag;
00972                     
00973         // hashing lists for templates
00974         //  string = id
00975         Hashing<String, OgmlNodeTemplate*> m_ogmlNodeTemplates;
00976         Hashing<String, OgmlEdgeTemplate*> m_ogmlEdgeTemplates;
00977         //Hashing<String, OgmlLabelTemplate> m_ogmlLabelTemplates;
00978 
00979     // auxiliary methods for mapping graph attributes
00980         // returns int value for the pattern
00981         int getBrushPatternAsInt(String s);
00982         
00983         // returns the shape as an integer value
00984         int getShapeAsInt(String s);
00985         
00986         // maps the OGML attribute values to corresponding GDE values
00987         String getNodeTemplateFromOgmlValue(String s);
00988         
00989         // line type
00990         int getLineTypeAsInt(String s);
00991 
00992         // image style
00993         int getImageStyleAsInt(String s);
00994         
00995         // alignment of image
00996         int getImageAlignmentAsInt(String s);
00997         
00998         // arrow style, actually a "boolean" function
00999         //  because it returns only 0 or 1 according to GDE
01000         // sot <=> source or target
01001         int getArrowStyleAsInt(String s, String sot);
01002         
01003         // the matching method to getArrowStyleAsInt
01004         GraphAttributes::EdgeArrow getArrowStyle(int i);
01005         
01006         // function that operates on a string
01007         // the input string contains "&lt;" instead of "<"
01008         //  and "&gt;" instead of ">"
01009         //  to disable interpreting the string as xml-tags (by DinoXmlParser)
01010         // so this function substitutes  "<" for "&lt;"
01011         String getLabelCaptionFromString(String str);
01012         
01013         // returns the integer value of the id at the end of the string - if existent       
01014         bool getIdFromString(String str, int id);
01015         
01016         //validiation method
01017         void validate(const char* fileName);
01018         
01019     public:
01020         
01021         //Construction
01022         OgmlParser() { }
01023         //Destruction
01024         ~OgmlParser() {}
01025         
01026         
01027         /* Builds a graph from file with name fileName and saves
01028          * the graph in G.
01029          * Returns true when successful, false otherwise.
01030          */ 
01031         bool read(
01032                 const char* fileName, 
01033                 Graph &G, 
01034                 ClusterGraph &CG);
01035 
01036         bool read(
01037                 const char* fileName, 
01038                 Graph &G, 
01039                 ClusterGraph &CG,
01040                 ClusterGraphAttributes &CGA);
01041         
01042 //o     bool read(
01043 //o             const char* fileName, 
01044 //o             Graph &G, 
01045 //o             CompoundGraph &CG,
01046 //o             CompoundGraphAttributes &CGA);
01047 
01048 //o     bool read(
01049 //o             const char* fileName, 
01050 //o             Graph &G, 
01051 //o             CompoundGraph &CG,
01052 //o             CompoundGraphAttributes &CGA,
01053 //o             GraphConstraints &GC);
01054                 
01055     
01056     };//end class OGMLParser
01057     
01058 }//end namespace ogdf
01059 
01060 #endif
01061