1 // SALOME SALOMEDS : data structure of SALOME and sources of Salome data server
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SALOMEDS_Study_i.cxx
25 // Author : Yves FRICAUD
29 #include <TDataStd_ChildNodeIterator.hxx>
30 #include <TDocStd_Application.hxx>
31 #include <TDocStd_Owner.hxx>
32 #include <CDM_Document.hxx>
33 #include <CDM_Application.hxx>
34 #include <TDF_ChildIDIterator.hxx>
36 #include <TColStd_SequenceOfExtendedString.hxx>
37 #include <TCollection_ExtendedString.hxx>
38 #include <TCollection_AsciiString.hxx>
40 #include <TColStd_ListIteratorOfListOfInteger.hxx>
41 #include <TColStd_ListOfInteger.hxx>
43 #include "SALOMEDS_Study_i.hxx"
45 #include "SALOMEDS_StudyManager_i.hxx"
46 #include "SALOMEDS_Callback_i.hxx"
48 #include "SALOMEDS_SComponent_i.hxx"
49 #include "SALOMEDS_SObject_i.hxx"
51 #include "SALOMEDS_StudyBuilder_i.hxx"
52 #include "SALOMEDS_ChildIterator_i.hxx"
54 #include "SALOMEDS_UseCaseBuilder_i.hxx"
55 #include "SALOMEDS_SComponentIterator_i.hxx"
57 #include "SALOME_GenericObj_i.hh"
58 #include "SALOMEDS_LocalIDAttribute.hxx"
59 #include "SALOMEDS_PersRefAttribute.hxx"
61 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
62 #include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
64 #include "utilities.h"
66 #define DIRECTORYID 16661
67 #define FILEID "FILE: "
68 #define FILELOCALID 26662
72 bool operator<(const TDF_Label& theLeft, const TDF_Label& theRight)
74 TColStd_ListOfInteger aTagLeftList;
75 TDF_Tool::TagList(theLeft,aTagLeftList);
76 TColStd_ListIteratorOfListOfInteger anLeftIter(aTagLeftList);
78 TColStd_ListOfInteger aTagRightList;
79 TDF_Tool::TagList(theRight,aTagRightList);
80 TColStd_ListIteratorOfListOfInteger anRightIter(aTagRightList);
83 Standard_Boolean aLeftMore = anLeftIter.More();
84 Standard_Boolean aRightMore = anRightIter.More();
86 if(!aLeftMore && !aRightMore)
87 return Standard_False;
93 return Standard_False;
95 Standard_Integer aLeftTag = anLeftIter.Value();
98 Standard_Integer aRightTag = anRightIter.Value();
101 if(aLeftTag == aRightTag)
104 return aLeftTag < aRightTag;
107 return Standard_False;
111 //============================================================================
112 /*! Function : SALOMEDS_Study_i
113 * Purpose : SALOMEDS_Study_i constructor
115 //============================================================================
116 SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDS_StudyManager_i* theStudyManager,
117 const Handle(TDocStd_Document)& theDoc,
118 const char* theStudyName):
119 _StudyManager(theStudyManager),
127 _UseCaseBuilder = new SALOMEDS_UseCaseBuilder_i(this,_doc);
128 SALOMEDS::UseCaseBuilder_var aUseCaseBuilder = _UseCaseBuilder->_this();
130 _Builder = new SALOMEDS_StudyBuilder_i(this,_doc);
131 SALOMEDS::StudyBuilder_var aStudyBuilder = _Builder->_this();
133 SALOMEDS_Callback_i* aCallBackServant = new SALOMEDS_Callback_i(aUseCaseBuilder);
134 _callbackOnAdd = aCallBackServant->_this();
135 _callbackOnRemove = _callbackOnAdd;
137 _name = new char[strlen(theStudyName) +1];
138 strcpy(_name,theStudyName);
139 myNbPostponed.Append(0);
142 //============================================================================
143 /*! Function : ~SALOMEDS_Study_i
144 * Purpose : SALOMEDS_Study_i destructor
146 //============================================================================
147 SALOMEDS_Study_i::~SALOMEDS_Study_i()
153 //============================================================================
154 CORBA::ORB_var SALOMEDS_Study_i::GetORB() const
156 return _StudyManager->GetORB();
159 //============================================================================
160 PortableServer::POA_var SALOMEDS_Study_i::GetPOA() const
162 return _StudyManager->GetPOA();
167 SALOMEDS_Study_i::DownCast(SALOMEDS::SObject_ptr theSObject) const
169 if(!CORBA::is_nil(theSObject)){
170 PortableServer::POA_var aPOA = GetPOA();
171 PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theSObject,aPOA);
173 return dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
178 //============================================================================
179 /*! Function : SetOnAddSObject
182 //============================================================================
183 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
185 SALOMEDS::Callback_var aRet = _callbackOnAdd;
186 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
190 //============================================================================
191 /*! Function : SetOnNewSObject
194 //============================================================================
195 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
197 SALOMEDS::Callback_var aRet = _callbackOnRemove;
198 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
202 //============================================================================
203 void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
205 if(!CORBA::is_nil(_callbackOnAdd.in()))
206 _callbackOnAdd->OnAddSObject(theObject);
209 //============================================================================
210 void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
212 if(!CORBA::is_nil(_callbackOnRemove.in()))
213 _callbackOnRemove->OnRemoveSObject(theObject);
216 //============================================================================
217 void SALOMEDS_Study_i::CheckLocked()
219 if(_doc->HasOpenCommand())
222 Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
223 if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
224 if(anAttr->IsLocked())
225 throw SALOMEDS::StudyBuilder::LockProtection();
229 //============================================================================
230 char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
232 return GetORB()->object_to_string(theObject);
236 //============================================================================
237 CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR)
239 return GetORB()->string_to_object(theIOR);
243 //============================================================================
244 /*! Function : GetPersistentReference
245 * Purpose : Get persistent reference of study (idem URL())
247 //============================================================================
248 char* SALOMEDS_Study_i::GetPersistentReference()
252 //============================================================================
253 /*! Function : GetTransientReference
254 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
256 //============================================================================
257 char* SALOMEDS_Study_i::GetTransientReference()
259 CORBA::String_var IOR;
261 Handle(SALOMEDS_IORAttribute) Att;
262 TDF_Label _lab = _doc->GetData()->Root();
263 if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
265 TCollection_AsciiString ch(Att->Get());
266 IOR = CORBA::string_dup(ch.ToCString());
268 else IOR = CORBA::string_dup(""); // NULL ?
270 return CORBA::string_dup(IOR);
273 //============================================================================
274 /*! Function : IsEmpty
275 * Purpose : Detect if study is empty
277 //============================================================================
278 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
280 if (_doc.IsNull()) return true;
281 return _doc->IsEmpty();
284 //============================================================================
285 /*! Function : FindComponent
286 * Purpose : Find a Component with ComponentDataType = aComponentName
288 //============================================================================
289 SALOMEDS::SComponent_ptr
290 SALOMEDS_Study_i::FindComponent(const char* theComponentName)
292 bool anIsFound = false;
293 SALOMEDS::SComponent_var aSComponent;
294 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
295 for(; aComponentIter.More() && !anIsFound; aComponentIter.Next()){
296 SALOMEDS::SComponent_var aSComp = aComponentIter.Value();
297 CORBA::String_var aName = aSComp->ComponentDataType();
298 if(strcmp(theComponentName,aName.in()) == 0){
299 aSComponent = aSComp;
303 return aSComponent._retn();
306 //============================================================================
307 /*! Function : FindComponentID
308 * Purpose : Find a Component from it's ID
310 //============================================================================
311 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
313 // Iterate on each components defined in the study
314 // Get the component ID and compare with aComponentID
317 SALOMEDS::SComponent_ptr compo;
319 SALOMEDS_SComponentIterator_i itcomp(this,_doc);
320 for (; itcomp.More(); itcomp.Next()) {
321 SALOMEDS::SComponent_var SC = itcomp.Value();
323 if(strcmp(aComponentID,ID)==0)
327 compo = SALOMEDS::SComponent::_narrow(SC);
332 compo = SALOMEDS::SComponent::_nil();
337 //============================================================================
338 /*! Function : FindObject
339 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
341 //============================================================================
342 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* theObjectName)
344 // Iterate to all components defined in the study
345 // After testing the component name, iterate in all objects defined under
346 // components (function _FindObject)
347 bool aIsFound = false;
348 SALOMEDS::SObject_var aRefSO;
349 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
350 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
351 TDF_Label aLab = aComponentIter.GetValue();
352 Handle(TDataStd_Name) anAttr;
353 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
354 TCollection_AsciiString aString(anAttr->Get());
355 if(strcmp(aString.ToCString(),theObjectName) == 0){
356 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab)._retn();
361 aRefSO = _FindObject(aLab,theObjectName,aIsFound);
364 return aRefSO._retn();
367 //============================================================================
368 /*! Function : FindObjectID
369 * Purpose : Find an Object with ID = anObjectID
371 //============================================================================
372 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
374 // Convert aSO->GetID in TDF_Label.
376 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
379 return SALOMEDS::SObject::_nil();
381 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
385 //============================================================================
386 /*! Function : CreateObjectID
387 * Purpose : Creates an Object with ID = anObjectID
389 //============================================================================
390 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
392 // Convert aSO->GetID in TDF_Label.
394 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
397 return SALOMEDS::SObject::_nil();
399 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
402 //============================================================================
403 /*! Function : FindObjectByName
404 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
405 * : with ComponentDataType = aComponentName
407 //============================================================================
408 SALOMEDS::Study::ListOfSObject*
409 SALOMEDS_Study_i::FindObjectByName(const char* theObjectName,
410 const char* theComponentName)
412 SALOMEDS::Study::ListOfSObject_var aListOfSObj = new SALOMEDS::Study::ListOfSObject ;
413 aListOfSObj->length(0);
415 SALOMEDS::SComponent_ptr aSComponent = FindComponent(theComponentName) ;
416 if(aSComponent->_is_nil()){
417 MESSAGE ("In FindObjectByName() : Component named " << theComponentName << " not found ");
418 return aListOfSObj._retn();
421 // Iterate on each object and subobject of the component
422 // If objectName is found add it to the list of SObjects
424 CORBA::String_var anEntry = aSComponent->GetID();
425 TDF_Tool::Label(_doc->GetData(),const_cast<char*>(anEntry.in()),aLabel);
428 SALOMEDS::SObject_var aRefSO;
429 TDF_ChildIterator aChildIter(aLabel,true);
430 for(; aChildIter.More(); aChildIter.Next()){
431 TDF_Label aLab = aChildIter.Value();
432 Handle(TDataStd_Name) anAttr;
433 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
434 TCollection_AsciiString aString(anAttr->Get());
435 if(strcmp(aString.ToCString(),theObjectName) == 0){
436 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab)._retn();
439 aListOfSObj->length(aLength);
440 aListOfSObj[aLength-1] = aRefSO;
445 return aListOfSObj._retn() ;
450 //============================================================================
451 /*! Function : FindObjectIOR
452 * Purpose : Find an Object with IOR = anObjectIOR
454 //============================================================================
455 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
457 // firstly searching in the datamap for optimization
458 char* anIOR = const_cast<char*>(theObjectIOR);
459 if(myIORLabels.IsBound(anIOR)){
460 TDF_Label aLabel = myIORLabels.Find(anIOR);
461 TSObjectHolder aSObjectHolder = SALOMEDS_SObject_i::New(this,aLabel);
462 SALOMEDS_SObject_i* aSObjectPtr = aSObjectHolder.first;
463 SALOMEDS::SObject_var aSObject = aSObjectHolder.second;
464 // 11 oct 2002: forbidden attributes must be checked here
465 SALOMEDS::GenericAttribute_var anAttr;
466 if(!aSObjectPtr->FindAttribute(anAttr,"AttributeIOR")){
467 myIORLabels.UnBind(anIOR);
469 return aSObject._retn();
473 // Iterate to all components defined in the study
474 // After testing the component name, iterate in all objects defined under
475 // components (function _FindObject)
476 bool aIsFound = false;
477 SALOMEDS::SObject_var aRefSO;
478 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
479 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
480 TDF_Label aLab = aComponentIter.GetValue();
481 Handle(SALOMEDS_IORAttribute) anAttr;
482 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
483 TCollection_AsciiString aString(anAttr->Get());
484 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
485 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab);
490 aRefSO = _FindObjectIOR(aLab,theObjectIOR,aIsFound);
493 if(!aRefSO->_is_nil())
494 MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
496 return aRefSO._retn();
499 //============================================================================
500 /*! Function : FindObjectByPath
501 * Purpose : Find an Object by its path = thePath
503 //============================================================================
504 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
506 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
507 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
508 int i = 1, aLength = aPath.Length();
509 bool isRelative = false;
511 if(aLength == 0) { //Empty path - return the current context
512 return SALOMEDS_SObject_i::NewRef(this,_current)._retn();
515 if(aPath.Value(1) != '/') //Relative path
518 TDF_ChildIterator anIterator;
520 Handle(TDataStd_Name) anAttr;
523 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
524 anIterator.Initialize(_current, Standard_False);
527 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
528 return SALOMEDS_SObject_i::NewRef(this,_doc->Main())._retn();
530 anIterator.Initialize(_doc->Main(), Standard_False);
533 while(i <= aLength) {
535 aToken = aPath.Token("/", i);
536 if(aToken.Length() == 0) break;
538 for ( ; anIterator.More(); anIterator.Next() ) {
539 aLabel = anIterator.Value();
540 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
541 if(anAttr->Get() == aToken) {
542 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
543 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
544 return SALOMEDS_SObject_i::NewRef(this,aLabel)._retn();
547 anIterator.Initialize(aLabel, Standard_False);
559 //============================================================================
560 /*! Function : GetObjectPath
563 //============================================================================
564 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
566 TCollection_AsciiString aPath("");
567 if(CORBA::is_nil(theObject))
568 return CORBA::string_dup(aPath.ToCString());
570 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
571 if(anObject->_is_nil()) {
572 CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
573 anObject = FindObjectIOR(anIOR);
574 if(anObject->_is_nil())
575 return CORBA::string_dup(aPath.ToCString());
578 SALOMEDS::GenericAttribute_var anAttr;
579 if(anObject->FindAttribute(anAttr, "AttributeName")) {
580 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
581 if(anAttr->_is_nil())
582 return CORBA::string_dup(aPath.ToCString());
583 TCollection_AsciiString aValue(aName->Value());
587 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
588 if(!aFather->_is_nil()) {
590 Handle(TDataStd_Name) aNameAttrib;
591 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
592 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
593 aValue = GetObjectPath(aFather);
594 aPath = aValue + aPath;
599 return CORBA::string_dup(aPath.ToCString());
603 //============================================================================
604 /*! Function : SetContext
605 * Purpose : Sets the current context
607 //============================================================================
608 void SALOMEDS_Study_i::SetContext(const char* thePath)
610 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
611 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
612 bool isInvalid = false;
613 SALOMEDS::SObject_var aSO;
615 if(aPath.Value(1) != '/') { //Relative path
616 aContext = TCollection_AsciiString(GetContext());
624 aSO = FindObjectByPath(aContext.ToCString());
630 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
633 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
634 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
636 _current = aLabel; //Set the current context
640 //============================================================================
641 /*! Function : GetContext
642 * Purpose : Gets the current context
644 //============================================================================
645 char* SALOMEDS_Study_i::GetContext()
647 if(_current.IsNull())
648 throw SALOMEDS::Study::StudyInvalidContext();
650 SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(this,_current);
651 return GetObjectPath(aSObject);
654 //============================================================================
655 /*! Function : GetObjectNames
656 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
658 //============================================================================
659 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
660 TColStd_SequenceOfExtendedString aResultSeq;
661 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
663 if (strlen(theContext) == 0) {
664 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
667 TDF_Label aTmp = _current;
668 SetContext(theContext);
672 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
673 for(; anIter.More(); anIter.Next()) {
674 TDF_Label aLabel = anIter.Value();
675 // Handle(TDF_Attribute) anAttribute;
676 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
677 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
678 Handle(TDataStd_Name) aName;
679 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
682 // fill the result table
683 int anIndex, aLength = aResultSeq.Length();
684 aResult->length(aLength);
685 for(anIndex = 0; anIndex < aLength; anIndex++) {
686 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
688 return aResult._retn();
691 //============================================================================
692 /*! Function : GetDirectoryNames
693 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
695 //============================================================================
696 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
697 TColStd_SequenceOfExtendedString aResultSeq;
698 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
700 if (strlen(theContext) == 0) {
701 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
704 TDF_Label aTmp = _current;
705 SetContext(theContext);
709 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
710 for(; anIter.More(); anIter.Next()) {
711 TDF_Label aLabel = anIter.Value();
712 Handle(SALOMEDS_LocalIDAttribute) anID;
713 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
714 if (anID->Get() == DIRECTORYID) {
715 Handle(TDataStd_Name) aName;
716 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
717 aResultSeq.Append(aName->Get());
722 // fill the result table
723 int anIndex, aLength = aResultSeq.Length();
724 aResult->length(aLength);
725 for(anIndex = 0; anIndex < aLength; anIndex++) {
726 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
728 return aResult._retn();
731 //============================================================================
732 /*! Function : GetFileNames
733 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
735 //============================================================================
736 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
737 TColStd_SequenceOfExtendedString aResultSeq;
738 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
740 if (strlen(theContext) == 0) {
741 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
744 TDF_Label aTmp = _current;
745 SetContext(theContext);
749 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
750 for(; anIter.More(); anIter.Next()) {
751 TDF_Label aLabel = anIter.Value();
752 Handle(SALOMEDS_LocalIDAttribute) anID;
753 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
754 if (anID->Get() == FILELOCALID) {
755 Handle(SALOMEDS_PersRefAttribute) aName;
756 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
757 TCollection_ExtendedString aFileName = aName->Get();
758 if(aFileName.Length() > 0)
759 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
765 // fill the result table
766 int anIndex, aLength = aResultSeq.Length();
767 aResult->length(aLength);
768 for(anIndex = 0; anIndex < aLength; anIndex++) {
769 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
771 return aResult._retn();
774 //============================================================================
775 /*! Function : GetComponentNames
776 * Purpose : method to get all components names
778 //============================================================================
779 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
780 TColStd_SequenceOfExtendedString aResultSeq;
781 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
782 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
783 for(; anIter.More(); anIter.Next()) {
784 TDF_Label aLabel = anIter.Value();
785 Handle(TDataStd_Name) aName;
786 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
788 // fill the result table
789 int anIndex, aLength = aResultSeq.Length();
790 aResult->length(aLength);
791 for(anIndex = 0; anIndex < aLength; anIndex++) {
792 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
794 return aResult._retn();
797 //============================================================================
798 /*! Function : NewChildIterator
799 * Purpose : Create a ChildIterator from an SObject
801 //============================================================================
802 SALOMEDS::ChildIterator_ptr
803 SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr theSObject)
805 SALOMEDS_ChildIterator_i* aServant =
806 new SALOMEDS_ChildIterator_i(GetChildIterator(theSObject));
808 return aServant->_this();
811 SALOMEDS_ChildIterator_i
812 SALOMEDS_Study_i::GetChildIterator(SALOMEDS::SObject_ptr theSObject)
815 TDF_Tool::Label(_doc->GetData(),theSObject->GetID(),aLab);
816 return SALOMEDS_ChildIterator_i(this,aLab);
819 //============================================================================
820 /*! Function : NewComponentIterator
821 * Purpose : Create a SComponentIterator
823 //============================================================================
824 SALOMEDS::SComponentIterator_ptr
825 SALOMEDS_Study_i::NewComponentIterator()
827 SALOMEDS_SComponentIterator_i* aServant =
828 new SALOMEDS_SComponentIterator_i(GetComponentIterator());
830 return aServant->_this();
833 SALOMEDS_SComponentIterator_i
834 SALOMEDS_Study_i::GetComponentIterator()
836 return SALOMEDS_SComponentIterator_i(this,_doc);
839 //============================================================================
840 /*! Function : GetUseCaseBuilder
841 * Purpose : Returns a UseCase builder
843 //============================================================================
844 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
846 return _UseCaseBuilder->_this();
849 //============================================================================
850 /*! Function : NewBuilder
851 * Purpose : Create a StudyBuilder
853 //============================================================================
854 SALOMEDS_StudyBuilder_i* SALOMEDS_Study_i::GetBuilder()
859 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
861 return GetBuilder()->_this();
864 //============================================================================
866 * Purpose : get study name
868 //============================================================================
869 char* SALOMEDS_Study_i::Name()
871 return CORBA::string_dup(_name);
874 //============================================================================
876 * Purpose : set study name
878 //============================================================================
879 void SALOMEDS_Study_i::Name(const char* name)
881 _name = new char[strlen(name) +1];
885 //============================================================================
886 /*! Function : IsSaved
887 * Purpose : get if study has been saved
889 //============================================================================
890 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
895 //============================================================================
896 /*! Function : IsSaved
897 * Purpose : set if study has been saved
899 //============================================================================
900 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
905 //============================================================================
906 /*! Function : IsModified
907 * Purpose : Detect if a Study has been modified since it has been saved
909 //============================================================================
910 CORBA::Boolean SALOMEDS_Study_i::IsModified()
912 // True if is modified and not saved
913 if (_doc->IsModified())
914 if (!_isSaved) return true;
919 //============================================================================
921 * Purpose : get URL of the study (persistent reference of the study)
923 //============================================================================
924 char* SALOMEDS_Study_i::URL()
930 return CORBA::string_dup(_URL);
933 //============================================================================
935 * Purpose : set URL of the study (persistent reference of the study)
937 //============================================================================
938 void SALOMEDS_Study_i::URL(const char* url)
940 if (_URL) delete [] _URL;
941 _URL = new char[strlen(url) +1];
946 char *adr = strtok(aName, "/");
950 adr = strtok(NULL, "/");
957 //============================================================================
958 /*! Function : _FindObject
959 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
961 //============================================================================
962 SALOMEDS::SObject_ptr
963 SALOMEDS_Study_i::_FindObject(TDF_Label theLabel,
964 const char* theObjectName,
968 // Iterate on each objects and subobjects of the component
969 // If objectName find, stop the loop and get the object reference
970 SALOMEDS::SObject_var aRefSO;
971 TDF_ChildIterator aChildIter(theLabel,true);
972 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
973 TDF_Label aLab = aChildIter.Value();
974 Handle(TDataStd_Name) anAttr;
975 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
976 TCollection_AsciiString aString(anAttr->Get());
977 if(strcmp(aString.ToCString(),theObjectName) == 0){
978 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
983 return aRefSO._retn();
986 //============================================================================
987 /*! Function : _FindObject
988 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
990 //============================================================================
991 SALOMEDS::SObject_ptr
992 SALOMEDS_Study_i::_FindObjectIOR(TDF_Label theLabel,
993 const char* theObjectIOR,
996 // Iterate on each objects and subobjects of the component
997 // If objectName find, stop the loop and get the object reference
998 SALOMEDS::SObject_var aRefSO;
999 TDF_ChildIterator aChildIter(theLabel,true);
1000 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
1001 TDF_Label aLab = aChildIter.Value();
1002 Handle(SALOMEDS_IORAttribute) anAttr;
1003 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
1004 TCollection_AsciiString aString(anAttr->Get());
1005 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
1006 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
1011 return aRefSO._retn();
1014 CORBA::Short SALOMEDS_Study_i::StudyId()
1019 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
1024 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
1026 CORBA::String_var anEn = CORBA::string_dup(anEntry);
1027 CORBA::String_var IOR = CORBA::string_dup(anIOR);
1028 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
1029 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
1030 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
1033 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute) {
1034 TCollection_AsciiString aString;
1035 TDF_Tool::Entry(theAttribute->Label(),aString);
1036 TCollection_AsciiString aValue(theAttribute->Get());
1037 UpdateIORLabelMap(aValue.ToCString(),aString.ToCString());
1040 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
1041 SALOMEDS::GenericAttribute_ptr aTarget;
1042 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
1043 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
1045 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
1051 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties(){
1052 SALOMEDS::SObject_var aSObject = FindObjectID("0:1");
1054 SALOMEDS::GenericAttribute_var anAttr =
1055 GetBuilder()->FindOrCreateAttribute(aSObject,"AttributeStudyProperties");
1057 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
1060 char* SALOMEDS_Study_i::GetLastModificationDate() {
1061 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1062 SALOMEDS::StringSeq_var aNames;
1063 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1064 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1065 int aLastIndex = aNames->length() - 1;
1067 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
1068 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
1069 CORBA::String_var aResStr = CORBA::string_dup(aResult);
1070 return aResStr._retn();
1073 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
1074 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1075 SALOMEDS::StringSeq_var aNames;
1076 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1077 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
1079 int anIndex, aLength = aNames->length();
1080 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
1081 aDates->length(aLength);
1083 for(anIndex = 0; anIndex < aLength; anIndex++) {
1085 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
1086 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
1087 aDates[anIndex] = CORBA::string_dup(aDate);
1089 return aDates._retn();
1094 //============================================================================
1095 /*! Function : Close
1098 //============================================================================
1099 void SALOMEDS_Study_i::Close()
1101 SALOMEDS_SComponentIterator_i itcomponent(this,_doc);
1103 const CORBA::ORB_var& anORB = GetORB();
1104 for (; itcomponent.More(); itcomponent.Next()) {
1105 SALOMEDS::SComponent_var sco = itcomponent.Value();
1107 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
1108 // if there is an associated Engine call its method for closing
1109 CORBA::String_var IOREngine;
1110 if (sco->ComponentIOR(IOREngine)) {
1111 // we have found the associated engine to write the data
1112 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
1113 CORBA::Object_var obj = anORB->string_to_object(IOREngine);
1114 if (!CORBA::is_nil(obj)) {
1115 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
1117 if (!anEngine->_is_nil())
1118 anEngine->Close(sco);
1123 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1124 // Handle(TDocStd_Owner) anOwner;
1125 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1126 // Handle(TDocStd_Document) anEmptyDoc;
1127 // anOwner->SetDocument(anEmptyDoc);
1129 if(!anApp.IsNull()) anApp->Close(_doc);
1133 //============================================================================
1134 /*! Function : AddPostponed
1137 //============================================================================
1138 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1139 if (!GetBuilder()->HasOpenCommand()) return;
1141 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1142 if (!CORBA::is_nil(obj)) {
1143 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1144 if (!CORBA::is_nil(aGeneric)) {
1145 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1147 myPostponedIORs.Append(anIOR); // add prefix: deleted
1148 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1154 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1155 if (!GetBuilder()->HasOpenCommand()) return;
1157 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1158 if (!CORBA::is_nil(obj)) {
1159 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1160 if (!CORBA::is_nil(aGeneric)) {
1161 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1163 myPostponedIORs.Append(anIOR); // add prefix: created
1164 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1170 //============================================================================
1171 /*! Function : RemovePostponed
1174 //============================================================================
1175 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1179 int aUndoLimit = theUndoLimit;
1180 if (theUndoLimit < 0) aUndoLimit = 0;
1182 const CORBA::ORB_var& anORB = GetORB();
1183 if (myNbUndos > 0) { // remove undone
1185 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1186 anOld += myNbPostponed(anIndex);
1187 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1189 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1190 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1191 if (anIOR.Value(1) == 'c') {
1192 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1193 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1194 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1197 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1198 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1203 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1205 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1206 anOld += myNbPostponed(anIndex);
1207 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1208 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1209 if (anIOR.Value(1) == 'd') {
1210 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1211 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1212 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1215 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1216 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1219 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1220 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1221 for(; anIter.More(); anIter.Next()) {
1222 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1223 CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
1225 CORBA::Object_var obj = anORB->string_to_object(anIOR);
1226 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1227 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1230 } else myNbPostponed.Append(0);
1233 //============================================================================
1234 /*! Function : UndoPostponed
1237 //============================================================================
1238 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1239 myNbUndos += theWay;
1240 // remove current postponed
1241 if (myNbPostponed.Last() > 0)
1242 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1243 myNbPostponed(myNbPostponed.Length()) = 0;