source: XIOS2/trunk/src/group_template_impl.hpp @ 2623

Last change on this file since 2623 was 2615, checked in by ymipsl, 4 months ago
  • Permit now usage of contex_group into xml file for more modularity
  • Src path is now relative to parent file, except if path is an absolute path

YM

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