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