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