Salome HOME
5d6e163825e2b97cedfc328308e12615355ace29
[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     TCollection_AsciiString anEntry;
290     TDF_Tool::Entry(theLabel,anEntry);
291     SALOMEDS_SObject_i* aSObject = new SALOMEDS_SObject_i(theStudy,theLabel);
292     aSObjectHolder.first = aSObject;
293     aSObjectHolder.second = aSObject->_this();
294     anSObjectMap[theLabel] = aSObjectHolder;
295   }
296   return aSObjectHolder;
297 }
298
299 SALOMEDS_SObject_i*
300 SALOMEDS_SObject_i::NewPtr(SALOMEDS_Study_i* theStudy,
301                            const TDF_Label& theLabel)
302 {
303   return New(theStudy,theLabel).first;
304 }
305
306 SALOMEDS::SObject_var
307 SALOMEDS_SObject_i::NewRef(SALOMEDS_Study_i* theStudy,
308                            const TDF_Label& theLabel)
309 {
310   return New(theStudy,theLabel).second;
311 }
312
313 //============================================================================
314 /*! Function : constructor
315  *  Purpose  : 
316  */
317 //============================================================================
318 SALOMEDS_SObject_i::SALOMEDS_SObject_i(SALOMEDS_Study_i* theStudy,
319                                        const TDF_Label& theLabel):
320   _lab(theLabel),
321   _study(theStudy)
322 {
323 }
324
325 //============================================================================
326 /*! Function : destructor
327  *  Purpose  : 
328  */
329 //============================================================================
330 SALOMEDS_SObject_i::~SALOMEDS_SObject_i()
331 {
332 }
333   
334
335 //============================================================================
336 CORBA::ORB_var SALOMEDS_SObject_i::GetORB() const
337 {
338   return _study->GetORB();
339 }
340
341
342 //============================================================================
343 PortableServer::POA_var SALOMEDS_SObject_i::GetPOA() const
344 {
345   return _study->GetPOA();
346 }
347
348
349 //============================================================================
350 /*! Function :
351  *  Purpose  : 
352  */
353 //============================================================================
354 char* SALOMEDS_SObject_i::GetID()
355 {
356   TCollection_AsciiString anEntry;
357   TDF_Tool::Entry(_lab,anEntry);
358   return CORBA::string_dup(anEntry.ToCString());
359 }
360   
361 //============================================================================
362 /*! Function :
363  *  Purpose  : 
364  */
365 //============================================================================
366 SALOMEDS::SComponent_ptr SALOMEDS_SObject_i::GetFatherComponent()
367 {
368   TDF_Label aSCompLabel = _lab;
369   while(!SALOMEDS_SComponent_i::IsA(aSCompLabel) && !aSCompLabel.IsRoot()){
370     aSCompLabel = aSCompLabel.Father();
371   }
372   return SALOMEDS_SComponent_i::NewRef(_study,aSCompLabel)._retn();
373 }
374   
375 //============================================================================
376 /*! Function :
377  *  Purpose  : 
378  */
379 //============================================================================
380 SALOMEDS::SObject_ptr SALOMEDS_SObject_i::GetFather()
381 {
382   return SALOMEDS_SObject_i::NewRef(_study,_lab.Father())._retn();
383 }
384
385 //============================================================================
386 /*! Function :
387  *  Purpose  : 
388  */
389 //============================================================================
390 SALOMEDS::Study_ptr SALOMEDS_SObject_i::GetStudy()
391 {
392   return _study->_this();
393 }
394
395 //============================================================================
396 /*! Function : ReferencedObject
397  *  Purpose  : 
398  */
399 //============================================================================
400 CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out theSObject)
401 {
402   Handle(TDF_Reference) aRef;
403   if (!_lab.FindAttribute(TDF_Reference::GetID(),aRef))
404     return false;
405   
406   theSObject = SALOMEDS_SObject_i::NewRef(_study,aRef->Get())._retn(); 
407   return true;
408 }
409
410 //============================================================================
411 /*! Function :
412  *  Purpose  : 
413  */
414 //============================================================================
415 CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(CORBA::Long theTag, SALOMEDS::SObject_out theSObject)
416 {
417   TDF_Label aLabel = _lab.FindChild(theTag,false);
418   if(aLabel.IsNull()) 
419     return false;
420   
421   theSObject = SALOMEDS_SObject_i::NewRef(_study,aLabel)._retn(); 
422   return true;
423 }  
424
425 //============================================================================
426 /*! Function :
427  *  Purpose  : 
428  */
429 //============================================================================
430 char* SALOMEDS_SObject_i::Name()
431 {
432   return CORBA::string_dup(_name.c_str());
433 }
434   
435 //============================================================================
436 /*! Function :
437  *  Purpose  : 
438  */
439 //============================================================================
440 void  SALOMEDS_SObject_i::Name(const char* theName)
441 {
442   _name = theName;
443 }
444   
445 //============================================================================
446 /*! Function :
447  *  Purpose  : 
448  */
449 //============================================================================
450 CORBA::Short SALOMEDS_SObject_i::Tag()
451 {
452   return _lab.Tag();
453 }
454
455 //============================================================================
456 /*! Function :
457  *  Purpose  : 
458  */
459 //============================================================================
460 CORBA::Short SALOMEDS_SObject_i::Depth()
461 {
462   return _lab.Depth();
463 }
464
465 //============================================================================
466 /*! Function :
467  *  Purpose  : 
468  */
469 //============================================================================
470 CORBA::Object_ptr SALOMEDS_SObject_i::GetObject()
471 {
472   try {
473     Handle(SALOMEDS_IORAttribute) anAttr;
474     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
475       CORBA::ORB_var anORB = _study->GetStudyManager()->GetORB();
476       return anORB->string_to_object(Str(anAttr->Get()));
477     }
478   }catch(...){
479   }
480   return CORBA::Object::_nil();
481 }
482
483 //============================================================================
484 /*! Function :
485  *  Purpose  : 
486  */
487 //============================================================================
488 char* SALOMEDS_SObject_i::GetName() {
489   Handle(TDataStd_Name) anAttr;
490   if(_lab.FindAttribute(TDataStd_Name::GetID(),anAttr))
491     return CORBA::string_dup(Str(anAttr->Get()));
492
493   return CORBA::string_dup("");
494 }
495
496 //============================================================================
497 /*! Function :
498  *  Purpose  : 
499  */
500 //============================================================================
501 char* SALOMEDS_SObject_i::GetComment() {
502   Handle(TDataStd_Comment) anAttr;
503   if(_lab.FindAttribute(TDataStd_Comment::GetID(), anAttr))
504     return CORBA::string_dup(Str(anAttr->Get()));
505
506   return CORBA::string_dup("");
507 }
508
509 //============================================================================
510 /*! Function :
511  *  Purpose  : 
512  */
513 //============================================================================
514 char* SALOMEDS_SObject_i::GetIOR() {
515   Handle(SALOMEDS_IORAttribute) anAttr;
516   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
517     return CORBA::string_dup(Str(anAttr->Get()));
518
519   return CORBA::string_dup("");
520 }
521
522
523 //============================================================================
524 /*! Function : GetAllAttributes
525  *  Purpose  : Returns list of all attributes for this sobject
526  */
527 //============================================================================
528 SALOMEDS_GenericAttribute_i* 
529 SALOMEDS_SObject_i::_FindGenAttribute(const Handle(TDF_Attribute)& theAttr)
530 {
531   SALOMEDS_GenericAttribute_i* anGenAttr = NULL;
532
533   Standard_GUID aGUID = theAttr->ID();
534
535   TGUID2AttrIDMap::const_iterator anIter = __GUID2AttrIDMap__.find(aGUID);
536   if(anIter != __GUID2AttrIDMap__.end())
537   {
538     const ::TAttributeID& anAttributeID = anIter->second;
539     TAttrMap::const_iterator anIter = myAttrMap.find(anAttributeID);
540     if(anIter != myAttrMap.end())
541       anGenAttr = anIter->second;
542
543     if(anGenAttr != NULL){
544       if(anGenAttr->GetAttribute() != theAttr)
545         anGenAttr->SetAttribute(theAttr);
546     }else{
547       anGenAttr = _CreateGenAttribute(theAttr,anAttributeID.c_str());
548     }
549   }
550
551   return anGenAttr;
552 }
553
554
555 SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
556 {
557   SALOMEDS::ListOfAttributes_var aSeqOfAttr = new SALOMEDS::ListOfAttributes;
558   if(_lab.NbAttributes() > 0){
559     Standard_Integer i = 0;
560     for(TDF_AttributeIterator iter(_lab); iter.More(); iter.Next()) {
561       Handle(TDF_Attribute) anAttr = iter.Value();
562       if(SALOMEDS_GenericAttribute_i* anGenAttr = _FindGenAttribute(anAttr))
563       {
564         aSeqOfAttr->length(++i);
565         aSeqOfAttr[i-1] = anGenAttr->_this();
566       }
567     }
568   }
569
570   return aSeqOfAttr._retn();
571 }
572
573
574 //============================================================================
575 /*! Function : FindAttribute
576  *  Purpose  : Find attribute of given type on this SObject
577  */
578 //============================================================================
579 SALOMEDS_GenericAttribute_i* 
580 SALOMEDS_SObject_i::_CreateGenAttribute(const Handle(TDF_Attribute)& theAttr,
581                                         const char* theType) 
582 {
583   
584   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
585   if(anIter != __AttrID2FunMap__.end()){
586     const TAttrID2FunMap::data_type& aValue = anIter->second;
587     
588     if(aValue.myIsCheckLockedStudy())
589       _study->CheckLocked();
590     
591     return aValue.myNewInstance(theAttr,this);
592   }
593   
594   if(strncmp(theType,"AttributeTreeNode",17) == 0){
595     return new SALOMEDS_AttributeTreeNode_i(theAttr,this);
596   }
597   
598   if(strncmp(theType,"AttributeUserID",15) == 0){
599     return new SALOMEDS_AttributeUserID_i(theAttr,this);
600   }
601   
602   return NULL;
603 }
604
605
606 SALOMEDS_GenericAttribute_i* 
607 SALOMEDS_SObject_i::_FindGenAttribute(const char* theType)
608 {
609   SALOMEDS_GenericAttribute_i* anGenAttr = NULL;
610   TAttrMap::const_iterator anIter = myAttrMap.find(theType);
611   if(anIter != myAttrMap.end())
612     anGenAttr = anIter->second;
613
614   Standard_GUID aGUID = ::GetGUID(theType);
615   Handle(TDF_Attribute) anAttr;
616
617   if(_lab.FindAttribute(aGUID,anAttr)){
618     if(anGenAttr != NULL){
619       if(anGenAttr->GetAttribute() != anAttr)
620         anGenAttr->SetAttribute(anAttr);
621     }else{
622       anGenAttr = _CreateGenAttribute(anAttr,theType);
623     }
624     if(anGenAttr != NULL)
625       myAttrMap[theType] = anGenAttr;
626   }else{
627     myAttrMap.erase(theType);
628     //if(anGenAttr != NULL)
629     //  anGenAttr->Destroy();
630   }
631
632   return anGenAttr;
633 }
634
635
636 SALOMEDS::GenericAttribute_ptr 
637 SALOMEDS_SObject_i::_FindCORBAAttribute(const char* theType)
638 {
639   if(SALOMEDS_GenericAttribute_i* anGenAttr = _FindGenAttribute(theType))
640     return anGenAttr->_this();
641   return SALOMEDS::GenericAttribute::_nil();
642 }
643
644
645 CORBA::Boolean 
646 SALOMEDS_SObject_i::FindAttribute(SALOMEDS::GenericAttribute_out theAttribute, 
647                                   const char* theType)
648 {
649   theAttribute = _FindCORBAAttribute(theType);
650   return !CORBA::is_nil(theAttribute);
651 }
652
653
654 //============================================================================
655 /*! Function : FindAttribute
656  *  Purpose  : Find attribute of given type on this SObject
657  */
658 //============================================================================
659 Handle(TDF_Attribute) 
660   SALOMEDS_SObject_i::_AddAttribute(const char* theType) 
661 {
662   Handle(TDF_Attribute) anAttr;
663   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
664   if(anIter != __AttrID2FunMap__.end()){
665     const TAttrID2FunMap::data_type& aValue = anIter->second;
666     
667     if(aValue.myIsCheckLockedStudy())
668       _study->CheckLocked();
669     
670     anAttr = aValue.myNewAttribute();
671     _lab.AddAttribute(anAttr);
672     return anAttr;
673   }
674   
675   if(strncmp(theType, "AttributeTreeNode",17) == 0){
676     Standard_GUID aGUID;
677     if(strcmp(theType, "AttributeTreeNode") == 0){
678       aGUID = TDataStd_TreeNode::GetDefaultTreeID();
679     }else{
680       char aString[40] = "";
681       sprintf(aString, &theType[21]);
682       aGUID = Standard_GUID(aString); // create tree node GUID by name
683     }
684     if(!_lab.FindAttribute(aGUID,anAttr)){
685       _study->CheckLocked();
686       anAttr = TDataStd_TreeNode::Set(_lab,aGUID);
687       _lab.AddAttribute(anAttr);
688       return anAttr;
689     }
690   }
691   
692   if(strncmp(theType, "AttributeUserID",15) == 0){
693     Standard_GUID aGUID = SALOMEDS_AttributeUserID_i::GetGUID();
694     if(!_lab.FindAttribute(aGUID,anAttr)){
695       _study->CheckLocked();
696       anAttr = TDataStd_UAttribute::Set(_lab,aGUID);
697       _lab.AddAttribute(anAttr);
698       return anAttr;
699     }
700   }
701   
702   
703   return anAttr;
704 }
705
706
707 SALOMEDS::GenericAttribute_ptr 
708 SALOMEDS_SObject_i::FindOrCreateAttribute(const char* theType)
709 {
710   if(SALOMEDS_GenericAttribute_i* anGenAttr = _FindGenAttribute(theType))
711     return anGenAttr->_this();
712   Handle(TDF_Attribute) anAttr = _AddAttribute(theType);
713   if(!anAttr.IsNull()){
714     if(SALOMEDS_GenericAttribute_i* anGenAttr = _CreateGenAttribute(anAttr,theType)){
715       return anGenAttr->_this();
716     }
717   }
718   return SALOMEDS::GenericAttribute::_nil();
719 }
720
721
722 //============================================================================
723 /*! Function : FindAttribute
724  *  Purpose  : Find attribute of given type on this SObject
725  */
726 //============================================================================
727 void SALOMEDS_SObject_i::RemoveAttribute(const char* theType)
728 {
729   _study->CheckLocked();
730   if(strcmp(theType, "AttributeIOR") == 0) { // postponed removing of CORBA objects
731     Handle(SALOMEDS_IORAttribute) anAttr;
732     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
733       _study->AddPostponed(Str(anAttr->Get()));
734     else 
735       return;
736   }
737   TAttrMap::iterator anIter = myAttrMap.find(theType);
738   if(anIter != myAttrMap.end()){
739     myAttrMap.erase(anIter);
740   }
741   _lab.ForgetAttribute(::GetGUID(theType));
742 }
743