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