source: XIOS/dev/dev_olga/src/group_template_impl.hpp @ 1021

Last change on this file since 1021 was 1021, checked in by oabramkina, 7 years ago

Intermeadiate version for merging with new server functionalities.

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 21.3 KB
Line 
1#ifndef __XIOS_CGroupTemplate_impl__
2#define __XIOS_CGroupTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "event_server.hpp"
6#include "object_template.hpp"
7#include "group_template.hpp"
8#include "context.hpp"
9#include "event_client.hpp"
10#include "message.hpp"
11#include "type.hpp"
12#include "type_util.hpp"
13
14
15namespace xios
16{
17
18   /// ////////////////////// Définitions ////////////////////// ///
19
20   template <class U, class V, class W>
21      CGroupTemplate<U, V, W>::CGroupTemplate(void)
22         : CObjectTemplate<V>() //, V()
23         , childMap(), childList()
24         , groupMap(), groupList()
25   { /* Ne rien faire de plus */ }
26
27   template <class U, class V, class W>
28      CGroupTemplate<U, V, W>::CGroupTemplate(const StdString & id)
29         : CObjectTemplate<V>(id) //, V()
30         , childMap(), childList()
31         , groupMap(), groupList()
32   { /* Ne rien faire de plus */ }
33
34   template <class U, class V, class W>
35      CGroupTemplate<U, V, W>::~CGroupTemplate(void)
36   { /* Ne rien faire de plus */ }
37   
38   ///--------------------------------------------------------------
39/*
40   template <class U, class V, class W>
41      void CGroupTemplate<U, V, W>::toBinary(StdOStream & os) const
42   {
43      SuperClass::toBinary(os);
44     
45      const StdSize grpnb = this->groupList.size();
46      const StdSize chdnb = this->childList.size();
47      ENodeType cenum = U::GetType();
48      ENodeType genum = V::GetType();
49     
50      os.write (reinterpret_cast<const char*>(&grpnb) , sizeof(StdSize));
51      os.write (reinterpret_cast<const char*>(&chdnb) , sizeof(StdSize));     
52     
53      typename std::vector<V*>::const_iterator 
54         itg = this->groupList.begin(), endg = this->groupList.end();
55      typename std::vector<U*>::const_iterator
56         itc = this->childList.begin(), endc = this->childList.end();
57           
58      for (; itg != endg; itg++)
59      {
60         V* group = *itg;
61         bool hid = group->hasId();
62         
63         os.write (reinterpret_cast<const char*>(&genum), sizeof(ENodeType));     
64         os.write (reinterpret_cast<const char*>(&hid), sizeof(bool));
65         
66         if (hid)
67         {
68            const StdString & id = group->getId();
69            const StdSize size   = id.size();
70               
71            os.write (reinterpret_cast<const char*>(&size), sizeof(StdSize));
72            os.write (id.data(), size * sizeof(char));         
73         }             
74         group->toBinary(os);
75      }
76           
77      for (; itc != endc; itc++)
78      {
79         U* child = *itc;
80         bool hid = child->hasId();
81         
82         os.write (reinterpret_cast<const char*>(&cenum), sizeof(ENodeType));
83         os.write (reinterpret_cast<const char*>(&hid), sizeof(bool));
84         
85         if (hid)
86         {
87            const StdString & id = child->getId();
88            const StdSize size   = id.size();
89               
90            os.write (reinterpret_cast<const char*>(&size), sizeof(StdSize));
91            os.write (id.data(), size * sizeof(char));         
92         }         
93         child->toBinary(os);
94      }
95     
96   }
97   
98   template <class U, class V, class W>
99      void CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)
100   {
101      SuperClass::fromBinary(is);
102     
103      V* group_ptr = (this->hasId())
104         ? V::get(this->getId())
105         : V::get((V*)this);
106     
107      StdSize grpnb = 0;
108      StdSize chdnb = 0;
109      ENodeType renum = Unknown;
110     
111      is.read (reinterpret_cast<char*>(&grpnb), sizeof(StdSize));
112      is.read (reinterpret_cast<char*>(&chdnb), sizeof(StdSize));
113     
114      for (StdSize i = 0; i < grpnb; i++)
115      {
116         bool hid = false;
117         is.read (reinterpret_cast<char*>(&renum), sizeof(ENodeType));
118         is.read (reinterpret_cast<char*>(&hid), sizeof(bool));
119         
120         if (renum != V::GetType())
121            ERROR("CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)",
122                  << "[ renum = " << renum << "] Bad type !");
123                       
124         if (hid)
125         {
126            StdSize size  = 0;
127            is.read (reinterpret_cast<char*>(&size), sizeof(StdSize));
128            StdString id(size, ' ');
129            is.read (const_cast<char *>(id.data()), size * sizeof(char));
130            CGroupFactory::CreateGroup(group_ptr->getShared(), id)->fromBinary(is);
131         }
132         else
133         {
134            CGroupFactory::CreateGroup(group_ptr->getShared())->fromBinary(is);
135         }
136      }
137     
138      for (StdSize j = 0; j < chdnb; j++)
139      {
140         bool hid = false;
141         is.read (reinterpret_cast<char*>(&renum), sizeof(ENodeType));
142         is.read (reinterpret_cast<char*>(&hid), sizeof(bool));
143         
144         if (renum != U::GetType())
145            ERROR("CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)",
146                  << "[ renum = " << renum << "] Bad type !");
147                 
148         if (hid)
149         {
150            StdSize size  = 0;
151            is.read (reinterpret_cast<char*>(&size), sizeof(StdSize));
152            StdString id(size, ' ');
153            is.read (const_cast<char *>(id.data()), size * sizeof(char));
154            CGroupFactory::CreateChild(group_ptr->getShared(), id)->fromBinary(is);           
155         }
156         else
157         {
158            CGroupFactory::CreateChild(group_ptr->getShared())->fromBinary(is);
159         }   
160      }
161   }
162*/
163   //--------------------------------------------------------------
164
165   template <class U, class V, class W>
166      StdString CGroupTemplate<U, V, W>::toString(void) const
167   {
168      StdOStringStream oss;
169      StdString name = (this->getId().compare(V::GetDefName()) != 0)
170                     ? V::GetName() : V::GetDefName();
171
172      oss << "<" << name << " ";
173      if (this->hasId() && (this->getId().compare(V::GetDefName()) != 0))
174         oss << " id=\"" << this->getId() << "\" ";
175         
176      if (this->hasChild())
177      {
178         oss << SuperClassAttribute::toString() << ">" << std::endl;
179         
180         typename std::vector<V*>::const_iterator
181            itg = this->groupList.begin(), endg = this->groupList.end();
182         typename std::vector<U*>::const_iterator
183            itc = this->childList.begin(), endc = this->childList.end();
184           
185         for (; itg != endg; itg++)
186         { 
187            V* group = *itg;
188            oss << *group << std::endl;
189         }
190           
191         for (; itc != endc; itc++)
192         { 
193            U* child = *itc;
194            oss << *child << std::endl;
195         }
196           
197         oss << "</" << name << " >";
198      }
199      else
200      {
201         oss << SuperClassAttribute::toString() << "/>";
202      }
203      return (oss.str());
204   }
205
206   template <class U, class V, class W>
207      void CGroupTemplate<U, V, W>::fromString(const StdString & str)
208   { 
209      ERROR("CGroupTemplate<U, V, W>::toString(void)",
210            << "[ str = " << str << "] Not implemented yet !");
211   }
212
213   //---------------------------------------------------------------
214
215   template <class U, class V, class W>
216      StdString CGroupTemplate<U, V, W>::GetName(void)
217   { 
218      return (U::GetName().append("_group")); 
219   }
220
221   template <class U, class V, class W>
222      StdString CGroupTemplate<U, V, W>::GetDefName(void)
223   { 
224      return (U::GetName().append("_definition")); 
225   }
226   
227   //---------------------------------------------------------------   
228
229   template <class U, class V, class W>
230      const std::vector<U*>&
231         CGroupTemplate<U, V, W>::getChildList(void) const
232   { 
233      return (this->childList); 
234   }
235
236   //---------------------------------------------------------------
237
238   template <class U, class V, class W>
239      const xios_map<StdString, V*>&
240         CGroupTemplate<U, V, W>::getGroupMap(void) const
241   { 
242      return (this->groupMap);
243   }
244
245   //---------------------------------------------------------------
246
247   template <class U, class V, class W>
248      bool CGroupTemplate<U, V, W>::hasChild(void) const
249   { 
250      return ((groupList.size() + childList.size()) > 0); 
251   }
252
253   //---------------------------------------------------------------
254
255   template <class U, class V, class W>
256      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node)
257   { 
258      this->parse(node, true); 
259   }
260   
261   //---------------------------------------------------------------
262   
263   template <class U, class V, class W>
264      void CGroupTemplate<U, V, W>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
265   {
266      if (parent != NULL)
267         SuperClassAttribute::setAttributes(parent, apply);
268         
269      typename std::vector<U*>::const_iterator
270         itc = this->childList.begin(), endc = this->childList.end();
271      typename std::vector<V*>::const_iterator
272         itg = this->groupList.begin(), endg = this->groupList.end();
273             
274      for (; itc != endc; itc++)
275      { 
276         U* child = *itc;
277         child->solveDescInheritance(apply,this);
278      }
279           
280      for (; itg != endg; itg++)
281      { 
282         V* group = *itg;
283         if (apply) group->solveRefInheritance();
284         group->solveDescInheritance(apply,this);
285      }
286   }
287
288   //---------------------------------------------------------------
289
290   template <class U, class V, class W>
291      void CGroupTemplate<U, V, W>::getAllChildren(std::vector<U*>& allc) const
292   {
293      allc.insert (allc.end(), childList.begin(), childList.end());
294      typename std::vector<V*>::const_iterator
295         itg = this->groupList.begin(), endg = this->groupList.end();
296         
297      for (; itg != endg; itg++)
298      { 
299         V* group = *itg;
300         group->getAllChildren(allc);
301      }
302   }
303
304   //---------------------------------------------------------------
305
306   template <class U, class V, class W>
307      std::vector<U*> CGroupTemplate<U, V, W>::getAllChildren(void) const
308   { 
309      std::vector<U*> allc;
310      this->getAllChildren(allc);
311      return (allc);
312   }
313
314   //---------------------------------------------------------------
315
316   template <class U, class V, class W>
317      void CGroupTemplate<U, V, W>::solveRefInheritance(void)
318   { /* Ne rien faire de plus */ }
319   
320//   template <class U, class V, class W>
321//   bool CGroupTemplate<U, V, W>::has(const string& id)
322//   {
323//       return CObjectFactory::HasObject<V>(id) ;
324//   }
325
326//   template <class U, class V, class W>
327//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get(const string& id)
328//   {
329//       return CObjectFactory::GetObject<V>(id) ;
330//   }
331
332//   template <class U, class V, class W>
333//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get()
334//   {
335//       return CObjectFactory::GetObject<V>(this) ;
336//   }
337   
338//   template <class U, class V, class W>
339//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::create(const string& id)
340//   {
341//       return CObjectFactory::CreateObject<V>(id) ;
342//   }
343   ///--------------------------------------------------------------
344
345 
346   template <class U, class V, class W>
347   U* CGroupTemplate<U, V, W>::createChild(const string& id) 
348  {
349    return CGroupFactory::CreateChild<V>(this->getShared(), id).get() ;
350  }
351
352   template <class U, class V, class W>
353   void CGroupTemplate<U, V, W>::addChild(U* child) 
354  {
355    return CGroupFactory::AddChild<V>(this->getShared(),child->getShared()) ;
356  }
357 
358   template <class U, class V, class W>
359   V* CGroupTemplate<U, V, W>::createChildGroup(const string& id) 
360  {
361    return CGroupFactory::CreateGroup<V>(this->getShared(), id).get() ;
362  }
363
364   template <class U, class V, class W>
365   void CGroupTemplate<U, V, W>::addChildGroup(V* childGroup) 
366  {
367    return CGroupFactory::AddGroup<V>(this->getShared(), childGroup->getShared()) ;
368  }
369
370
371   template <class U, class V, class W>
372   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id)
373   {
374    CContext* context=CContext::getCurrent() ; 
375
376    if (context->hasClient)
377    // if (!context->hasServer )
378    {
379      // Use correct context client to send message
380//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
381      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
382      for (int i = 0; i < nbSrvPools; ++i)
383      {
384         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
385
386         CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
387         if (contextClientTmp->isServerLeader())
388         {
389           CMessage msg ;
390           msg<<this->getId() ;
391           msg<<id ;
392           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
393           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
394             event.push(*itRank,1,msg) ;
395           contextClientTmp->sendEvent(event) ;
396         }
397         else contextClientTmp->sendEvent(event) ;
398      }
399    }
400
401    // if (! context->hasServer )
402    // {
403    //    CContextClient* client=context->client ;
404
405    //    CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;   
406    //    if (client->isServerLeader())
407    //    {
408    //      CMessage msg ;
409    //      msg<<this->getId() ;
410    //      msg<<id ;
411    //      const std::list<int>& ranks = client->getRanksServerLeader();
412    //      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
413    //        event.push(*itRank,1,msg) ;
414    //      client->sendEvent(event) ;
415    //    }
416    //    else client->sendEvent(event) ;
417    // }
418     
419   }
420
421   template <class U, class V, class W>
422   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id, CContextClient* client)
423   {
424
425    CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
426    if (client->isServerLeader())
427    {
428      CMessage msg ;
429      msg<<this->getId() ;
430      msg<<id ;
431      const std::list<int>& ranks = client->getRanksServerLeader();
432      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
433       event.push(*itRank,1,msg) ;
434      client->sendEvent(event) ;
435    }
436    else client->sendEvent(event) ;
437   }
438
439
440   template <class U, class V, class W>
441   void CGroupTemplate<U, V, W>::sendCreateChildGroup(const string& id)
442   {
443    CContext* context=CContext::getCurrent() ;
444    if (context->hasClient)
445    {
446      // Use correct context client to send message
447      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
448      for (int i = 0; i < nbSrvPools; ++i)
449      {
450        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
451        CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;
452        if (contextClientTmp->isServerLeader())
453        {
454          CMessage msg ;
455          msg<<this->getId() ;
456          msg<<id ;
457          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
458          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
459            event.push(*itRank,1,msg) ;
460          contextClientTmp->sendEvent(event) ;
461        }
462        else contextClientTmp->sendEvent(event) ;
463      }
464    }
465
466    // if (! context->hasServer )
467    // {
468    //    CContextClient* client=context->client ;
469
470    //    CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;   
471    //    if (client->isServerLeader())
472    //    {
473    //      CMessage msg ;
474    //      msg<<this->getId() ;
475    //      msg<<id ;
476    //      const std::list<int>& ranks = client->getRanksServerLeader();
477    //      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
478    //        event.push(*itRank,1,msg) ;
479    //      client->sendEvent(event) ;
480    //    }
481    //    else client->sendEvent(event) ;
482    // }
483     
484   }
485   
486   template <class U, class V, class W>
487   void CGroupTemplate<U, V, W>::recvCreateChild(CEventServer& event)
488   {
489     
490      CBufferIn* buffer=event.subEvents.begin()->buffer;
491      string id;
492      *buffer>>id ;
493      V::get(id)->recvCreateChild(*buffer) ;
494   }
495   
496   
497   template <class U, class V, class W>
498   void CGroupTemplate<U, V, W>::recvCreateChild(CBufferIn& buffer)
499   {
500      string id ;
501      buffer>>id ;
502      createChild(id) ;
503   }
504
505   template <class U, class V, class W>
506   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CEventServer& event)
507   {
508     
509      CBufferIn* buffer=event.subEvents.begin()->buffer;
510      string id;
511      *buffer>>id ;
512      V::get(id)->recvCreateChildGroup(*buffer) ;
513   }
514   
515   
516   template <class U, class V, class W>
517   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CBufferIn& buffer)
518   {
519      string id ;
520      buffer>>id ;
521      createChildGroup(id) ;
522   }
523   
524
525   template <class U, class V, class W>
526   bool CGroupTemplate<U, V, W>::dispatchEvent(CEventServer& event)
527   {
528      if (CObjectTemplate<V>::dispatchEvent(event)) return true ;
529      else
530      {
531        switch(event.type)
532        {
533           case EVENT_ID_CREATE_CHILD :
534             recvCreateChild(event) ;
535             return true ;
536             break ;
537         
538           case EVENT_ID_CREATE_CHILD_GROUP :
539             recvCreateChildGroup(event) ;
540             return true ;
541             break ;       
542         
543           default :
544           return false ;
545        }
546      }
547   }
548
549   template <class U, class V, class W>
550      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)
551   {
552
553      StdString name = node.getElementName();
554      xml::THashAttributes attributes = node.getAttributes();
555      if (withAttr)
556      {
557         CGroupTemplate<U, V, W>::SuperClass::parse(node);
558         if (attributes.end() != attributes.find("src"))
559         {
560            StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in );
561            if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 )
562               ERROR("void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)",
563                     <<endl<< "Can not open <"<<attributes["src"].c_str()<<"> file" );
564           
565            if (!ifs.good())
566               ERROR("CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)",
567                     << "[ filename = " << attributes["src"] << " ] Bad xml stream !");
568            xml::CXMLParser::ParseInclude(ifs, attributes["src"].c_str(), *this);
569         }
570      }
571
572      // PARSING POUR GESTION DES ENFANTS
573           V* group_ptr = (this->hasId()) 
574         ? V::get(this->getId())
575         : boost::polymorphic_downcast<V*>(this);
576
577      if (!(node.goToChildElement()))
578      {
579         if (this->hasId())
580         {
581            DEBUG(<< "L'objet de type \'" << V::GetName()
582                  << "\' nommé \'" << this->getId()
583                  << "\' ne contient pas d\'enfant !");
584         }
585      }
586      else
587      {
588         do { // Parcours pour traitement.
589
590            StdString name = node.getElementName();
591            attributes.clear();
592            attributes = node.getAttributes();
593
594            if (name.compare(V::GetName()) == 0)
595            {
596               if (attributes.end() == attributes.find("id"))
597                  CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node);
598               else
599                  CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node);
600               continue;
601            }
602
603            if (name.compare(U::GetName()) == 0)
604            {
605               if (attributes.end() == attributes.find("id"))
606                  CGroupFactory::CreateChild(group_ptr->getShared())->parse(node);
607               else
608                  CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node);
609               continue;
610            }
611
612            DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId()
613                  << "\', un objet de type \'" << V::GetName()
614                  << "\' ne peut contenir qu'un objet de type \'" << V::GetName()
615                  << "\' ou de type \'" << U::GetName()
616                  << "\' (reçu : " << name << ") !");
617
618         } while (node.goToNextElement());
619         node.goToParentElement(); // Retour au parent
620      }
621   }
622   
623   template <class U, class V, class W>
624   void CGroupTemplate<U, V, W>::parseChild(xml::CXMLNode & node)
625   {
626
627
628      // PARSING POUR GESTION DES ENFANTS
629           V* group_ptr = (this->hasId()) 
630         ? V::get(this->getId())
631         : boost::polymorphic_downcast<V*>(this);
632
633          StdString name = node.getElementName();
634          xml::THashAttributes attributes = node.getAttributes();
635
636          if (name.compare(V::GetName()) == 0)
637          {
638             if (attributes.end() == attributes.find("id"))
639                CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node);
640             else
641                CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node);
642             return ;
643          }
644          else if (name.compare(U::GetName()) == 0)
645          {
646             if (attributes.end() == attributes.find("id"))
647                CGroupFactory::CreateChild(group_ptr->getShared())->parse(node);
648             else
649                CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node);
650             return ;
651          }
652
653          DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId()
654                << "\', un objet de type \'" << V::GetName()
655                << "\' ne peut contenir qu'un objet de type \'" << V::GetName()
656                << "\' ou de type \'" << U::GetName()
657                << "\' (reçu : " << name << ") !");
658
659   }
660} // namespace xios
661
662
663#endif // __XIOS_CGroupTemplate_impl__
Note: See TracBrowser for help on using the repository browser.