XmlParser.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 // CERTI - HLA RunTime Infrastructure
00003 // Copyright (C) 2003-2006  ONERA
00004 //
00005 // This file is part of CERTI-libCERTI
00006 //
00007 // CERTI-libCERTI is free software ; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License
00009 // as published by the Free Software Foundation ; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // CERTI-libCERTI is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY ; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015 // Lesser General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this program ; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 // ----------------------------------------------------------------------------
00021 
00022 #include "XmlParser.hh"
00023 #include "ObjectClassSet.hh"
00024 #include "InteractionSet.hh"
00025 #include "ObjectClassAttribute.hh"
00026 #include "RoutingSpace.hh"
00027 #include "PrettyDebug.hh"
00028 
00029 using std::string ;
00030 using std::cerr ;
00031 using std::endl ;
00032 
00033 #ifdef HAVE_XML
00034 
00035 #define NODE_OBJECT_MODEL (const xmlChar*) "objectModel"
00036 #define NODE_OBJECTS (const xmlChar*) "objects"
00037 #define NODE_OBJECT_CLASS (const xmlChar*) "objectClass"
00038 #define NODE_INTERACTIONS (const xmlChar*) "interactions"
00039 #define NODE_INTERACTION_CLASS (const xmlChar*) "interactionClass"
00040 #define NODE_ATTRIBUTE (const xmlChar*) "attribute"
00041 #define NODE_PARAMETER (const xmlChar*) "parameter"
00042 #define NODE_ROUTING_SPACE (const xmlChar*) "routingSpace"
00043 #define NODE_DIMENSIONS (const xmlChar*) "dimensions"
00044 #define NODE_DIMENSION (const xmlChar*) "dimension"
00045 
00046 #define ATTRIBUTE_NAME (const xmlChar*) "name"
00047 #define ATTRIBUTE_TRANSPORTATION (const xmlChar*) "transportation"
00048 #define ATTRIBUTE_ORDER (const xmlChar*) "order"
00049 #define ATTRIBUTE_SPACE (const xmlChar*) "space"
00050 
00051 #define VALUE_RELIABLE (const xmlChar*) "HLAreliable"
00052 #define VALUE_BESTEFFORT (const xmlChar*) "HLAbestEffort"
00053 #define VALUE_TSO (const xmlChar*) "TimeStamp"
00054 #define VALUE_RO (const xmlChar*) "Receive"
00055 
00056 namespace certi {
00057 
00058 static pdCDebug D("XMLPARSER", "(XmlParser) ");
00059 
00060 XmlParser::XmlParser(RootObject* r)
00061 {
00062     root = r ;
00063 
00064     freeObjectClassHandle = 1 ;
00065     freeInteractionClassHandle = 1 ;
00066     freeAttributeHandle = 1 ;
00067     freeParameterHandle = 1 ;
00068     freeSpaceHandle = 1 ;
00069 }
00070 
00071 // ----------------------------------------------------------------------------
00072 RootObject*
00073 XmlParser::parse(string pathToXmlFile)
00074 {
00075     D.Out(pdTrace, "Starting to parse XML file");
00076     filename = pathToXmlFile;
00077 
00078     // transportation = HLAreliable
00079     // order = TimeStamp
00080 
00081     doc = xmlParseFile(filename.c_str());
00082 
00083     // Did libXML manage to parse the file ?
00084     if (doc == 0) {
00085         cerr << "XML file not parsed successfully" << endl ;
00086         xmlFreeDoc(doc);
00087         return 0 ;
00088     }
00089 
00090     // Is there a root element ?
00091     cur = xmlDocGetRootElement(doc);
00092     if (cur == 0) {
00093         cerr << "XML file is empty" << endl ;
00094         xmlFreeDoc(doc);
00095         return 0 ;
00096     }
00097 
00098     // Is this root element an objectModel ?
00099     if (xmlStrcmp(cur->name, (const xmlChar *) NODE_OBJECT_MODEL)) {
00100         cerr << "Wrong XML file: not the expected root node" << endl ;
00101         return 0 ;
00102     }
00103     D.Out(pdTrace, "XML file looks ok, starting main loop");
00104 
00105     // First Loop (Routing Spaces)
00106     cur = xmlDocGetRootElement(doc);
00107     cur = cur->xmlChildrenNode ;
00108     while (cur != NULL) {
00109         if ((!xmlStrcmp(cur->name, NODE_ROUTING_SPACE))) {
00110             D.Out(pdTrace, "Found a routing space");
00111             xmlNodePtr prev = cur ;
00112             this->parseRoutingSpace();
00113             cur = prev ;
00114         }
00115         cur = cur->next ;
00116     }
00117 
00118     // Second Loop (Object and Interaction classes)
00119     cur = xmlDocGetRootElement(doc);
00120     cur = cur->xmlChildrenNode ;
00121     while (cur != NULL) {
00122         if ((!xmlStrcmp(cur->name, NODE_OBJECTS))) {
00123             D.Out(pdTrace, "Found a group of object classes");
00124             xmlNodePtr prev = cur ;
00125             cur = cur->xmlChildrenNode ;
00126             while (cur != NULL) {
00127                 if ((!xmlStrcmp(cur->name, NODE_OBJECT_CLASS))) {
00128                     this->parseClass(0);
00129                 }
00130                 cur = cur->next ;
00131             }
00132             cur = prev ;
00133         }
00134         if ((!xmlStrcmp(cur->name, NODE_INTERACTIONS))) {
00135             D.Out(pdTrace, "Found a group of interaction classes");
00136             xmlNodePtr prev = cur ;
00137             cur = cur->xmlChildrenNode ;
00138             while (cur != NULL) {
00139                 if ((!xmlStrcmp(cur->name, NODE_INTERACTION_CLASS))) {
00140                     this->parseInteraction(0);
00141                 }
00142                 cur = cur->next ;
00143             }
00144             cur = prev ;
00145         }
00146         cur = cur->next ;
00147     }
00148 
00149     xmlFreeDoc(doc);
00150 
00151     D[pdTrace] << "XmlParser: finished parsing" << endl ;
00152     return root ;
00153 }
00154 
00155 // ----------------------------------------------------------------------------
00156 void
00157 XmlParser::parseClass(ObjectClass* parent)
00158 {
00159     D[pdTrace] << "New Object Class" << endl ;
00160 
00161     xmlNodePtr prev = cur ;
00162     /* note how objectHandle counter is incremented */
00163     ObjectClass* current = new ObjectClass(std::string(CleanXmlGetProp(cur,ATTRIBUTE_NAME)),freeObjectClassHandle++);
00164 
00165     root->addObjectClass(current, parent);
00166     cur = cur->xmlChildrenNode ;
00167     while (cur != NULL) {
00168         // Attributes
00169         if ((!xmlStrcmp(cur->name, NODE_ATTRIBUTE))) {
00170             std::string name = std::string(CleanXmlGetProp(cur,ATTRIBUTE_NAME));
00171             TransportType transport;
00172             OrderType order;
00173 
00174             // Transportation
00175             xmlChar* xtransport = xmlGetProp(cur, ATTRIBUTE_TRANSPORTATION);
00176             if (!xmlStrcmp(xtransport,VALUE_RELIABLE)) {
00177                 transport = RELIABLE ;
00178             }
00179             else {
00180                 if (!xmlStrcmp(xtransport,VALUE_BESTEFFORT)) {
00181                     transport = BEST_EFFORT ;
00182                 }
00183             }
00184             xmlFree(xtransport);
00185 
00186             // Order
00187             xmlChar* xorder = xmlGetProp(cur, ATTRIBUTE_ORDER);
00188             if (!xmlStrcmp(xorder, VALUE_TSO)) {
00189                 order = TIMESTAMP ;
00190             }
00191             else {
00192                 if (!xmlStrcmp(xorder, VALUE_RO)) {
00193                     order = RECEIVE ;
00194                 }
00195             }
00196             xmlFree(xorder);
00197             ObjectClassAttribute *attr = new ObjectClassAttribute(name,transport,order);
00198             // Routing space
00199             char *space = (char *) xmlGetProp(cur, ATTRIBUTE_SPACE);
00200             if (space) {
00201                 SpaceHandle h ;
00202                 try {
00203                     h = root->getRoutingSpaceHandle(string(space));
00204                 }
00205                 catch (Exception &e) {
00206                     cerr << "warning: Incorrect space name for attribute"
00207                          << endl ;
00208                 }
00209                 attr->setSpace(h);
00210             }
00211             xmlFree(space);
00212 
00213             // Attribute complete, adding to the class
00214             current->addAttribute(attr);
00215         }
00216         // Subclass
00217         if ((!xmlStrcmp(cur->name, NODE_OBJECT_CLASS))) {
00218             this->parseClass(current);
00219         }
00220         cur = cur->next ;
00221     }
00222     cur = prev ;
00223 }
00224 
00225 // ----------------------------------------------------------------------------
00226 void
00227 XmlParser::parseInteraction(Interaction* parent)
00228 {
00229     D[pdTrace] << "New Interaction Class" << endl;
00230     std::string name;
00231     TransportType transport;
00232     OrderType order;
00233 
00234     xmlNodePtr prev = cur ;
00235 
00236     // Name
00237     name = std::string(CleanXmlGetProp(cur,ATTRIBUTE_NAME));
00238 
00239     // Transportation
00240     xmlChar* xtransport = xmlGetProp(cur, ATTRIBUTE_TRANSPORTATION);
00241     if (!xmlStrcmp(xtransport, VALUE_RELIABLE)) {
00242         transport = RELIABLE ;
00243     }
00244     else {
00245         if (!xmlStrcmp(xtransport,VALUE_BESTEFFORT))  {
00246             transport = BEST_EFFORT ;
00247         }
00248     }
00249     xmlFree(xtransport);
00250 
00251     // Order
00252     xmlChar* xorder = xmlGetProp(cur, ATTRIBUTE_ORDER);
00253     if (!xmlStrcmp(xorder, VALUE_TSO)) {
00254         order = TIMESTAMP ;
00255     }
00256     else {
00257         if (!xmlStrcmp(xorder, VALUE_RO)) {
00258             order = RECEIVE ;
00259         }
00260     }
00261     xmlFree(xorder);
00262     Interaction* current = new Interaction(name,freeInteractionClassHandle++,transport,order);
00263 
00264     // Routing space
00265     char *space = (char *) xmlGetProp(cur, ATTRIBUTE_SPACE);
00266     if (space) {
00267         SpaceHandle h ;
00268         try {
00269             h = root->getRoutingSpaceHandle(string(space));
00270         }
00271         catch (Exception &e) {
00272             cerr << "warning: Incorrect space name for interaction"
00273                  << endl ;
00274         }
00275         current->setSpace(h);
00276     }
00277     xmlFree(space);
00278 
00279     // Add to interactions list, and build inheritance relation
00280     root->addInteractionClass(current,parent);
00281 
00282     cur = cur->xmlChildrenNode ;
00283     while (cur != NULL) {
00284         if ((!xmlStrcmp(cur->name, NODE_PARAMETER))) {
00285             Parameter *param = new Parameter();
00286             param->setName(CleanXmlGetProp(cur,ATTRIBUTE_NAME));
00287             param->setHandle(freeParameterHandle++);
00288             current->addParameter(param);
00289         }
00290         // Subinteraction
00291         if ((!xmlStrcmp(cur->name, NODE_INTERACTION_CLASS))) {
00292             this->parseInteraction(current);
00293         }
00294         cur = cur->next ;
00295     }
00296     cur = prev ;
00297 }
00298 
00299 // ----------------------------------------------------------------------------
00300 void
00301 XmlParser::parseRoutingSpace()
00302 {
00303     D[pdTrace] << "New Routing Space" << endl ;
00304 
00305     DimensionHandle freeDimensionHandle = 1 ;
00306     xmlNodePtr prev = cur ;
00307     RoutingSpace current ;
00308     current.setHandle(freeSpaceHandle++);
00309     current.setName(CleanXmlGetProp(cur,ATTRIBUTE_NAME));
00310 
00311     // Dimensions
00312     cur = cur->xmlChildrenNode ;
00313     while (cur != NULL) {
00314         if ((!xmlStrcmp(cur->name, NODE_DIMENSION))) {
00315             Dimension dimension(freeDimensionHandle++);
00316             dimension.setName(CleanXmlGetProp(cur,ATTRIBUTE_NAME));
00317             current.addDimension(dimension);
00318         }
00319         cur = cur->next ;
00320     }
00321     // Routing Space should be added after the
00322     // Dimension has been added since addRoutingSpace store a copy
00323     // of the object and not a reference
00324     // see bug #19534
00325     // https://savannah.nongnu.org/bugs/?19534
00326     root->addRoutingSpace(current);
00327 
00328     cur = prev ;
00329 }
00330 
00331 // ----------------------------------------------------------------------------
00332 bool
00333 XmlParser::exists()
00334 {
00335     return true;
00336 }
00337 
00338 } // namespace certi
00339 
00340 #else // !HAVE_XML
00341 
00342 namespace certi {
00343 
00344 XmlParser::XmlParser(RootObject *)
00345 {
00346 }
00347 
00348 RootObject *XmlParser::parse(std::string)
00349 {
00350     return 0 ;
00351 }
00352 
00353 bool XmlParser::exists()
00354 {
00355     return false ;
00356 }
00357 
00358 } // namespace certi
00359 
00360 #endif // HAVE_XML

Generated on Thu Apr 30 15:53:50 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5