source: XIOS/trunk/src/group_template_impl.hpp @ 445

Last change on this file since 445 was 445, checked in by ymipsl, 11 years ago

Add possibility to make inheritance of attributes and reference before closing the context definition.
New fortran fonction : xios_solve inheritance()
After this call, the value of attribute have the inherited value of their parent.

YM

File size: 16.7 KB
Line 
1#ifndef __XMLIO_CGroupTemplate_impl__
2#define __XMLIO_CGroupTemplate_impl__
3
4#include "xmlioserver_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   template <class U, class V, class W>
257      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node)
258   { 
259      this->parse(node, true); 
260   }
261   
262   //---------------------------------------------------------------
263   
264   template <class U, class V, class W>
265      void CGroupTemplate<U, V, W>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
266   {
267      if (parent != NULL)
268         SuperClassAttribute::setAttributes(parent, apply);
269         
270      typename std::vector<U*>::const_iterator
271         itc = this->childList.begin(), endc = this->childList.end();
272      typename std::vector<V*>::const_iterator
273         itg = this->groupList.begin(), endg = this->groupList.end();
274             
275      for (; itc != endc; itc++)
276      { 
277         U* child = *itc;
278         child->solveDescInheritance(apply,this);
279      }
280           
281      for (; itg != endg; itg++)
282      { 
283         V* group = *itg;
284         group->solveRefInheritance();
285         group->solveDescInheritance(apply,this);
286      }
287   }
288
289   //---------------------------------------------------------------
290
291   template <class U, class V, class W>
292      void CGroupTemplate<U, V, W>::getAllChildren(std::vector<U*>& allc) const
293   {
294      allc.insert (allc.end(), childList.begin(), childList.end());
295      typename std::vector<V*>::const_iterator
296         itg = this->groupList.begin(), endg = this->groupList.end();
297         
298      for (; itg != endg; itg++)
299      { 
300         V* group = *itg;
301         group->getAllChildren(allc);
302      }
303   }
304
305   //---------------------------------------------------------------
306
307   template <class U, class V, class W>
308      std::vector<U*> CGroupTemplate<U, V, W>::getAllChildren(void) const
309   { 
310      std::vector<U*> allc;
311      this->getAllChildren(allc);
312      return (allc);
313   }
314
315   //---------------------------------------------------------------
316
317   template <class U, class V, class W>
318      void CGroupTemplate<U, V, W>::solveRefInheritance(void)
319   { /* Ne rien faire de plus */ }
320   
321//   template <class U, class V, class W>
322//   bool CGroupTemplate<U, V, W>::has(const string& id)
323//   {
324//       return CObjectFactory::HasObject<V>(id) ;
325//   }
326
327//   template <class U, class V, class W>
328//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get(const string& id)
329//   {
330//       return CObjectFactory::GetObject<V>(id) ;
331//   }
332
333//   template <class U, class V, class W>
334//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get()
335//   {
336//       return CObjectFactory::GetObject<V>(this) ;
337//   }
338   
339//   template <class U, class V, class W>
340//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::create(const string& id)
341//   {
342//       return CObjectFactory::CreateObject<V>(id) ;
343//   }
344   ///--------------------------------------------------------------
345
346 
347   template <class U, class V, class W>
348   U* CGroupTemplate<U, V, W>::createChild(const string& id) 
349  {
350    return CGroupFactory::CreateChild<V>(this->getShared(), id).get() ;
351  }
352
353   template <class U, class V, class W>
354   void CGroupTemplate<U, V, W>::addChild(U* child) 
355  {
356    return CGroupFactory::AddChild<V>(this->getShared(),child->getShared()) ;
357  }
358 
359   template <class U, class V, class W>
360   V* CGroupTemplate<U, V, W>::createChildGroup(const string& id) 
361  {
362    return CGroupFactory::CreateGroup<V>(this->getShared(), id).get() ;
363  }
364
365   template <class U, class V, class W>
366   void CGroupTemplate<U, V, W>::addChildGroup(V* childGroup) 
367  {
368    return CGroupFactory::AddGroup<V>(this->getShared(), childGroup->getShared()) ;
369  }
370
371
372   template <class U, class V, class W>
373   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id)
374   {
375    CContext* context=CContext::getCurrent() ;
376   
377    if (! context->hasServer )
378    {
379       CContextClient* client=context->client ;
380
381       CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;   
382       if (client->isServerLeader())
383       {
384         CMessage msg ;
385         msg<<this->getId() ;
386         msg<<id ;
387         event.push(client->getServerLeader(),1,msg) ;
388         client->sendEvent(event) ;
389       }
390       else client->sendEvent(event) ;
391    }
392     
393   }
394   
395   template <class U, class V, class W>
396   void CGroupTemplate<U, V, W>::sendCreateChildGroup(const string& id)
397   {
398    CContext* context=CContext::getCurrent() ;
399    if (! context->hasServer )
400    {
401       CContextClient* client=context->client ;
402
403       CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;   
404       if (client->isServerLeader())
405       {
406         CMessage msg ;
407         msg<<this->getId() ;
408         msg<<id ;
409         event.push(client->getServerLeader(),1,msg) ;
410         client->sendEvent(event) ;
411       }
412       else client->sendEvent(event) ;
413    }
414     
415   }
416   
417   template <class U, class V, class W>
418   void CGroupTemplate<U, V, W>::recvCreateChild(CEventServer& event)
419   {
420     
421      CBufferIn* buffer=event.subEvents.begin()->buffer;
422      string id;
423      *buffer>>id ;
424      V::get(id)->recvCreateChild(*buffer) ;
425   }
426   
427   
428   template <class U, class V, class W>
429   void CGroupTemplate<U, V, W>::recvCreateChild(CBufferIn& buffer)
430   {
431      string id ;
432      buffer>>id ;
433      createChild(id) ;
434   }
435
436   template <class U, class V, class W>
437   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CEventServer& event)
438   {
439     
440      CBufferIn* buffer=event.subEvents.begin()->buffer;
441      string id;
442      *buffer>>id ;
443      V::get(id)->recvCreateChildGroup(*buffer) ;
444   }
445   
446   
447   template <class U, class V, class W>
448   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CBufferIn& buffer)
449   {
450      string id ;
451      buffer>>id ;
452      createChildGroup(id) ;
453   }
454   
455
456   template <class U, class V, class W>
457   bool CGroupTemplate<U, V, W>::dispatchEvent(CEventServer& event)
458   {
459      if (CObjectTemplate<V>::dispatchEvent(event)) return true ;
460      else
461      {
462        switch(event.type)
463        {
464           case EVENT_ID_CREATE_CHILD :
465             recvCreateChild(event) ;
466             return true ;
467             break ;
468         
469           case EVENT_ID_CREATE_CHILD_GROUP :
470             recvCreateChildGroup(event) ;
471             return true ;
472             break ;       
473         
474           default :
475           return false ;
476        }
477      }
478   }
479
480   template <class U, class V, class W>
481      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)
482   {
483
484      StdString name = node.getElementName();
485      xml::THashAttributes attributes = node.getAttributes();
486      if (withAttr)
487      {
488         CGroupTemplate<U, V, W>::SuperClass::parse(node);
489         if (attributes.end() != attributes.find("src"))
490         {
491            StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in );
492            if (!ifs.good())
493               ERROR("CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)",
494                     << "[ filename = " << attributes["src"] << " ] Bad xml stream !");
495            xml::CXMLParser::ParseInclude(ifs, *this);
496         }
497      }
498
499      // PARSING POUR GESTION DES ENFANTS
500           V* group_ptr = (this->hasId()) 
501         ? V::get(this->getId())
502         : boost::polymorphic_downcast<V*>(this);
503
504      if (!(node.goToChildElement()))
505      {
506         if (this->hasId())
507         {
508            DEBUG(<< "L'objet de type \'" << V::GetName()
509                  << "\' nommé \'" << this->getId()
510                  << "\' ne contient pas d\'enfant !");
511         }
512      }
513      else
514      {
515         do { // Parcours pour traitement.
516
517            StdString name = node.getElementName();
518            attributes.clear();
519            attributes = node.getAttributes();
520
521            if (name.compare(V::GetName()) == 0)
522            {
523               if (attributes.end() == attributes.find("id"))
524                  CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node);
525               else
526                  CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node);
527               continue;
528            }
529
530            if (name.compare(U::GetName()) == 0)
531            {
532               if (attributes.end() == attributes.find("id"))
533                  CGroupFactory::CreateChild(group_ptr->getShared())->parse(node);
534               else
535                  CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node);
536               continue;
537            }
538
539            DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId()
540                  << "\', un objet de type \'" << V::GetName()
541                  << "\' ne peut contenir qu'un objet de type \'" << V::GetName()
542                  << "\' ou de type \'" << U::GetName()
543                  << "\' (reçu : " << name << ") !");
544
545         } while (node.goToNextElement());
546         node.goToParentElement(); // Retour au parent
547      }
548   }
549} // namespace xios
550
551
552#endif // __XMLIO_CGroupTemplate_impl__
Note: See TracBrowser for help on using the repository browser.