Salome HOME
Fix on [Bug PAL7900] g++ 3.3 compatibility
[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::mapped_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 TDF_Label SALOMEDS_SObject_i::GetFatherComponentLabel()
369 {
370   TDF_Label aLabel = _lab;
371   while(!SALOMEDS_SComponent_i::IsA(aLabel) && !aLabel.IsRoot())
372     aLabel = aLabel.Father();
373
374   return aLabel;
375 }
376
377 SALOMEDS::SComponent_ptr SALOMEDS_SObject_i::GetFatherComponent()
378 {
379   TDF_Label aSCompLabel = GetFatherComponentLabel();
380
381   return SALOMEDS_SComponent_i::NewRef(_study,aSCompLabel)._retn();
382 }
383   
384 //============================================================================
385 /*! Function :
386  *  Purpose  : 
387  */
388 //============================================================================
389 SALOMEDS::SObject_ptr SALOMEDS_SObject_i::GetFather()
390 {
391   return SALOMEDS_SObject_i::NewRef(_study,_lab.Father())._retn();
392 }
393
394 //============================================================================
395 /*! Function :
396  *  Purpose  : 
397  */
398 //============================================================================
399 SALOMEDS::Study_ptr SALOMEDS_SObject_i::GetStudy()
400 {
401   return _study->_this();
402 }
403
404 //============================================================================
405 /*! Function : ReferencedObject
406  *  Purpose  : 
407  */
408 //============================================================================
409 CORBA::Boolean SALOMEDS_SObject_i::ReferencedObject(SALOMEDS::SObject_out theSObject)
410 {
411   Handle(TDF_Reference) aRef;
412   if (!_lab.FindAttribute(TDF_Reference::GetID(),aRef))
413     return false;
414   
415   theSObject = SALOMEDS_SObject_i::NewRef(_study,aRef->Get())._retn(); 
416   return true;
417 }
418
419 //============================================================================
420 /*! Function :
421  *  Purpose  : 
422  */
423 //============================================================================
424 CORBA::Boolean SALOMEDS_SObject_i::FindSubObject(CORBA::Long theTag, SALOMEDS::SObject_out theSObject)
425 {
426   TDF_Label aLabel = _lab.FindChild(theTag,false);
427   if(aLabel.IsNull()) 
428     return false;
429   
430   theSObject = SALOMEDS_SObject_i::NewRef(_study,aLabel)._retn(); 
431   return true;
432 }  
433
434 //============================================================================
435 /*! Function :
436  *  Purpose  : 
437  */
438 //============================================================================
439 char* SALOMEDS_SObject_i::Name()
440 {
441   return CORBA::string_dup(_name.c_str());
442 }
443   
444 //============================================================================
445 /*! Function :
446  *  Purpose  : 
447  */
448 //============================================================================
449 void  SALOMEDS_SObject_i::Name(const char* theName)
450 {
451   _name = theName;
452 }
453   
454 //============================================================================
455 /*! Function :
456  *  Purpose  : 
457  */
458 //============================================================================
459 CORBA::Short SALOMEDS_SObject_i::Tag()
460 {
461   return _lab.Tag();
462 }
463
464 //============================================================================
465 /*! Function :
466  *  Purpose  : 
467  */
468 //============================================================================
469 CORBA::Short SALOMEDS_SObject_i::Depth()
470 {
471   return _lab.Depth();
472 }
473
474 //============================================================================
475 /*! Function :
476  *  Purpose  : 
477  */
478 //============================================================================
479 CORBA::Object_ptr SALOMEDS_SObject_i::GetObject()
480 {
481   try {
482     Handle(SALOMEDS_IORAttribute) anAttr;
483     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
484       CORBA::ORB_var anORB = _study->GetStudyManager()->GetORB();
485       return anORB->string_to_object(Str(anAttr->Get()));
486     }
487   }catch(...){
488   }
489   return CORBA::Object::_nil();
490 }
491
492 //============================================================================
493 /*! Function :
494  *  Purpose  : 
495  */
496 //============================================================================
497 char* SALOMEDS_SObject_i::GetName() {
498   Handle(TDataStd_Name) anAttr;
499   if(_lab.FindAttribute(TDataStd_Name::GetID(),anAttr))
500     return CORBA::string_dup(Str(anAttr->Get()));
501
502   return CORBA::string_dup("");
503 }
504
505 //============================================================================
506 /*! Function :
507  *  Purpose  : 
508  */
509 //============================================================================
510 char* SALOMEDS_SObject_i::GetComment() {
511   Handle(TDataStd_Comment) anAttr;
512   if(_lab.FindAttribute(TDataStd_Comment::GetID(), anAttr))
513     return CORBA::string_dup(Str(anAttr->Get()));
514
515   return CORBA::string_dup("");
516 }
517
518 //============================================================================
519 /*! Function :
520  *  Purpose  : 
521  */
522 //============================================================================
523 char* SALOMEDS_SObject_i::GetIOR() {
524   Handle(SALOMEDS_IORAttribute) anAttr;
525   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
526     return CORBA::string_dup(Str(anAttr->Get()));
527
528   return CORBA::string_dup("");
529 }
530
531
532 //============================================================================
533 /*! Function : GetAllAttributes
534  *  Purpose  : Returns list of all attributes for this sobject
535  */
536 //============================================================================
537 SALOMEDS_SObject_i::TAttrHolder 
538 SALOMEDS_SObject_i::_FindGenAttribute(const Handle(TDF_Attribute)& theAttr)
539 {
540   std::string aType = GetType(theAttr);
541   return _FindGenAttribute(aType.c_str());
542 }
543
544
545 SALOMEDS::ListOfAttributes* SALOMEDS_SObject_i::GetAllAttributes()
546 {
547   SALOMEDS::ListOfAttributes_var aSeqOfAttr = new SALOMEDS::ListOfAttributes;
548   if(_lab.NbAttributes() > 0){
549     Standard_Integer i = 0;
550     for(TDF_AttributeIterator iter(_lab); iter.More(); iter.Next()) {
551       Handle(TDF_Attribute) anAttr = iter.Value();
552       TAttrHolder anAttrHolder = _FindGenAttribute(anAttr);
553       SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
554       if(!anGenAttr->_is_nil())
555       {
556         aSeqOfAttr->length(++i);
557         aSeqOfAttr[i-1] = anGenAttr._retn();
558       }
559     }
560   }
561
562   return aSeqOfAttr._retn();
563 }
564
565
566 //============================================================================
567 /*! Function : FindAttribute
568  *  Purpose  : Find attribute of given type on this SObject
569  */
570 //============================================================================
571 SALOMEDS_SObject_i::TAttrHolder 
572 SALOMEDS_SObject_i::_CreateGenAttribute(const Handle(TDF_Attribute)& theAttr,
573                                         const char* theType) 
574 {
575   SALOMEDS_GenericAttribute_i* anAttr;
576   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
577   if(anIter != __AttrID2FunMap__.end()){
578     const TAttrID2FunMap::data_type& aValue = anIter->second;
579     
580     if(aValue.myIsCheckLockedStudy())
581       _study->CheckLocked();
582     
583     anAttr = aValue.myNewInstance(theAttr,this);
584     return TAttrHolder(anAttr,anAttr->_this());
585   }
586   
587   if(strncmp(theType,"AttributeTreeNode",17) == 0){
588     anAttr = new SALOMEDS_AttributeTreeNode_i(theAttr,this);
589     return TAttrHolder(anAttr,anAttr->_this());
590   }
591   
592   if(strncmp(theType,"AttributeUserID",15) == 0){
593     anAttr =  new SALOMEDS_AttributeUserID_i(theAttr,this);
594     return TAttrHolder(anAttr,anAttr->_this());
595   }
596   
597   return TAttrHolder();
598 }
599
600
601 SALOMEDS_SObject_i::TAttrHolder 
602 SALOMEDS_SObject_i::_FindGenAttribute(const char* theType)
603 {
604   TAttrHolder anAttrHolder;
605   TAttrMap::const_iterator anIter = myAttrMap.find(theType);
606   if(anIter != myAttrMap.end())
607     anAttrHolder = anIter->second;
608
609   Standard_GUID aGUID = ::GetGUID(theType);
610   Handle(TDF_Attribute) anAttr;
611
612   if(_lab.FindAttribute(aGUID,anAttr)){
613     SALOMEDS_GenericAttribute_i* aGenAttr = anAttrHolder.first;
614     if(aGenAttr != NULL){
615       if(aGenAttr->GetAttribute() != anAttr)
616         aGenAttr->SetAttribute(anAttr);
617     }else{
618       anAttrHolder = _CreateGenAttribute(anAttr,theType);
619     }
620     aGenAttr = anAttrHolder.first;
621     if(aGenAttr != NULL)
622       myAttrMap[theType] = anAttrHolder;
623   }else{
624     //myAttrMap.erase(theType);
625     //if(anGenAttr != NULL)
626     //  anGenAttr->Destroy();
627     return TAttrHolder();
628   }
629
630   return anAttrHolder;
631 }
632
633
634 SALOMEDS::GenericAttribute_ptr 
635 SALOMEDS_SObject_i::_FindCORBAAttribute(const char* theType)
636 {
637   TAttrHolder anAttr = _FindGenAttribute(theType);
638   SALOMEDS::GenericAttribute_var anGenAttr = anAttr.second;
639   if(!CORBA::is_nil(anGenAttr)){
640     return anGenAttr._retn();
641   }
642
643   return SALOMEDS::GenericAttribute::_nil();
644 }
645
646
647 CORBA::Boolean 
648 SALOMEDS_SObject_i::FindAttribute(SALOMEDS::GenericAttribute_out theAttribute, 
649                                   const char* theType)
650 {
651   theAttribute = _FindCORBAAttribute(theType);
652   return !CORBA::is_nil(theAttribute);
653 }
654
655
656 //============================================================================
657 /*! Function : FindAttribute
658  *  Purpose  : Find attribute of given type on this SObject
659  */
660 //============================================================================
661 Handle(TDF_Attribute) 
662   SALOMEDS_SObject_i::_AddAttribute(const char* theType) 
663 {
664   Handle(TDF_Attribute) anAttr;
665   TAttrID2FunMap::const_iterator anIter = __AttrID2FunMap__.find(theType);
666   if(anIter != __AttrID2FunMap__.end()){
667     const TAttrID2FunMap::data_type& aValue = anIter->second;
668     
669     if(aValue.myIsCheckLockedStudy())
670       _study->CheckLocked();
671     
672     anAttr = aValue.myNewAttribute();
673     _lab.AddAttribute(anAttr);
674     return anAttr;
675   }
676   
677   if(strncmp(theType, "AttributeTreeNode",17) == 0){
678     Standard_GUID aGUID;
679     if(strcmp(theType, "AttributeTreeNode") == 0){
680       aGUID = TDataStd_TreeNode::GetDefaultTreeID();
681     }else{
682       char aString[40] = "";
683       sprintf(aString, &theType[21]);
684       aGUID = Standard_GUID(aString); // create tree node GUID by name
685     }
686     if(!_lab.FindAttribute(aGUID,anAttr)){
687       _study->CheckLocked();
688       anAttr = TDataStd_TreeNode::Set(_lab,aGUID);
689       return anAttr;
690     }
691   }
692   
693   if(strncmp(theType, "AttributeUserID",15) == 0){
694     Standard_GUID aGUID = SALOMEDS_AttributeUserID_i::GetGUID();
695     if(!_lab.FindAttribute(aGUID,anAttr)){
696       _study->CheckLocked();
697       anAttr = TDataStd_UAttribute::Set(_lab,aGUID);
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   TAttrHolder anAttrHolder = _FindGenAttribute(theType);
711   SALOMEDS::GenericAttribute_var anGenAttr = anAttrHolder.second;
712   if(!anGenAttr->_is_nil())
713     return anGenAttr._retn();
714
715   Handle(TDF_Attribute) anAttr = _AddAttribute(theType);
716   if(!anAttr.IsNull()){
717     anAttrHolder = _CreateGenAttribute(anAttr,theType);
718     anGenAttr = anAttrHolder.second;
719     if(!anGenAttr->_is_nil())
720       return anGenAttr._retn();
721   }
722
723   return SALOMEDS::GenericAttribute::_nil();
724 }
725
726
727 //============================================================================
728 /*! Function : FindAttribute
729  *  Purpose  : Find attribute of given type on this SObject
730  */
731 //============================================================================
732 void SALOMEDS_SObject_i::RemoveAttribute(const char* theType)
733 {
734   _study->CheckLocked();
735   if(strcmp(theType, "AttributeIOR") == 0) { // postponed removing of CORBA objects
736     Handle(SALOMEDS_IORAttribute) anAttr;
737     if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
738       _study->AddPostponed(Str(anAttr->Get()));
739     else 
740       return;
741   }
742   TAttrMap::iterator anIter = myAttrMap.find(theType);
743   if(anIter != myAttrMap.end()){
744     //myAttrMap.erase(anIter);
745   }
746   _lab.ForgetAttribute(::GetGUID(theType));
747 }
748
749
750 void SALOMEDS_SObject_i::OnRemove()
751 {
752   Handle(TDF_Reference) aReference;
753   if(_lab.FindAttribute(TDF_Reference::GetID(),aReference)){
754     Handle(SALOMEDS_TargetAttribute) aTarget;
755     if(aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
756       aTarget->Remove(_lab);
757   }
758
759   Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
760   if(_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
761     _study->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
762   }
763
764   //myAttrMap.clear();
765
766   //SALOMEDS_Study_i::TSObjectMap& anSObjectMap = _study->GetSObjectMap();
767   //anSObjectMap.erase(_lab);
768 }