Salome HOME
2ff17b580562eb0865da39a5ac79f742419fde2a
[modules/yacs.git] / src / SALOMEDS / SALOMEDS_SObject_i.cxx
1 //  SALOME SALOMEDS : data structure of SALOME and sources of Salome data server 
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOMEDS_SObject_i.cxx
25 //  Author : Yves FRICAUD
26 //  Module : SALOME
27 //  $Header$
28
29 #include <TDF_Tool.hxx>
30 #include <TDF_Attribute.hxx>
31 #include <TDF_Reference.hxx>
32 #include <Standard_GUID.hxx>
33 #include <Standard_NoSuchObject.hxx>
34 #include <TDataStd_Name.hxx>
35 #include <TDataStd_Comment.hxx>
36 #include <TDataStd_Integer.hxx>
37 #include <TDataStd_Real.hxx>
38 #include <TDataStd_TreeNode.hxx>
39 #include <TDataStd_UAttribute.hxx>
40
41 #include <TCollection_AsciiString.hxx>
42 #include <TDF_AttributeIterator.hxx>
43
44 #include "SALOMEDS_SObject_i.hxx"
45
46 //SALOMEDS Headers
47 #include "SALOMEDS_Study_i.hxx"
48 #include "SALOMEDS_StudyManager_i.hxx"
49 #include "SALOMEDS_SComponent_i.hxx"
50
51 #include "SALOMEDS_AttributeComment_i.hxx"
52
53 #include "SALOMEDS_AttributeTreeNode_i.hxx"
54 #include "SALOMEDS_AttributeUserID_i.hxx"
55
56 #include "SALOMEDS_AttributePersistentRef_i.hxx"
57 #include "SALOMEDS_AttributeIOR_i.hxx"
58 #include "SALOMEDS_AttributeExternalFileDef_i.hxx"
59 #include "SALOMEDS_AttributeFileType_i.hxx"
60 #include "SALOMEDS_AttributeName_i.hxx"
61 #include "SALOMEDS_AttributeSequenceOfInteger_i.hxx"
62 #include "SALOMEDS_AttributeSequenceOfReal_i.hxx"
63 #include "SALOMEDS_AttributeTableOfInteger_i.hxx"
64 #include "SALOMEDS_AttributeTableOfReal_i.hxx"
65 #include "SALOMEDS_AttributeTableOfString_i.hxx"
66 #include "SALOMEDS_AttributeInteger_i.hxx"
67 #include "SALOMEDS_AttributeReal_i.hxx"
68 #include "SALOMEDS_AttributeDrawable_i.hxx"
69 #include "SALOMEDS_AttributeSelectable_i.hxx"
70 #include "SALOMEDS_AttributeExpandable_i.hxx"
71 #include "SALOMEDS_AttributeOpened_i.hxx"
72 #include "SALOMEDS_AttributeTextColor_i.hxx"
73 #include "SALOMEDS_AttributeTextHighlightColor_i.hxx"
74 #include "SALOMEDS_AttributePixMap_i.hxx"
75 #include "SALOMEDS_AttributeTarget_i.hxx"
76 #include "SALOMEDS_AttributeLocalID_i.hxx"
77 #include "SALOMEDS_AttributeStudyProperties_i.hxx"
78 #include "SALOMEDS_AttributePythonObject_i.hxx"
79
80 #include "SALOMEDS_AttributeGraphic_i.hxx"
81 #include "SALOMEDS_AttributeFlags_i.hxx"
82
83 #include "Utils_ExceptHandlers.hxx"
84 UNEXPECT_CATCH(GALockProtection, SALOMEDS::GenericAttribute::LockProtection);
85
86 #include "utilities.h"
87
88 using namespace std;
89 using namespace SALOMEDS;
90
91
92 inline bool operator<(const Standard_GUID& theLeft, const Standard_GUID& theRight)
93 {
94   char aLeft[40] = "";
95   theLeft.ToCString(aLeft);
96
97   char aRight[40] = "";
98   theRight.ToCString(aRight);
99   
100   return strcmp(aLeft,aRight) < 0;
101 }
102
103
104 namespace SALOMEDS{
105
106   const char* Str(const TCollection_ExtendedString& theString)
107   {
108     return TCollection_AsciiString(theString).ToCString();
109   }
110
111   typedef std::string TAttributeID;
112
113   typedef Standard_GUID (*TGetGUID)();
114   typedef bool (*TIsCheckLockedStudy)();
115   typedef Handle(TDF_Attribute) (*TNewAttribute)();
116   typedef SALOMEDS_GenericAttribute_i* (*TNewInstance)(const Handle(TDF_Attribute)&, SALOMEDS_SObject_i*);
117   
118   struct TAttrFun{
119     TAttrFun(const TGetGUID& theGetGUID,
120              const TIsCheckLockedStudy& theIsCheckLockedStudy,
121              const TNewAttribute& theNewAttribute,
122              const TNewInstance& theNewInstance):
123       myGetGUID(theGetGUID),
124       myIsCheckLockedStudy(theIsCheckLockedStudy),
125       myNewAttribute(theNewAttribute),
126       myNewInstance(theNewInstance)
127     {
128     }
129
130     TGetGUID myGetGUID;
131     TIsCheckLockedStudy myIsCheckLockedStudy;
132     TNewAttribute myNewAttribute;
133     TNewInstance myNewInstance;
134   };
135   
136   typedef std::map<TAttributeID,TAttrFun> TAttrID2FunMap;
137   static TAttrID2FunMap __AttrID2FunMap__;
138   
139   
140   typedef std::map<Standard_GUID,TAttributeID> TGUID2AttrIDMap;
141   static TGUID2AttrIDMap __GUID2AttrIDMap__;
142   
143   bool Init()
144   {
145     
146 #define ADD_ATTRID2FUNMAP_ITEM(theName) \
147     __AttrID2FunMap__.insert( \
148       TAttrID2FunMap::value_type(#theName,TAttrFun( \
149         &(SALOMEDS_##theName##_i::GetGUID), \
150         &(SALOMEDS_##theName##_i::IsCheckLockedStudy), \
151         &(SALOMEDS_##theName##_i::NewAttribute), \
152         &(SALOMEDS_##theName##_i::NewInstance) \
153     )))
154                                                        
155     ADD_ATTRID2FUNMAP_ITEM(AttributeName);
156     ADD_ATTRID2FUNMAP_ITEM(AttributeComment); 
157     ADD_ATTRID2FUNMAP_ITEM(AttributeIOR);
158     ADD_ATTRID2FUNMAP_ITEM(AttributeReal);
159     ADD_ATTRID2FUNMAP_ITEM(AttributeInteger);
160     ADD_ATTRID2FUNMAP_ITEM(AttributeSequenceOfInteger);
161     ADD_ATTRID2FUNMAP_ITEM(AttributeSequenceOfReal);
162     ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfInteger);
163     ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfReal);
164     ADD_ATTRID2FUNMAP_ITEM(AttributeTableOfString);
165     ADD_ATTRID2FUNMAP_ITEM(AttributeLocalID);
166     ADD_ATTRID2FUNMAP_ITEM(AttributePythonObject);
167     
168     ADD_ATTRID2FUNMAP_ITEM(AttributeUserID);
169     ADD_ATTRID2FUNMAP_ITEM(AttributeTreeNode);
170
171     ADD_ATTRID2FUNMAP_ITEM(AttributePersistentRef);
172     ADD_ATTRID2FUNMAP_ITEM(AttributeDrawable);
173     ADD_ATTRID2FUNMAP_ITEM(AttributeSelectable);
174     ADD_ATTRID2FUNMAP_ITEM(AttributeExpandable);
175     ADD_ATTRID2FUNMAP_ITEM(AttributeOpened);
176     ADD_ATTRID2FUNMAP_ITEM(AttributeTextColor);
177     ADD_ATTRID2FUNMAP_ITEM(AttributeTextHighlightColor);
178     ADD_ATTRID2FUNMAP_ITEM(AttributePixMap);
179     ADD_ATTRID2FUNMAP_ITEM(AttributeTarget);
180     ADD_ATTRID2FUNMAP_ITEM(AttributeStudyProperties);
181     ADD_ATTRID2FUNMAP_ITEM(AttributeExternalFileDef);
182     ADD_ATTRID2FUNMAP_ITEM(AttributeFileType);
183
184     ADD_ATTRID2FUNMAP_ITEM(AttributeGraphic);
185     ADD_ATTRID2FUNMAP_ITEM(AttributeFlags);
186
187     TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.begin();
188     TAttrID2FunMap::const_iterator anEnd = __AttrID2FunMap__.end();
189     for(; anIter != anEnd; anIter++){
190       const TAttrID2FunMap::key_type& aKey = anIter->first;
191       const TAttrID2FunMap::data_type& aValue = anIter->second;
192       __GUID2AttrIDMap__[aValue.myGetGUID()] = aKey;
193     };
194
195 #undef ADD_ATTRID2FUNMAP_ITEM
196     return true;
197   }
198   
199
200   static bool __IsInitilized__ = Init();
201
202
203   //============================================================================
204   bool GetAttrFun(const Standard_GUID& theGUID, TAttrFun& theAttrFun)
205   {
206     TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(theGUID);
207     if(anIter != __GUID2AttrIDMap__.end())
208     {
209       const TAttributeID& anAttributeID = anIter->second;
210       TAttrID2FunMap::const_iterator anIter2 = __AttrID2FunMap__.find(anAttributeID);
211       if(anIter2 != __AttrID2FunMap__.end())
212       {
213         theAttrFun = anIter2->second;
214         return true;
215       }
216     }
217     return false;
218   }
219
220
221   //============================================================================
222   Standard_GUID GetGUID(const char* theType)
223   {
224     TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
225     if(anIter != __AttrID2FunMap__.end()){
226       const TAttrID2FunMap::data_type& aValue = anIter->second;
227       return aValue.myGetGUID();
228     }
229     // create tree node GUID by name
230     if(strncmp(theType,"AttributeTreeNodeGUID",21) == 0){
231       char aGUIDString[40] = "";
232       sprintf(aGUIDString,&theType[21]);
233       return aGUIDString;
234     }
235     
236     return Standard_GUID();
237   }
238
239
240   //============================================================================
241   std::string GetType(const Handle(TDF_Attribute)& theAttr)
242   {
243     if(theAttr.IsNull())
244       return CORBA::string_dup("");
245     
246     Standard_GUID aGUID = theAttr->ID();
247     TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(aGUID);
248     if(anIter != __GUID2AttrIDMap__.end())
249     {
250       const TAttributeID& anAttributeID = anIter->second;
251       return anAttributeID;
252     }
253     
254     char aType[60] = "";
255     {
256       Handle(TDataStd_TreeNode) anAttr = Handle(TDataStd_TreeNode)::DownCast(theAttr);
257       if (!anAttr.IsNull()) {
258         char aGUID[40] = "";
259         anAttr->ID().ToCString(aGUID);
260         sprintf(aType, "AttributeTreeNodeGUID%s",aGUID);
261         return aType;
262       }
263     }
264     {
265       Handle(TDataStd_UAttribute) anAttr = Handle(TDataStd_UAttribute)::DownCast(theAttr);
266       if (!anAttr.IsNull()) {
267         char aGUID[40] = "";
268         anAttr->ID().ToCString(aGUID);
269         sprintf(aType, "AttributeUserID_%s",aGUID); 
270         return aType;
271       }
272     }
273     return aType;
274   }
275   
276 }  
277   
278 //============================================================================
279 SALOMEDS_Study_i::TSObjectHolder
280 SALOMEDS_SObject_i::New(SALOMEDS_Study_i* theStudy,
281                         const TDF_Label& theLabel)
282 {
283   SALOMEDS_Study_i::TSObjectHolder aSObjectHolder;
284   SALOMEDS_Study_i::TSObjectMap& anSObjectMap = theStudy->GetSObjectMap();
285   SALOMEDS_Study_i::TSObjectMap::const_iterator anIter = anSObjectMap.find(theLabel);
286   if(anIter != anSObjectMap.end())
287     aSObjectHolder = anIter->second;
288   else{
289     SALOMEDS_SObject_i* aSObject = new SALOMEDS_SObject_i(theStudy,theLabel);
290     aSObjectHolder.first = aSObject;
291     aSObjectHolder.second = aSObject->_this();
292     anSObjectMap[theLabel] = aSObjectHolder;
293
294     //TCollection_AsciiString anEntry;
295     //TDF_Tool::Entry(theLabel,anEntry);
296     //cout<<"APO - SALOMEDS_SObject_i::New - anEntry = "<<anEntry.ToCString()<<endl;
297   }
298   return aSObjectHolder;
299 }
300
301 SALOMEDS_SObject_i*
302 SALOMEDS_SObject_i::NewPtr(SALOMEDS_Study_i* theStudy,
303                            const TDF_Label& theLabel)
304 {
305   return New(theStudy,theLabel).first;
306 }
307
308 SALOMEDS::SObject_var
309 SALOMEDS_SObject_i::NewRef(SALOMEDS_Study_i* theStudy,
310                            const TDF_Label& theLabel)
311 {
312   return New(theStudy,theLabel).second;
313 }
314
315 //============================================================================
316 /*! Function : constructor
317  *  Purpose  : 
318  */
319 //============================================================================
320 SALOMEDS_SObject_i::SALOMEDS_SObject_i(SALOMEDS_Study_i* theStudy,
321                                        const TDF_Label& theLabel):
322   _lab(theLabel),
323   _study(theStudy)
324 {
325 }
326
327 //============================================================================
328 /*! Function : destructor
329  *  Purpose  : 
330  */
331 //============================================================================
332 SALOMEDS_SObject_i::~SALOMEDS_SObject_i()
333 {
334 }
335   
336
337 //============================================================================
338 CORBA::ORB_var SALOMEDS_SObject_i::GetORB() const
339 {
340   return _study->GetORB();
341 }
342
343
344 //============================================================================
345 PortableServer::POA_var SALOMEDS_SObject_i::GetPOA() const
346 {
347   return _study->GetPOA();
348 }
349
350
351 //============================================================================
352 /*! Function :
353  *  Purpose  : 
354  */
355 //============================================================================
356 char* SALOMEDS_SObject_i::GetID()
357 {
358   TCollection_AsciiString anEntry;
359   TDF_Tool::Entry(_lab,anEntry);
360   return CORBA::string_dup(anEntry.ToCString());
361 }
362   
363 //============================================================================
364 /*! Function :
365  *  Purpose  : 
366  */
367 //============================================================================
368 SALOMEDS::SComponent_ptr SALOMEDS_SObject_i::GetFatherComponent()
369 {
370   TDF_Label aSCompLabel = _lab;
371   while(!SALOMEDS_SComponent_i::IsA(aSCompLabel) && !aSCompLabel.IsRoot()){
372     aSCompLabel = aSCompLabel.Father();
373   }
374   return SALOMEDS_SComponent_i::NewRef(_study,aSCompLabel)._retn();
375 }
376   
377 //============================================================================
378 /*! Function :
379  *  Purpose  : 
380  */
381 //============================================================================
382 SALOMEDS::SObject_ptr SALOMEDS_SObject_i::GetFather()
383 {
384   return SALOMEDS_SObject_i::NewRef(_study,_lab.Father())._retn();
385 }
386
387 //============================================================================
388 /*! Function :
389  *  Purpose  : 
390  */
391 //============================================================================
392 SALOMEDS::Study_ptr SALOMEDS_SObject_i::GetStudy()
393 {
394   return _study->_this();
395 }
396
397 //============================================================================
398 /*! Function : ReferencedObject
399  *  Purpose  : 
400  */
401 //============================================================================
402 CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out theSObject)
403 {
404   Handle(TDF_Reference) aRef;
405   if (!_lab.FindAttribute(TDF_Reference::GetID(),aRef))
406     return false;
407   
408   theSObject = SALOMEDS_SObject_i::NewRef(_study,aRef->Get())._retn(); 
409   return true;
410 }
411
412 //============================================================================
413 /*! Function :
414  *  Purpose  : 
415  */
416 //============================================================================
417 CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(CORBA::Long theTag, SALOMEDS::SObject_out theSObject)
418 {
419   TDF_Label aLabel = _lab.FindChild(theTag,false);
420   if(aLabel.IsNull()) 
421     return false;
422   
423   theSObject = SALOMEDS_SObject_i::NewRef(_study,aLabel)._retn(); 
424   return true;
425 }  
426
427 //============================================================================
428 /*! Function :
429  *  Purpose  : 
430  */
431 //============================================================================
432 char* SALOMEDS_SObject_i::Name()
433 {
434   return CORBA::string_dup(_name.c_str());
435 }
436   
437 //============================================================================
438 /*! Function :
439  *  Purpose  : 
440  */
441 //============================================================================
442 void  SALOMEDS_SObject_i::Name(const char* theName)
443 {
444   _name = theName;
445 }
446   
447 //============================================================================
448 /*! Function :
449  *  Purpose  : 
450  */
451 //============================================================================
452 CORBA::Short SALOMEDS_SObject_i::Tag()
453 {
454   return _lab.Tag();
455 }
456
457 //============================================================================
458 /*! Function :
459  *  Purpose  : 
460  */
461 //============================================================================
462 CORBA::Short SALOMEDS_SObject_i::Depth()
463 {
464   return _lab.Depth();
465 }
466
467 //============================================================================
468 /*! Function :
469  *  Purpose  : 
470  */
471 //============================================================================
472 CORBA::Object_ptr SALOMEDS_SObject_i::GetObject()
473 {
474   try {
475     Handle(SALOMEDS_IORAttribute) anAttr;
476     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
477       CORBA::ORB_var anORB = _study->GetStudyManager()->GetORB();
478       return anORB->string_to_object(Str(anAttr->Get()));
479     }
480   }catch(...){
481   }
482   return CORBA::Object::_nil();
483 }
484
485 //============================================================================
486 /*! Function :
487  *  Purpose  : 
488  */
489 //============================================================================
490 char* SALOMEDS_SObject_i::GetName() {
491   Handle(TDataStd_Name) anAttr;
492   if(_lab.FindAttribute(TDataStd_Name::GetID(),anAttr))
493     return CORBA::string_dup(Str(anAttr->Get()));
494
495   return CORBA::string_dup("");
496 }
497
498 //============================================================================
499 /*! Function :
500  *  Purpose  : 
501  */
502 //============================================================================
503 char* SALOMEDS_SObject_i::GetComment() {
504   Handle(TDataStd_Comment) anAttr;
505   if(_lab.FindAttribute(TDataStd_Comment::GetID(), anAttr))
506     return CORBA::string_dup(Str(anAttr->Get()));
507
508   return CORBA::string_dup("");
509 }
510
511 //============================================================================
512 /*! Function :
513  *  Purpose  : 
514  */
515 //============================================================================
516 char* SALOMEDS_SObject_i::GetIOR() {
517   Handle(SALOMEDS_IORAttribute) anAttr;
518   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
519     return CORBA::string_dup(Str(anAttr->Get()));
520
521   return CORBA::string_dup("");
522 }
523
524
525 //============================================================================
526 /*! Function : GetAllAttributes
527  *  Purpose  : Returns list of all attributes for this sobject
528  */
529 //============================================================================
530 SALOMEDS_SObject_i::TAttrHolder 
531 SALOMEDS_SObject_i::_FindGenAttribute(const Handle(TDF_Attribute)& theAttr)
532 {
533   TAttrHolder anGenAttr;
534
535   Standard_GUID aGUID = theAttr->ID();
536
537   TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(aGUID);
538   if(anIter != __GUID2AttrIDMap__.end())
539   {
540     const ::TAttributeID& anAttributeID = anIter->second;
541     TAttrMap::const_iterator anIter = myAttrMap.find(anAttributeID);
542     if(anIter != myAttrMap.end())
543       anGenAttr = anIter->second;
544
545     SALOMEDS_GenericAttribute_i* anAttr = anGenAttr.first;
546     if(anAttr != NULL){
547       if(anAttr->GetAttribute() != theAttr)
548         anAttr->SetAttribute(theAttr);
549     }else{
550       anGenAttr = _CreateGenAttribute(theAttr,anAttributeID.c_str());
551     }
552   }
553
554   return anGenAttr;
555 }
556
557
558 SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
559 {
560   SALOMEDS::ListOfAttributes_var aSeqOfAttr = new SALOMEDS::ListOfAttributes;
561   if(_lab.NbAttributes() > 0){
562     Standard_Integer i = 0;
563     for(TDF_AttributeIterator iter(_lab); iter.More(); iter.Next()) {
564       Handle(TDF_Attribute) anAttr = iter.Value();
565       TAttrHolder anAttrHolder = _FindGenAttribute(anAttr);
566       SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
567       if(!anGenAttr->_is_nil())
568       {
569         aSeqOfAttr->length(++i);
570         aSeqOfAttr[i-1] = anGenAttr._retn();
571       }
572     }
573   }
574
575   return aSeqOfAttr._retn();
576 }
577
578
579 //============================================================================
580 /*! Function : FindAttribute
581  *  Purpose  : Find attribute of given type on this SObject
582  */
583 //============================================================================
584 SALOMEDS_SObject_i::TAttrHolder 
585 SALOMEDS_SObject_i::_CreateGenAttribute(const Handle(TDF_Attribute)& theAttr,
586                                         const char* theType) 
587 {
588   SALOMEDS_GenericAttribute_i* anAttr;
589   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
590   if(anIter != __AttrID2FunMap__.end()){
591     const TAttrID2FunMap::data_type& aValue = anIter->second;
592     
593     if(aValue.myIsCheckLockedStudy())
594       _study->CheckLocked();
595     
596     anAttr = aValue.myNewInstance(theAttr,this);
597     return TAttrHolder(anAttr,anAttr->_this());
598   }
599   
600   if(strncmp(theType,"AttributeTreeNode",17) == 0){
601     anAttr = new SALOMEDS_AttributeTreeNode_i(theAttr,this);
602     return TAttrHolder(anAttr,anAttr->_this());
603   }
604   
605   if(strncmp(theType,"AttributeUserID",15) == 0){
606     anAttr =  new SALOMEDS_AttributeUserID_i(theAttr,this);
607     return TAttrHolder(anAttr,anAttr->_this());
608   }
609   
610   return TAttrHolder();
611 }
612
613
614 SALOMEDS_SObject_i::TAttrHolder 
615 SALOMEDS_SObject_i::_FindGenAttribute(const char* theType)
616 {
617   TAttrHolder anAttrHolder;
618   TAttrMap::const_iterator anIter = myAttrMap.find(theType);
619   if(anIter != myAttrMap.end())
620     anAttrHolder = anIter->second;
621
622   Standard_GUID aGUID = ::GetGUID(theType);
623   Handle(TDF_Attribute) anAttr;
624
625   if(_lab.FindAttribute(aGUID,anAttr)){
626     SALOMEDS_GenericAttribute_i* aGenAttr = anAttrHolder.first;
627     if(aGenAttr != NULL){
628       if(aGenAttr->GetAttribute() != anAttr)
629         aGenAttr->SetAttribute(anAttr);
630     }else{
631       anAttrHolder = _CreateGenAttribute(anAttr,theType);
632     }
633     aGenAttr = anAttrHolder.first;
634     if(aGenAttr != NULL)
635       myAttrMap[theType] = anAttrHolder;
636   }else{
637     myAttrMap.erase(theType);
638     //if(anGenAttr != NULL)
639     //  anGenAttr->Destroy();
640     return TAttrHolder();
641   }
642
643   return anAttrHolder;
644 }
645
646
647 SALOMEDS::GenericAttribute_ptr 
648 SALOMEDS_SObject_i::_FindCORBAAttribute(const char* theType)
649 {
650   TAttrHolder anAttr = _FindGenAttribute(theType);
651   SALOMEDS::GenericAttribute_var anGenAttr = anAttr.second;
652   if(!CORBA::is_nil(anGenAttr)){
653     return anGenAttr._retn();
654   }
655
656   return SALOMEDS::GenericAttribute::_nil();
657 }
658
659
660 CORBA::Boolean 
661 SALOMEDS_SObject_i::FindAttribute(SALOMEDS::GenericAttribute_out theAttribute, 
662                                   const char* theType)
663 {
664   theAttribute = _FindCORBAAttribute(theType);
665   return !CORBA::is_nil(theAttribute);
666 }
667
668
669 //============================================================================
670 /*! Function : FindAttribute
671  *  Purpose  : Find attribute of given type on this SObject
672  */
673 //============================================================================
674 Handle(TDF_Attribute) 
675   SALOMEDS_SObject_i::_AddAttribute(const char* theType) 
676 {
677   Handle(TDF_Attribute) anAttr;
678   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
679   if(anIter != __AttrID2FunMap__.end()){
680     const TAttrID2FunMap::data_type& aValue = anIter->second;
681     
682     if(aValue.myIsCheckLockedStudy())
683       _study->CheckLocked();
684     
685     anAttr = aValue.myNewAttribute();
686     _lab.AddAttribute(anAttr);
687     return anAttr;
688   }
689   
690   if(strncmp(theType, "AttributeTreeNode",17) == 0){
691     Standard_GUID aGUID;
692     if(strcmp(theType, "AttributeTreeNode") == 0){
693       aGUID = TDataStd_TreeNode::GetDefaultTreeID();
694     }else{
695       char aString[40] = "";
696       sprintf(aString, &theType[21]);
697       aGUID = Standard_GUID(aString); // create tree node GUID by name
698     }
699     if(!_lab.FindAttribute(aGUID,anAttr)){
700       _study->CheckLocked();
701       anAttr = TDataStd_TreeNode::Set(_lab,aGUID);
702       _lab.AddAttribute(anAttr);
703       return anAttr;
704     }
705   }
706   
707   if(strncmp(theType, "AttributeUserID",15) == 0){
708     Standard_GUID aGUID = SALOMEDS_AttributeUserID_i::GetGUID();
709     if(!_lab.FindAttribute(aGUID,anAttr)){
710       _study->CheckLocked();
711       anAttr = TDataStd_UAttribute::Set(_lab,aGUID);
712       _lab.AddAttribute(anAttr);
713       return anAttr;
714     }
715   }
716   
717   
718   return anAttr;
719 }
720
721
722 SALOMEDS::GenericAttribute_ptr 
723 SALOMEDS_SObject_i::FindOrCreateAttribute(const char* theType)
724 {
725   TAttrHolder anAttrHolder = _FindGenAttribute(theType);
726   SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
727   if(!anGenAttr->_is_nil())
728     return anGenAttr._retn();
729
730   Handle(TDF_Attribute) anAttr = _AddAttribute(theType);
731   if(!anAttr.IsNull()){
732     anAttrHolder = _CreateGenAttribute(anAttr,theType);
733     anGenAttr = anAttrHolder.second;
734     if(!anGenAttr->_is_nil())
735       return anGenAttr._retn();
736   }
737
738   return SALOMEDS::GenericAttribute::_nil();
739 }
740
741
742 //============================================================================
743 /*! Function : FindAttribute
744  *  Purpose  : Find attribute of given type on this SObject
745  */
746 //============================================================================
747 void SALOMEDS_SObject_i::RemoveAttribute(const char* theType)
748 {
749   _study->CheckLocked();
750   if(strcmp(theType, "AttributeIOR") == 0) { // postponed removing of CORBA objects
751     Handle(SALOMEDS_IORAttribute) anAttr;
752     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
753       _study->AddPostponed(Str(anAttr->Get()));
754     else 
755       return;
756   }
757   TAttrMap::iterator anIter = myAttrMap.find(theType);
758   if(anIter != myAttrMap.end()){
759     myAttrMap.erase(anIter);
760   }
761   _lab.ForgetAttribute(::GetGUID(theType));
762 }
763
764
765 void SALOMEDS_SObject_i::OnRemove()
766 {
767   Handle(TDF_Reference) aReference;
768   if(_lab.FindAttribute(TDF_Reference::GetID(),aReference)){
769     Handle(SALOMEDS_TargetAttribute) aTarget;
770     if(aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
771       aTarget->Remove(_lab);
772   }
773
774   Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
775   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
776     _study->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
777   }
778
779   myAttrMap.clear();
780
781   SALOMEDS_Study_i::TSObjectMap& anSObjectMap = _study->GetSObjectMap();
782   anSObjectMap.erase(_lab);
783 }