# TreeNamedAndHandledSet.hh

Go to the documentation of this file.

    00001 // ----------------------------------------------------------------------------
    00002 // CERTI - HLA RunTime Infrastructure
    00003 // Copyright (C) 2002-2008  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
    00020 // USA
    00021 //
    00022 // $Id: TreeNamedAndHandledSet.hh,v 1.8 2008/11/15 14:54:26 gotthardp Exp $
    00023 // ----------------------------------------------------------------------------
    00024
    00025 #ifndef _TreeNamedAndHandledSet_HH
    00026 #define _TreeNamedAndHandledSet_HH
    00027
    00028 // CERTI headers
    00029 #include "certi.hh"
    00030 #include "Named.hh"
    00031
    00032 // System headers
    00033 #include <string>
    00034 #include <map>
    00035 #include <iostream>
    00036
    00037 namespace certi {
    00038
    00062 template<typename ObjectType>
    00063 class TreeNamedAndHandledSet
    00064 {
    00065
    00066 public:
    00070     typedef typename ObjectType::handle_t            HandleType;
    00076     typedef typename ObjectType::ObjectNotDefinedException ObjectNotDefinedException;
    00077
    00078     TreeNamedAndHandledSet(std::string setName,bool isRootSet=false);
    00079     ~TreeNamedAndHandledSet();
    00080
    00081     std::string getSetName() const {return setName;};
    00082
    00093     void add(ObjectType *child, ObjectType* parent=NULL) throw (RTIinternalError);
    00094
    00101     HandleType getHandleFromName(const std::string name) const
    00102     throw (NameNotFound);
    00103
    00110     std::string getNameFromHandle(HandleType handle) const
    00111     throw (ObjectNotDefinedException);
    00112
    00119     ObjectType* getObjectFromHandle(HandleType handle) const
    00120     throw (ObjectNotDefinedException);
    00121
    00125     typedef std::map<HandleType,ObjectType*,std::less<HandleType> > Handle2ObjectMap_t;
    00126     typedef typename Handle2ObjectMap_t::const_iterator handled_const_iterator;
    00127     typedef typename Handle2ObjectMap_t::iterator       handled_iterator;
    00128
    00129     handled_const_iterator handled_begin() const {
    00130         return fromHandle.begin();
    00131     }
    00132
    00133     handled_const_iterator handled_end() const {
    00134         return fromHandle.end();
    00135     }
    00139     typedef std::map<std::string,ObjectType*,std::less<std::string> > Name2ObjectMap_t;
    00140     typedef typename Name2ObjectMap_t::const_iterator named_const_iterator;
    00141     typedef typename Name2ObjectMap_t::const_iterator const_iterator;
    00142     typedef typename Name2ObjectMap_t::iterator       iterator;
    00143
    00144     named_const_iterator begin() const {
    00145         return fromName.begin();
    00146     }
    00147
    00148     named_const_iterator end() const {
    00149         return fromName.end();
    00150     }
    00151
    00157     const size_t size() {return fromName.size();}
    00158
    00159 protected:
    00160     Handle2ObjectMap_t fromHandle;
    00161     Name2ObjectMap_t   fromName;
    00162     /*
    00163      * The "Root" set is owning the object
    00164      * and will destroy objects in its destructor.
    00165      * Non "Root" set won't destroy anything beside itself.
    00166      */
    00167     bool               isRootSet;
    00168     /*
    00169      * The name of the set.
    00170      * Mainly used for displaying the set.
    00171      */
    00172     std::string        setName;
    00173 private:
    00174
    00175 };
    00176
    00177 template <typename ObjectType>
    00178 TreeNamedAndHandledSet<ObjectType>::TreeNamedAndHandledSet(std::string theSetName, bool theIsRootSet) {
    00179    this->setName   = theSetName;
    00180    this->isRootSet = theIsRootSet;
    00181 } /* end of TreeNamedAndHandledSet (constructor) */
    00182
    00183 template <typename ObjectType>
    00184 TreeNamedAndHandledSet<ObjectType>::~TreeNamedAndHandledSet() {
    00185     /* clear name map */
    00186     fromName.clear();
    00187     /*
    00188      * If we are Root Set (the class set owned by RootObject)
    00189      *    we delete the content
    00190      * If not we only clear the map in order to avoid double deletion.
    00191      * The "Non Root" set are those who are not "owning"
    00192      * the stored object.
    00193      */
    00194     if (isRootSet) {
    00195         while (!fromHandle.empty()) {
    00196             delete (fromHandle.begin()->second);
    00197             fromHandle.erase(fromHandle.begin());
    00198         }
    00199     }
    00200     else {
    00201         fromHandle.clear();
    00202     }
    00203 } /* end of ~TreeNamedAndHandledSet (destructor) */
    00204
    00205 template <typename ObjectType>
    00206 void
    00207 TreeNamedAndHandledSet<ObjectType>::add(ObjectType *child, ObjectType *parent)
    00208     throw (RTIinternalError) {
    00209     typename Name2ObjectMap_t::iterator findit;
    00210     std::stringstream             msg;
    00211
    00212     /* build hierarchical name if a parent is given */
    00213     if (NULL!=parent) {
    00214         std::string parentName = parent->getName();
    00215         /*
    00216          * Inclusion or exclusion of those prefix is optional
    00217          * see IEEE-1516.1-2000 - 10.1.1 Names
    00218          * Do not build HLA root name in the hierarchical name
    00219          */
    00220         if (!((parentName=="ObjectRoot") ||
    00221               (parentName=="InteractionRoot") ||
    00222               (parentName=="HLAobjectRoot") ||
    00223               (parentName=="HLAinteractionRoot")
    00224               )
    00225               ){
    00226             child->setName(parentName+"."+child->getName());
    00227         }
    00228         //std::cout << "Adding child :" << child->getName() << std::endl;
    00229         parent->addSubClass(child);
    00230     }
    00231
    00232     /*
    00233      * Check whether addition of this object class
    00234      * will generate a name collision or not.
    00235      * i.e. we may not add an object class of the SAME
    00236      * name to the object class set
    00237      */
    00238     findit = fromName.find(child->getName());
    00239     if (findit != fromName.end()) {
    00240         msg << "Name collision another object class named <"
    00241             << child->getName()
    00242             << "> with handle <"
    00243             << findit->second->getHandle()
    00244             << "> was found when trying to add identically named object class with handle <"
    00245             << child->getHandle();
    00246         throw RTIinternalError(msg.str().c_str());
    00247     }
    00248     /* store ref to new object in Object from Handle Map */
    00249     fromHandle[child->getHandle()] = child;
    00250     /* store ref to new object in Object from Name Map */
    00251     fromName[child->getName()] = child;
    00252 } /* end of add */
    00253
    00254 template <typename ObjectType>
    00255 typename TreeNamedAndHandledSet<ObjectType>::HandleType
    00256 TreeNamedAndHandledSet<ObjectType>::getHandleFromName(std::string name) const
    00257     throw (NameNotFound) {
    00258
    00259     named_const_iterator   findit;
    00260     std::string            sname;
    00261     std::string            prefix;
    00262
    00263     sname = name;
    00264     prefix = Named::getNextClassName(sname);
    00265     /*
    00266      * Inclusion or exclusion of those prefix is optional
    00267      * see IEEE-1516.1-2000 - 10.1.1 Names
    00268      * Do not build HLA root name in the hierarchical name
    00269      */
    00270     if (!((prefix=="ObjectRoot") ||
    00271           (prefix=="InteractionRoot") ||
    00272           (prefix=="HLAobjectRoot") ||
    00273           (prefix=="HLAinteractionRoot")
    00274          )
    00275        ) {
    00276         sname = name;
    00277     }
    00278     /*
    00279      * First try to find the named object
    00280      * This should be an efficient binary_search
    00281      */
    00282     findit = fromName.find(sname);
    00283     //std::cout << "Looking for " << sname << std::endl;
    00284     /* If found return the handle */
    00285     if (findit != fromName.end()) {
    00286         return findit->second->getHandle();
    00287     }
    00288
    00289     /*
    00290      * If not found then look for shortcut name
    00291      * this is a CERTI non-standard behavior
    00292      */
    00293     if (!Named::isQualifiedClassName(sname)) {
    00294         /* linear search in the whole set */
    00295         for (findit=fromName.begin(); findit!=fromName.end();++findit) {
    00296             if (Named::getLeafClassName(findit->first) == sname) {
    00297                 return findit->second->getHandle();
    00298             }
    00299             else {
    00300             //std::cout << Named::getLeafClassName(findit->first) << "- and -" << sname << " - do not match" << std::endl;
    00301             }
    00302         }
    00303     }
    00304
    00305     /* every search has failed */
    00306     throw NameNotFound(name.c_str());
    00307 } /* end of getObjectClassHandle */
    00308
    00309 template <typename ObjectType>
    00310 std::string
    00311 TreeNamedAndHandledSet<ObjectType>::getNameFromHandle(HandleType handle) const
    00312 throw (ObjectNotDefinedException) {
    00313
    00314     return getObjectFromHandle(handle)->getName();
    00315 } /* end of getNameFromHandle */
    00316
    00317 template <typename ObjectType>
    00318 ObjectType*
    00319 TreeNamedAndHandledSet<ObjectType>::getObjectFromHandle(HandleType handle) const
    00320     throw (ObjectNotDefinedException) {
    00321
    00322     std::stringstream       msg;
    00323     handled_const_iterator iter;
    00324
    00325     iter = fromHandle.find(handle);
    00326
    00327     if (iter != fromHandle.end()) {
    00328         return iter->second;
    00329     } else {
    00330         msg << "Unknown Object Handle <" << handle << ">";
    00331         throw ObjectNotDefinedException(msg.str().c_str());
    00332     }
    00333 } /* end of getObjectFromHandle */
    00334
    00335 template <typename ObjectType>
    00336 std::ostream& operator<<(std::ostream& os, TreeNamedAndHandledSet<ObjectType> set) {
    00337     typename TreeNamedAndHandledSet<ObjectType>::const_iterator i;
    00338     // display the set name
    00339     os << set.getSetName() << " : "<< std::endl ;
    00340     // then display the object contained in the set
    00341     // FIXME currently the display method of ObjectClass
    00342     // and Interaction is not <iostream> oriented.
    00343     // will update that later
    00344     for (i = set.begin(); i != set.end(); ++i) {
    00345         i->second->display();
    00346     }
    00347     return os;
    00348 }
    00349
    00350 } // namespace certi
    00351
    00352
    00353
    00354 #endif // _TreeNamedAndHandledSet_HH
    00355