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 

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