Salome HOME
Fix on [Bug PAL7023] Problem loading MED file with a large number of families (same...
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_UseCaseBuilder_i.cxx
1 //  SALOME SALOMEDS : data structure of SALOME and sources of Salome data server 
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : SALOMEDS_UseCaseBuilder_i.cxx
8 //  Author : Yves FRICAUD
9 //  Module : SALOME
10
11 #include "SALOMEDS_UseCaseBuilder_i.hxx"
12 #include "SALOMEDS_Study_i.hxx"
13 #include "SALOMEDS_SObject_i.hxx"
14 #include "SALOMEDS_UseCaseIterator_i.hxx"
15
16 #include <TDF_Label.hxx>
17 #include <TDF_Tool.hxx>
18 #include <TDF_Data.hxx>
19 #include <TDF_Reference.hxx>
20 #include <TDF_AttributeList.hxx>
21 #include <TDF_ListIteratorOfAttributeList.hxx>
22 #include <TDataStd_ChildNodeIterator.hxx>
23 #include <TCollection_AsciiString.hxx>
24 #include <TDF_ChildIterator.hxx>
25
26 #include <TDataStd_Integer.hxx>
27 #include <TDataStd_Name.hxx>
28 #include <Standard_GUID.hxx>
29
30 #define USE_CASE_LABEL_TAG           2
31 #define USE_CASE_GUID                "AA43BB12-D9CD-11d6-945D-0050DA506788"
32
33 #include "utilities.h"
34
35 using namespace std;
36
37 //============================================================================
38 /*! Function : constructor
39  *  Purpose  :
40  */
41 //============================================================================
42 SALOMEDS_UseCaseBuilder_i::SALOMEDS_UseCaseBuilder_i(SALOMEDS_Study_i* theStudy,
43                                                      const Handle(TDocStd_Document)& theDocument):
44   _doc(theDocument),
45   _study(theStudy)
46 {
47   if(_doc.IsNull()) return;
48
49   TDF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
50   if(!aLabel.FindAttribute(Standard_GUID(USE_CASE_GUID), _root)) {
51     _root = TDataStd_TreeNode::Set(aLabel, Standard_GUID(USE_CASE_GUID));
52   }
53
54   Handle(TDF_Reference) aRef;
55   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
56     aRef = TDF_Reference::Set(_root->Label(), _root->Label());  
57   }  
58
59   Handle(TDataStd_Name) aNameAttr;
60   if(!aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttr)) { 
61     aNameAttr = TDataStd_Name::Set(aLabel, "Use cases"); 
62   }
63
64 }
65
66 //============================================================================
67 /*! Function : destructor
68  *  Purpose  :
69  */
70 //============================================================================
71 SALOMEDS_UseCaseBuilder_i::~SALOMEDS_UseCaseBuilder_i()
72 {
73 }
74
75
76 //============================================================================
77 CORBA::ORB_var SALOMEDS_UseCaseBuilder_i::GetORB() const
78 {
79   return _study->GetORB();
80 }
81
82
83 //============================================================================
84 PortableServer::POA_var SALOMEDS_UseCaseBuilder_i::GetPOA() const
85 {
86   return _study->GetPOA();
87 }
88
89
90 //============================================================================
91 //============================================================================
92 /*! Function : Append
93  *  Purpose  : 
94  */
95 //============================================================================
96 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::Append(SALOMEDS::SObject_ptr theObject)
97 {
98   if(_root.IsNull() || theObject->_is_nil()) return 0;
99
100   TDF_Label aLabel;
101
102   TDF_Tool::Label(_root->Label().Data(), theObject->GetID(), aLabel);
103   if(aLabel.IsNull()) return 0;
104
105   Handle(TDataStd_TreeNode) aNode, aCurrentNode;
106   aNode = TDataStd_TreeNode::Set(aLabel, _root->ID());
107   aNode->Remove();
108
109   Handle(TDF_Reference) aRef;
110   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
111     aRef = TDF_Reference::Set(_root->Label(), _root->Label());  
112   }  
113   TDF_Label aCurrent = aRef->Get();
114
115   if(aCurrent.IsNull() || !aCurrent.FindAttribute(_root->ID(), aCurrentNode)) 
116     aCurrentNode = _root;
117
118   return aCurrentNode->Append(aNode);
119 }
120
121  //============================================================================
122 /*! Function : Remove
123  *  Purpose  :
124  */
125 //============================================================================
126 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::Remove(SALOMEDS::SObject_ptr theObject)
127 {
128   if(_root.IsNull() || theObject->_is_nil()) return 0;
129
130   TDF_Label aLabel;
131   TDF_Tool::Label(_root->Label().Data(), theObject->GetID(), aLabel);
132   if(aLabel.IsNull()) return 0;
133
134   Handle(TDataStd_TreeNode) aNode;
135   if(!aLabel.FindAttribute(_root->ID(), aNode)) return 0;
136
137   aNode->Remove();
138
139   TDF_AttributeList aList;
140   aList.Append(aNode);
141
142   Handle(TDF_Reference) aRef;
143   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
144     aRef = TDF_Reference::Set(_root->Label(), _root->Label());  
145   }  
146   TDF_Label aCurrent = aRef->Get();
147
148   TDataStd_ChildNodeIterator aChildItr(aNode, Standard_True);
149   for(; aChildItr.More(); aChildItr.Next()) 
150     aList.Append(aChildItr.Value());
151
152   TDF_ListIteratorOfAttributeList anIterator(aList);
153   for(; anIterator.More(); anIterator.Next()) {
154     if(anIterator.Value()->Label() ==  aCurrent) { //The current node is removed
155       aRef->Set(_root->Label()); //Reset the current node to the root
156     }
157     anIterator.Value()->Label().ForgetAttribute(_root->ID());
158   }
159
160   return 1;
161 }
162
163
164 //============================================================================
165 /*! Function : AppendTo
166  *  Purpose  :
167  */
168 //============================================================================
169 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::AppendTo(SALOMEDS::SObject_ptr theFather, 
170                                                    SALOMEDS::SObject_ptr theObject)
171 {
172   if(_root.IsNull() || theFather->_is_nil() || theObject->_is_nil()) return 0;
173
174   TDF_Label aFatherLabel, aLabel;
175   Handle(TDataStd_TreeNode) aFather, aNode;
176   
177   TDF_Tool::Label(_root->Label().Data(), theFather->GetID(), aFatherLabel);
178   if(aFatherLabel.IsNull()) return 0;
179   if(!aFatherLabel.FindAttribute(_root->ID(), aFather)) return 0;
180
181   TDF_Tool::Label(_root->Label().Data(), theObject->GetID(), aLabel);
182   if(aLabel.IsNull()) return 0;
183   if(!aLabel.FindAttribute(_root->ID(), aNode)) {
184     aNode = TDataStd_TreeNode::Set(aLabel, _root->ID());
185   }
186   else
187     aNode->Remove();
188
189   return aFather->Append(aNode);
190 }
191
192 //============================================================================
193 /*! Function : InsertBefore
194  *  Purpose  :
195  */
196 //============================================================================
197 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::InsertBefore(SALOMEDS::SObject_ptr theFirst, 
198                                                        SALOMEDS::SObject_ptr theNext)
199 {
200   if(_root.IsNull() || theFirst->_is_nil() || theNext->_is_nil()) return 0;
201
202   TDF_Label aFirstLabel, aLabel;
203   Handle(TDataStd_TreeNode) aFirstNode, aNode;
204   
205   TDF_Tool::Label(_root->Label().Data(), theFirst->GetID(), aFirstLabel);
206   if(aFirstLabel.IsNull()) return 0;
207   if(aFirstLabel.FindAttribute(_root->ID(), aFirstNode)) {
208     aFirstNode->Remove();
209     aFirstLabel.ForgetAttribute(aFirstNode->ID());
210   }
211
212   aFirstNode = TDataStd_TreeNode::Set(aFirstLabel, _root->ID());
213   
214
215   TDF_Tool::Label(_root->Label().Data(), theNext->GetID(), aLabel);
216   if(aLabel.IsNull()) return 0;
217   if(!aLabel.FindAttribute(_root->ID(), aNode)) return 0;
218
219   return aNode->InsertBefore(aFirstNode);
220 }
221
222
223 //============================================================================
224 /*! Function : SetCurrentObject
225  *  Purpose  :
226  */
227 //============================================================================
228 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::SetCurrentObject(SALOMEDS::SObject_ptr theObject)
229 {
230   if(_root.IsNull() || theObject->_is_nil()) return 0;
231
232   TDF_Label aLabel;
233   Handle(TDataStd_TreeNode) aNode;
234   TDF_Tool::Label(_root->Label().Data(), theObject->GetID(), aLabel);
235   if(aLabel.IsNull()) return 0;
236   if(!aLabel.FindAttribute(_root->ID(), aNode)) return 0;
237
238
239   Handle(TDF_Reference) aRef;
240   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
241     aRef = TDF_Reference::Set(_root->Label(), aNode->Label());  
242   }
243   
244   aRef->Set(aNode->Label());
245
246   return 1;
247 }
248
249 //============================================================================
250 /*! Function : SetRootCurrent
251  *  Purpose  :
252  */
253 //============================================================================
254 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::SetRootCurrent()
255 {
256   if(_root.IsNull()) return 0;
257    
258   Handle(TDF_Reference) aRef;
259   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) 
260     aRef = TDF_Reference::Set(_root->Label(), _root->Label());  
261
262   aRef->Set(_root->Label());
263   return 1;
264 }
265
266 //============================================================================
267 /*! Function : HasChildren
268  *  Purpose  :
269  */
270 //============================================================================
271 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::HasChildren(SALOMEDS::SObject_ptr theObject)
272 {
273   if(_root.IsNull()) return 0;
274
275   TDF_Label aLabel;
276   if (theObject->_is_nil()) aLabel = _root->Label();
277   else TDF_Tool::Label(_root->Label().Data(), theObject->GetID(), aLabel);
278   if(aLabel.IsNull()) return 0;
279
280   Handle(TDataStd_TreeNode) aNode;
281   if(!aLabel.FindAttribute(_root->ID(), aNode)) return 0;
282
283   return !(aNode->First().IsNull());
284 }
285
286 //============================================================================
287 /*! Function : SetName
288  *  Purpose  :
289  */
290 //============================================================================
291 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::SetName(const char* theName) {
292   if(_root.IsNull()) return 0;
293
294   Handle(TDataStd_Name) aNameAttrib;
295   TCollection_ExtendedString aName(const_cast<char*>(theName));
296
297   if (!_root->FindAttribute(TDataStd_Name::GetID(), aNameAttrib))
298     aNameAttrib = TDataStd_Name::Set(_root->Label(), aName);
299   else    
300     aNameAttrib->Set(aName);
301     
302   return 1;
303 }
304
305
306 //============================================================================
307 /*! Function : GetCurrentObject
308  *  Purpose  :
309  */
310 //============================================================================
311 SALOMEDS::SObject_ptr SALOMEDS_UseCaseBuilder_i::GetCurrentObject()
312 {
313   if(_root.IsNull()) return NULL;
314
315   Handle(TDF_Reference) aRef;
316   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
317     aRef = TDF_Reference::Set(_root->Label(), _root->Label());  
318   }  
319   TDF_Label aCurrent = aRef->Get();  
320   if(aCurrent.IsNull()) return NULL;
321
322   return SALOMEDS_SObject_i::NewRef(_study,aCurrent)._retn();
323 }
324
325 //============================================================================
326 /*! Function : GetName
327  *  Purpose  :
328  */
329 //============================================================================
330 char* SALOMEDS_UseCaseBuilder_i::GetName() {
331   CORBA::String_var aString;
332   if(_root.IsNull()) return aString._retn();
333
334   Handle(TDataStd_Name) aName;
335   if (!_root->FindAttribute(TDataStd_Name::GetID(), aName)) return aString._retn();
336   aString = CORBA::string_dup(TCollection_AsciiString(aName->Get()).ToCString());
337   return aString._retn();
338 }
339
340 //============================================================================ 
341 /*! Function :  IsUseCase
342  *  Purpose  :  
343  */ 
344 //============================================================================ 
345 CORBA::Boolean SALOMEDS_UseCaseBuilder_i::IsUseCase(SALOMEDS::SObject_ptr theObject)
346 {
347   if(theObject->_is_nil()) return false;
348   TDF_Label aFather, aLabel; 
349   TDF_Tool::Label(_doc->GetData(), theObject->GetID(), aLabel);
350   aFather = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
351   if(aLabel.Father() == aFather) return true;
352   return false;
353 }
354
355 //============================================================================ 
356 /*! Function : NewUseCase 
357  *  Purpose  :  
358  */ 
359 //============================================================================ 
360 SALOMEDS::SObject_ptr SALOMEDS_UseCaseBuilder_i::AddUseCase(const char* theName)
361 {
362   Standard_GUID aBasicGUID(USE_CASE_GUID);
363
364   //Create a use cases structure if it not exists 
365
366   Handle(TDataStd_TreeNode) aFatherNode, aNode;
367   Handle(TDataStd_Integer) anInteger;
368   Handle(TDF_Reference) aRef;
369
370   TDF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
371
372   if(!_root->FindAttribute(TDF_Reference::GetID(), aRef)) {
373     aRef = TDF_Reference::Set(aLabel, aLabel);
374   }
375  
376   if(!aRef->Get().FindAttribute(aBasicGUID, aFatherNode)) {
377     aFatherNode = TDataStd_TreeNode::Set(aRef->Get());
378   }
379
380   if(!_root->FindAttribute(TDataStd_Integer::GetID(), anInteger)) {
381     anInteger = TDataStd_Integer::Set(aLabel, 0);
382   }
383
384   //Create a new use case
385   anInteger->Set(anInteger->Get()+1);
386   TDF_Label aChild = aLabel.FindChild(anInteger->Get());
387   aNode = TDataStd_TreeNode::Set(aChild, aBasicGUID);
388   aFatherNode->Append(aNode);
389   TDataStd_Name::Set(aChild, TCollection_ExtendedString(const_cast<char*>(theName)));
390
391   return SALOMEDS_SObject_i::NewRef(_study,aChild)._retn();
392 }
393
394 //============================================================================
395 /*! Function : GetUseCaseIterator
396  *  Purpose  : Creates a new UseCase iterator, if anObject is null all use cases are iterated 
397  */
398 //============================================================================
399 SALOMEDS::UseCaseIterator_ptr SALOMEDS_UseCaseBuilder_i::GetUseCaseIterator(SALOMEDS::SObject_ptr anObject) 
400 {
401   TDF_Label aLabel;
402
403   if(!anObject->_is_nil()) {
404     TDF_Tool::Label(_doc->GetData(), anObject->GetID(), aLabel); //Iterate only sub tree in the use case
405   }
406   else {
407     aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
408   }
409
410   SALOMEDS_UseCaseIterator_i* aServant = new SALOMEDS_UseCaseIterator_i(_study,aLabel,USE_CASE_GUID,Standard_False);
411   return aServant->_this(); 
412 }