Salome HOME
PAL13000: Crash with 'import CALCULATOR_TEST_STUDY_WITHOUTIHM'
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_UseCaseBuilder.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : SALOMEDSImpl_UseCaseBuilder.cxx
21 //  Author : Sergey RUIN
22 //  Module : SALOME
23
24
25 #include "SALOMEDSImpl_UseCaseBuilder.hxx"
26 #include "SALOMEDSImpl_SObject.hxx"
27 #include "SALOMEDSImpl_SComponent.hxx"
28 #include "SALOMEDSImpl_Study.hxx"
29 #include "SALOMEDSImpl_Attributes.hxx"
30
31 #include <TDF_Label.hxx>
32 #include <TDF_Tool.hxx>
33 #include <TDF_Data.hxx>
34 #include <TDF_AttributeList.hxx>
35 #include <TDF_ListIteratorOfAttributeList.hxx>
36 #include <TCollection_AsciiString.hxx>
37 #include <TDF_ChildIterator.hxx>
38
39 using namespace std;
40
41 IMPLEMENT_STANDARD_HANDLE( SALOMEDSImpl_UseCaseBuilder, MMgt_TShared )
42 IMPLEMENT_STANDARD_RTTIEXT( SALOMEDSImpl_UseCaseBuilder, MMgt_TShared )
43
44
45 #define USE_CASE_LABEL_TAG           2
46 #define USE_CASE_GUID                "AA43BB12-D9CD-11d6-945D-0050DA506788"
47
48
49 //============================================================================
50 /*! Function : constructor
51  *  Purpose  :
52  */
53 //============================================================================
54 SALOMEDSImpl_UseCaseBuilder::SALOMEDSImpl_UseCaseBuilder(const Handle(TDocStd_Document)& theDocument)
55 :_doc(theDocument)
56 {
57   if(_doc.IsNull()) return;
58   
59   TDF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
60   if(!aLabel.FindAttribute(Standard_GUID(USE_CASE_GUID), _root)) {
61     _root = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, Standard_GUID(USE_CASE_GUID));
62   }
63  
64   Handle(SALOMEDSImpl_AttributeReference) aRef;
65   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
66     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
67   }  
68
69   Handle(SALOMEDSImpl_AttributeName) aNameAttr;
70   if(!aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aNameAttr)) { 
71     aNameAttr = SALOMEDSImpl_AttributeName::Set(aLabel, "Use cases"); 
72   }  
73 }
74
75 //============================================================================
76 /*! Function : destructor
77  *  Purpose  :
78  */
79 //============================================================================
80 SALOMEDSImpl_UseCaseBuilder::~SALOMEDSImpl_UseCaseBuilder()
81 {
82 }
83
84
85 //============================================================================
86 /*! Function : Append
87  *  Purpose  : 
88  */
89 //============================================================================
90 bool SALOMEDSImpl_UseCaseBuilder::Append(const Handle(SALOMEDSImpl_SObject)& theObject)
91 {
92   if(_root.IsNull() || theObject.IsNull()) return false;
93
94   TDF_Label aLabel = theObject->GetLabel();
95   if(aLabel.IsNull()) return false;
96
97   Handle(SALOMEDSImpl_AttributeTreeNode) aNode, aCurrentNode;
98   aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
99   aNode->Remove();
100
101   Handle(SALOMEDSImpl_AttributeReference) aRef;
102   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
103     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
104   }  
105
106   TDF_Label aCurrent = aRef->Get();
107   if(aCurrent.IsNull() || !aCurrent.FindAttribute(_root->ID(), aCurrentNode)) 
108     aCurrentNode = _root;
109
110   aCurrentNode->Append(aNode);
111
112   return true;
113 }
114
115  //============================================================================
116 /*! Function : Remove
117  *  Purpose  :
118  */
119 //============================================================================
120 bool SALOMEDSImpl_UseCaseBuilder::Remove(const Handle(SALOMEDSImpl_SObject)& theObject)
121 {
122   if(_root.IsNull() || theObject.IsNull()) return false;
123
124   TDF_Label aLabel = theObject->GetLabel();   
125   if(aLabel.IsNull()) return false;
126
127   Handle(SALOMEDSImpl_AttributeTreeNode) aNode;
128   if(!aLabel.FindAttribute(_root->ID(), aNode)) return false;
129
130   aNode->Remove();
131
132   TDF_AttributeList aList;
133   aList.Append(aNode);
134
135   Handle(SALOMEDSImpl_AttributeReference) aRef;
136   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
137     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
138   }  
139   TDF_Label aCurrent = aRef->Get();
140
141   SALOMEDSImpl_ChildNodeIterator aChildItr(aNode, Standard_True);
142   for(; aChildItr.More(); aChildItr.Next()) 
143     aList.Append(aChildItr.Value());
144
145   TDF_ListIteratorOfAttributeList anIterator(aList);
146   for(; anIterator.More(); anIterator.Next()) {
147     if(anIterator.Value()->Label() ==  aCurrent) { //The current node is removed
148       aRef->Set(_root->Label()); //Reset the current node to the root
149     }
150     anIterator.Value()->Label().ForgetAttribute(_root->ID());
151   }
152
153   return true;
154 }
155
156
157 //============================================================================
158 /*! Function : AppendTo
159  *  Purpose  :
160  */
161 //============================================================================
162 bool SALOMEDSImpl_UseCaseBuilder::AppendTo(const Handle(SALOMEDSImpl_SObject)& theFather, 
163                                            const Handle(SALOMEDSImpl_SObject)& theObject)
164 {
165   if(_root.IsNull() || theFather.IsNull() || theObject.IsNull()) return false;
166
167   TDF_Label aFatherLabel = theFather->GetLabel(), aLabel = theObject->GetLabel();
168   Handle(SALOMEDSImpl_AttributeTreeNode) aFather, aNode;
169   
170   if(aFatherLabel.IsNull()) return false;
171   if(!aFatherLabel.FindAttribute(_root->ID(), aFather)) return false;
172
173   if(aLabel.IsNull()) return false;
174   if(!aLabel.FindAttribute(_root->ID(), aNode)) {
175     aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID());
176   }
177
178   aNode->Remove();
179
180   return aFather->Append(aNode);
181 }
182
183 //============================================================================
184 /*! Function : InsertBefore
185  *  Purpose  :
186  */
187 //============================================================================
188 bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const Handle(SALOMEDSImpl_SObject)& theFirst, 
189                                                const Handle(SALOMEDSImpl_SObject)& theNext)
190 {
191   if(_root.IsNull() || theFirst.IsNull() || theNext.IsNull()) return false;
192
193   TDF_Label aFirstLabel = theFirst->GetLabel(), aLabel= theNext->GetLabel();
194   Handle(SALOMEDSImpl_AttributeTreeNode) aFirstNode, aNode;
195   
196   if(aFirstLabel.IsNull()) return false;
197   if(aFirstLabel.FindAttribute(_root->ID(), aFirstNode)) {
198     aFirstNode->Remove();
199     aFirstLabel.ForgetAttribute(aFirstNode->ID());
200   }
201
202   aFirstNode = SALOMEDSImpl_AttributeTreeNode::Set(aFirstLabel, _root->ID());
203   
204   if(aLabel.IsNull()) return false;
205   if(!aLabel.FindAttribute(_root->ID(), aNode)) return false;
206
207   aFirstNode->Remove();
208
209   return aNode->InsertBefore(aFirstNode);
210 }
211
212
213 //============================================================================
214 /*! Function : SetCurrentObject
215  *  Purpose  :
216  */
217 //============================================================================
218 bool SALOMEDSImpl_UseCaseBuilder::SetCurrentObject(const Handle(SALOMEDSImpl_SObject)& theObject)
219 {
220   if(_root.IsNull() || theObject.IsNull()) return false;
221
222   TDF_Label aLabel = theObject->GetLabel();
223   Handle(SALOMEDSImpl_AttributeTreeNode) aNode;
224   if(aLabel.IsNull()) return false;
225   if(!aLabel.FindAttribute(_root->ID(), aNode)) return false;
226
227
228   Handle(SALOMEDSImpl_AttributeReference) aRef;
229   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
230     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), aNode->Label());  
231   }
232   
233   aRef->Set(aNode->Label());
234
235   return true;
236 }
237
238 //============================================================================
239 /*! Function : SetRootCurrent
240  *  Purpose  :
241  */
242 //============================================================================
243 bool SALOMEDSImpl_UseCaseBuilder::SetRootCurrent()
244 {
245   if(_root.IsNull()) return false;
246    
247   Handle(SALOMEDSImpl_AttributeReference) aRef;
248   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) 
249     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
250
251   aRef->Set(_root->Label());
252   return true;
253 }
254
255 //============================================================================
256 /*! Function : HasChildren
257  *  Purpose  :
258  */
259 //============================================================================
260 bool SALOMEDSImpl_UseCaseBuilder::HasChildren(const Handle(SALOMEDSImpl_SObject)& theObject)
261 {
262   if(_root.IsNull()) return false;
263
264   TDF_Label aLabel;
265   if (theObject.IsNull()) aLabel = _root->Label();
266   else 
267     aLabel = theObject->GetLabel(); 
268   if(aLabel.IsNull()) return false;
269
270   Handle(SALOMEDSImpl_AttributeTreeNode) aNode;
271   if(!aLabel.FindAttribute(_root->ID(), aNode)) return false;
272
273   return !(aNode->GetFirst().IsNull());
274 }
275
276 //============================================================================
277 /*! Function : SetName
278  *  Purpose  :
279  */
280 //============================================================================
281 bool SALOMEDSImpl_UseCaseBuilder::SetName(const TCollection_AsciiString& theName) {
282   if(_root.IsNull()) return false;
283
284   Handle(SALOMEDSImpl_AttributeName) aNameAttrib;
285
286   if (!_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aNameAttrib))
287     aNameAttrib = SALOMEDSImpl_AttributeName::Set(_root->Label(), theName);
288   else    
289     aNameAttrib->SetValue(theName);
290     
291   return true;
292 }
293
294
295 //============================================================================
296 /*! Function : GetCurrentObject
297  *  Purpose  :
298  */
299 //============================================================================
300 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_UseCaseBuilder::GetCurrentObject()
301 {
302   if(_root.IsNull()) return NULL;
303
304   Handle(SALOMEDSImpl_AttributeReference) aRef;
305   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
306     aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label());  
307   }  
308   TDF_Label aCurrent = aRef->Get();  
309   if(aCurrent.IsNull()) return NULL;
310
311   return SALOMEDSImpl_Study::SObject(aCurrent);
312 }
313
314 //============================================================================
315 /*! Function : GetName
316  *  Purpose  :
317  */
318 //============================================================================
319 TCollection_AsciiString SALOMEDSImpl_UseCaseBuilder::GetName() 
320 {
321   TCollection_AsciiString aString;
322   if(_root.IsNull()) return aString;
323
324   Handle(SALOMEDSImpl_AttributeName) aName;
325   if (!_root->FindAttribute(SALOMEDSImpl_AttributeName::GetID(), aName)) return aString;
326   aString = TCollection_AsciiString(aName->Value());
327   return aString;
328 }
329
330 //============================================================================ 
331 /*! Function :  IsUseCase
332  *  Purpose  :  
333  */ 
334 //============================================================================ 
335 bool SALOMEDSImpl_UseCaseBuilder::IsUseCase(const Handle(SALOMEDSImpl_SObject)& theObject)
336 {
337   if(theObject.IsNull()) return false;
338   TDF_Label aFather, aLabel = theObject->GetLabel(); 
339   aFather = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
340   if(aLabel.Father() == aFather) return true;
341   return false;
342 }
343
344 //============================================================================ 
345 /*! Function : NewUseCase 
346  *  Purpose  :  
347  */ 
348 //============================================================================ 
349 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_UseCaseBuilder::AddUseCase(const TCollection_AsciiString& theName)
350 {
351   Standard_GUID aBasicGUID(USE_CASE_GUID);
352
353   //Create a use cases structure if it not exists 
354
355   Handle(SALOMEDSImpl_AttributeTreeNode) aFatherNode, aNode;
356   Handle(SALOMEDSImpl_AttributeInteger) anInteger;
357   Handle(SALOMEDSImpl_AttributeReference) aRef;
358
359   TDF_Label aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG);
360
361   if(!_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID(), aRef)) {
362     aRef = SALOMEDSImpl_AttributeReference::Set(aLabel, aLabel);
363   }
364  
365   if(!aRef->Get().FindAttribute(aBasicGUID, aFatherNode)) {
366     aFatherNode = SALOMEDSImpl_AttributeTreeNode::Set(aRef->Get(), aBasicGUID);
367   }
368
369   if(!_root->FindAttribute(SALOMEDSImpl_AttributeInteger::GetID(), anInteger)) {
370     anInteger = SALOMEDSImpl_AttributeInteger::Set(aLabel, 0);
371   }
372
373   //Create a new use case
374   anInteger->SetValue(anInteger->Value()+1);
375   TDF_Label aChild = aLabel.FindChild(anInteger->Value());
376   aNode = SALOMEDSImpl_AttributeTreeNode::Set(aChild, aBasicGUID);
377   aNode->Remove();
378   aFatherNode->Append(aNode);
379   SALOMEDSImpl_AttributeName::Set(aChild, theName);
380
381   return SALOMEDSImpl_Study::SObject(aChild);
382 }
383
384 //============================================================================
385 /*! Function : GetUseCaseIterator
386  *  Purpose  : Creates a new UseCase iterator, if anObject is null all use cases are iterated 
387  */
388 //============================================================================
389 Handle(SALOMEDSImpl_UseCaseIterator) 
390 SALOMEDSImpl_UseCaseBuilder::GetUseCaseIterator(const Handle(SALOMEDSImpl_SObject)& theObject) 
391 {
392   TDF_Label aLabel;
393
394   if(!theObject.IsNull()) {
395     aLabel = theObject->GetLabel(); //Iterate only sub tree in the use case
396   }
397   else {
398     aLabel = _doc->Main().Root().FindChild(USE_CASE_LABEL_TAG); //Iterate all use cases
399   }
400
401   return new SALOMEDSImpl_UseCaseIterator(aLabel, USE_CASE_GUID, false); 
402 }
403
404
405 Handle(SALOMEDSImpl_SObject) SALOMEDSImpl_UseCaseBuilder::GetSObject(const TCollection_AsciiString& theEntry)
406 {
407    TDF_Label aLabel;    
408    TDF_Tool::Label(_doc->GetData(), theEntry, aLabel);
409    return SALOMEDSImpl_Study::SObject(aLabel);    
410 }