Salome HOME
Fix on [Bug PAL7750] Regression of UNDO in GEOM
[modules/kernel.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     const TAttributeID& anAttributeID = anIter->second;
540     anGenAttr = _FindGenAttribute(anAttributeID.c_str());
541   }
542
543   return anGenAttr;
544 }
545
546
547 SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
548 {
549   SALOMEDS::ListOfAttributes_var aSeqOfAttr = new SALOMEDS::ListOfAttributes;
550   if(_lab.NbAttributes() > 0){
551     Standard_Integer i = 0;
552     for(TDF_AttributeIterator iter(_lab); iter.More(); iter.Next()) {
553       Handle(TDF_Attribute) anAttr = iter.Value();
554       TAttrHolder anAttrHolder = _FindGenAttribute(anAttr);
555       SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
556       if(!anGenAttr->_is_nil())
557       {
558         aSeqOfAttr->length(++i);
559         aSeqOfAttr[i-1] = anGenAttr._retn();
560       }
561     }
562   }
563
564   return aSeqOfAttr._retn();
565 }
566
567
568 //============================================================================
569 /*! Function : FindAttribute
570  *  Purpose  : Find attribute of given type on this SObject
571  */
572 //============================================================================
573 SALOMEDS_SObject_i::TAttrHolder 
574 SALOMEDS_SObject_i::_CreateGenAttribute(const Handle(TDF_Attribute)& theAttr,
575                                         const char* theType) 
576 {
577   SALOMEDS_GenericAttribute_i* anAttr;
578   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
579   if(anIter != __AttrID2FunMap__.end()){
580     const TAttrID2FunMap::data_type& aValue = anIter->second;
581     
582     if(aValue.myIsCheckLockedStudy())
583       _study->CheckLocked();
584     
585     anAttr = aValue.myNewInstance(theAttr,this);
586     return TAttrHolder(anAttr,anAttr->_this());
587   }
588   
589   if(strncmp(theType,"AttributeTreeNode",17) == 0){
590     anAttr = new SALOMEDS_AttributeTreeNode_i(theAttr,this);
591     return TAttrHolder(anAttr,anAttr->_this());
592   }
593   
594   if(strncmp(theType,"AttributeUserID",15) == 0){
595     anAttr =  new SALOMEDS_AttributeUserID_i(theAttr,this);
596     return TAttrHolder(anAttr,anAttr->_this());
597   }
598   
599   return TAttrHolder();
600 }
601
602
603 SALOMEDS_SObject_i::TAttrHolder 
604 SALOMEDS_SObject_i::_FindGenAttribute(const char* theType)
605 {
606   TAttrHolder anAttrHolder;
607   TAttrMap::const_iterator anIter = myAttrMap.find(theType);
608   if(anIter != myAttrMap.end())
609     anAttrHolder = anIter->second;
610
611   Standard_GUID aGUID = ::GetGUID(theType);
612   Handle(TDF_Attribute) anAttr;
613
614   if(_lab.FindAttribute(aGUID,anAttr)){
615     SALOMEDS_GenericAttribute_i* aGenAttr = anAttrHolder.first;
616     if(aGenAttr != NULL){
617       if(aGenAttr->GetAttribute() != anAttr)
618         aGenAttr->SetAttribute(anAttr);
619     }else{
620       anAttrHolder = _CreateGenAttribute(anAttr,theType);
621     }
622     aGenAttr = anAttrHolder.first;
623     if(aGenAttr != NULL)
624       myAttrMap[theType] = anAttrHolder;
625   }else{
626     myAttrMap.erase(theType);
627     //if(anGenAttr != NULL)
628     //  anGenAttr->Destroy();
629     return TAttrHolder();
630   }
631
632   return anAttrHolder;
633 }
634
635
636 SALOMEDS::GenericAttribute_ptr 
637 SALOMEDS_SObject_i::_FindCORBAAttribute(const char* theType)
638 {
639   TAttrHolder anAttr = _FindGenAttribute(theType);
640   SALOMEDS::GenericAttribute_var anGenAttr = anAttr.second;
641   if(!CORBA::is_nil(anGenAttr)){
642     return anGenAttr._retn();
643   }
644
645   return SALOMEDS::GenericAttribute::_nil();
646 }
647
648
649 CORBA::Boolean 
650 SALOMEDS_SObject_i::FindAttribute(SALOMEDS::GenericAttribute_out theAttribute, 
651                                   const char* theType)
652 {
653   theAttribute = _FindCORBAAttribute(theType);
654   return !CORBA::is_nil(theAttribute);
655 }
656
657
658 //============================================================================
659 /*! Function : FindAttribute
660  *  Purpose  : Find attribute of given type on this SObject
661  */
662 //============================================================================
663 Handle(TDF_Attribute) 
664   SALOMEDS_SObject_i::_AddAttribute(const char* theType) 
665 {
666   Handle(TDF_Attribute) anAttr;
667   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
668   if(anIter != __AttrID2FunMap__.end()){
669     const TAttrID2FunMap::data_type& aValue = anIter->second;
670     
671     if(aValue.myIsCheckLockedStudy())
672       _study->CheckLocked();
673     
674     anAttr = aValue.myNewAttribute();
675     _lab.AddAttribute(anAttr);
676     return anAttr;
677   }
678   
679   if(strncmp(theType, "AttributeTreeNode",17) == 0){
680     Standard_GUID aGUID;
681     if(strcmp(theType, "AttributeTreeNode") == 0){
682       aGUID = TDataStd_TreeNode::GetDefaultTreeID();
683     }else{
684       char aString[40] = "";
685       sprintf(aString, &theType[21]);
686       aGUID = Standard_GUID(aString); // create tree node GUID by name
687     }
688     if(!_lab.FindAttribute(aGUID,anAttr)){
689       _study->CheckLocked();
690       anAttr = TDataStd_TreeNode::Set(_lab,aGUID);
691       _lab.AddAttribute(anAttr);
692       return anAttr;
693     }
694   }
695   
696   if(strncmp(theType, "AttributeUserID",15) == 0){
697     Standard_GUID aGUID = SALOMEDS_AttributeUserID_i::GetGUID();
698     if(!_lab.FindAttribute(aGUID,anAttr)){
699       _study->CheckLocked();
700       anAttr = TDataStd_UAttribute::Set(_lab,aGUID);
701       _lab.AddAttribute(anAttr);
702       return anAttr;
703     }
704   }
705   
706   
707   return anAttr;
708 }
709
710
711 SALOMEDS::GenericAttribute_ptr 
712 SALOMEDS_SObject_i::FindOrCreateAttribute(const char* theType)
713 {
714   TAttrHolder anAttrHolder = _FindGenAttribute(theType);
715   SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
716   if(!anGenAttr->_is_nil())
717     return anGenAttr._retn();
718
719   Handle(TDF_Attribute) anAttr = _AddAttribute(theType);
720   if(!anAttr.IsNull()){
721     anAttrHolder = _CreateGenAttribute(anAttr,theType);
722     anGenAttr = anAttrHolder.second;
723     if(!anGenAttr->_is_nil())
724       return anGenAttr._retn();
725   }
726
727   return SALOMEDS::GenericAttribute::_nil();
728 }
729
730
731 //============================================================================
732 /*! Function : FindAttribute
733  *  Purpose  : Find attribute of given type on this SObject
734  */
735 //============================================================================
736 void SALOMEDS_SObject_i::RemoveAttribute(const char* theType)
737 {
738   _study->CheckLocked();
739   if(strcmp(theType, "AttributeIOR") == 0) { // postponed removing of CORBA objects
740     Handle(SALOMEDS_IORAttribute) anAttr;
741     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
742       _study->AddPostponed(Str(anAttr->Get()));
743     else 
744       return;
745   }
746   TAttrMap::iterator anIter = myAttrMap.find(theType);
747   if(anIter != myAttrMap.end()){
748     myAttrMap.erase(anIter);
749   }
750   _lab.ForgetAttribute(::GetGUID(theType));
751 }
752
753
754 void SALOMEDS_SObject_i::OnRemove()
755 {
756   Handle(TDF_Reference) aReference;
757   if(_lab.FindAttribute(TDF_Reference::GetID(),aReference)){
758     Handle(SALOMEDS_TargetAttribute) aTarget;
759     if(aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
760       aTarget->Remove(_lab);
761   }
762
763   Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
764   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
765     _study->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
766   }
767
768   myAttrMap.clear();
769
770   SALOMEDS_Study_i::TSObjectMap& anSObjectMap = _study->GetSObjectMap();
771   anSObjectMap.erase(_lab);
772 }