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.hxx"
44 #include "SALOMEDS_Study_i.hxx"
46 #include "SALOMEDS_StudyManager_i.hxx"
47 #include "SALOMEDS_Callback_i.hxx"
49 #include "SALOMEDS_SComponent_i.hxx"
50 #include "SALOMEDS_SObject_i.hxx"
52 #include "SALOMEDS_StudyBuilder_i.hxx"
53 #include "SALOMEDS_ChildIterator_i.hxx"
55 #include "SALOMEDS_UseCaseBuilder_i.hxx"
56 #include "SALOMEDS_SComponentIterator_i.hxx"
58 #include "SALOME_GenericObj_i.hh"
59 #include "SALOMEDS_LocalIDAttribute.hxx"
60 #include "SALOMEDS_PersRefAttribute.hxx"
62 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
63 #include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
65 #include "utilities.h"
67 #define DIRECTORYID 16661
68 #define FILEID "FILE: "
69 #define FILELOCALID 26662
73 bool operator<(const TDF_Label& theLeft, const TDF_Label& theRight)
75 TColStd_ListOfInteger aTagLeftList;
76 TDF_Tool::TagList(theLeft,aTagLeftList);
77 TColStd_ListIteratorOfListOfInteger anLeftIter(aTagLeftList);
79 TColStd_ListOfInteger aTagRightList;
80 TDF_Tool::TagList(theRight,aTagRightList);
81 TColStd_ListIteratorOfListOfInteger anRightIter(aTagRightList);
84 Standard_Boolean aLeftMore = anLeftIter.More();
85 Standard_Boolean aRightMore = anRightIter.More();
87 if(!aLeftMore && !aRightMore)
88 return Standard_False;
94 return Standard_False;
96 Standard_Integer aLeftTag = anLeftIter.Value();
99 Standard_Integer aRightTag = anRightIter.Value();
102 if(aLeftTag == aRightTag)
105 return aLeftTag < aRightTag;
108 return Standard_False;
112 //============================================================================
113 /*! Function : SALOMEDS_Study_i
114 * Purpose : SALOMEDS_Study_i constructor
116 //============================================================================
117 SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDS_StudyManager_i* theStudyManager,
118 const Handle(TDocStd_Document)& theDoc,
119 const char* theStudyName):
120 _StudyManager(theStudyManager),
128 _UseCaseBuilder = new SALOMEDS_UseCaseBuilder_i(this,_doc);
129 SALOMEDS::UseCaseBuilder_var aUseCaseBuilder = _UseCaseBuilder->_this();
131 _Builder = new SALOMEDS_StudyBuilder_i(this,_doc);
132 SALOMEDS::StudyBuilder_var aStudyBuilder = _Builder->_this();
134 SALOMEDS_Callback_i* aCallBackServant = new SALOMEDS_Callback_i(aUseCaseBuilder);
135 _callbackOnAdd = aCallBackServant->_this();
136 _callbackOnRemove = _callbackOnAdd;
138 _name = new char[strlen(theStudyName) +1];
139 strcpy(_name,theStudyName);
140 myNbPostponed.Append(0);
143 //============================================================================
144 /*! Function : ~SALOMEDS_Study_i
145 * Purpose : SALOMEDS_Study_i destructor
147 //============================================================================
148 SALOMEDS_Study_i::~SALOMEDS_Study_i()
154 //============================================================================
155 CORBA::ORB_var SALOMEDS_Study_i::GetORB() const
157 return _StudyManager->GetORB();
160 //============================================================================
161 PortableServer::POA_var SALOMEDS_Study_i::GetPOA() const
163 return _StudyManager->GetPOA();
168 SALOMEDS_Study_i::DownCast(SALOMEDS::SObject_ptr theSObject) const
170 if(!CORBA::is_nil(theSObject)){
171 PortableServer::POA_var aPOA = GetPOA();
172 PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theSObject,aPOA);
174 return dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
179 //============================================================================
180 /*! Function : SetOnAddSObject
183 //============================================================================
184 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
186 SALOMEDS::Callback_var aRet = _callbackOnAdd;
187 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
191 //============================================================================
192 /*! Function : SetOnNewSObject
195 //============================================================================
196 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
198 SALOMEDS::Callback_var aRet = _callbackOnRemove;
199 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
203 //============================================================================
204 void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
206 if(!CORBA::is_nil(_callbackOnAdd.in()))
207 _callbackOnAdd->OnAddSObject(theObject);
210 //============================================================================
211 void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
213 if(!CORBA::is_nil(_callbackOnRemove.in()))
214 _callbackOnRemove->OnRemoveSObject(theObject);
217 //============================================================================
218 void SALOMEDS_Study_i::CheckLocked()
220 SALOMEDS::Locker lock;
222 if(_doc->HasOpenCommand())
225 Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
226 if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
227 if(anAttr->IsLocked())
228 throw SALOMEDS::StudyBuilder::LockProtection();
232 //============================================================================
233 char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
235 return GetORB()->object_to_string(theObject);
239 //============================================================================
240 CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR)
242 return GetORB()->string_to_object(theIOR);
246 //============================================================================
247 /*! Function : GetPersistentReference
248 * Purpose : Get persistent reference of study (idem URL())
250 //============================================================================
251 char* SALOMEDS_Study_i::GetPersistentReference()
253 SALOMEDS::Locker lock;
257 //============================================================================
258 /*! Function : GetTransientReference
259 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
261 //============================================================================
262 char* SALOMEDS_Study_i::GetTransientReference()
264 SALOMEDS::Locker lock;
266 CORBA::String_var IOR;
268 Handle(SALOMEDS_IORAttribute) Att;
269 TDF_Label _lab = _doc->GetData()->Root();
270 if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
272 TCollection_AsciiString ch(Att->Get());
273 IOR = CORBA::string_dup(ch.ToCString());
275 else IOR = CORBA::string_dup(""); // NULL ?
277 return CORBA::string_dup(IOR);
280 //============================================================================
281 /*! Function : IsEmpty
282 * Purpose : Detect if study is empty
284 //============================================================================
285 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
287 SALOMEDS::Locker lock;
289 if (_doc.IsNull()) return true;
290 return _doc->IsEmpty();
293 //============================================================================
294 /*! Function : FindComponent
295 * Purpose : Find a Component with ComponentDataType = aComponentName
297 //============================================================================
298 SALOMEDS::SComponent_ptr
299 SALOMEDS_Study_i::FindComponent(const char* theComponentName)
301 SALOMEDS::Locker lock;
303 bool anIsFound = false;
304 SALOMEDS::SComponent_var aSComponent;
305 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
306 for(; aComponentIter.More() && !anIsFound; aComponentIter.Next()){
307 SALOMEDS::SComponent_var aSComp = aComponentIter.Value();
308 CORBA::String_var aName = aSComp->ComponentDataType();
309 if(strcmp(theComponentName,aName.in()) == 0){
310 aSComponent = aSComp;
314 return aSComponent._retn();
317 //============================================================================
318 /*! Function : FindComponentID
319 * Purpose : Find a Component from it's ID
321 //============================================================================
322 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
324 SALOMEDS::Locker lock;
326 // Iterate on each components defined in the study
327 // Get the component ID and compare with aComponentID
330 SALOMEDS::SComponent_ptr compo;
332 SALOMEDS_SComponentIterator_i itcomp(this,_doc);
333 for (; itcomp.More(); itcomp.Next()) {
334 SALOMEDS::SComponent_var SC = itcomp.Value();
336 if(strcmp(aComponentID,ID)==0)
340 compo = SALOMEDS::SComponent::_narrow(SC);
345 compo = SALOMEDS::SComponent::_nil();
350 //============================================================================
351 /*! Function : FindObject
352 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
354 //============================================================================
355 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* theObjectName)
357 SALOMEDS::Locker lock;
359 // Iterate to all components defined in the study
360 // After testing the component name, iterate in all objects defined under
361 // components (function _FindObject)
362 bool aIsFound = false;
363 SALOMEDS::SObject_var aRefSO;
364 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
365 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
366 TDF_Label aLab = aComponentIter.GetValue();
367 Handle(TDataStd_Name) anAttr;
368 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
369 TCollection_AsciiString aString(anAttr->Get());
370 if(strcmp(aString.ToCString(),theObjectName) == 0){
371 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab)._retn();
376 aRefSO = _FindObject(aLab,theObjectName,aIsFound);
379 return aRefSO._retn();
382 //============================================================================
383 /*! Function : FindObjectID
384 * Purpose : Find an Object with ID = anObjectID
386 //============================================================================
387 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
389 SALOMEDS::Locker lock;
391 // Convert aSO->GetID in TDF_Label.
393 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
396 return SALOMEDS::SObject::_nil();
398 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
402 //============================================================================
403 /*! Function : CreateObjectID
404 * Purpose : Creates an Object with ID = anObjectID
406 //============================================================================
407 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
409 SALOMEDS::Locker lock;
411 // Convert aSO->GetID in TDF_Label.
413 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
416 return SALOMEDS::SObject::_nil();
418 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
421 //============================================================================
422 /*! Function : FindObjectByName
423 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
424 * : with ComponentDataType = aComponentName
426 //============================================================================
427 SALOMEDS::Study::ListOfSObject*
428 SALOMEDS_Study_i::FindObjectByName(const char* theObjectName,
429 const char* theComponentName)
431 SALOMEDS::Locker lock;
433 SALOMEDS::Study::ListOfSObject_var aListOfSObj = new SALOMEDS::Study::ListOfSObject ;
434 aListOfSObj->length(0);
436 SALOMEDS::SComponent_ptr aSComponent = FindComponent(theComponentName) ;
437 if(aSComponent->_is_nil()){
438 MESSAGE ("In FindObjectByName() : Component named " << theComponentName << " not found ");
439 return aListOfSObj._retn();
442 // Iterate on each object and subobject of the component
443 // If objectName is found add it to the list of SObjects
445 CORBA::String_var anEntry = aSComponent->GetID();
446 TDF_Tool::Label(_doc->GetData(),const_cast<char*>(anEntry.in()),aLabel);
449 SALOMEDS::SObject_var aRefSO;
450 TDF_ChildIterator aChildIter(aLabel,true);
451 for(; aChildIter.More(); aChildIter.Next()){
452 TDF_Label aLab = aChildIter.Value();
453 Handle(TDataStd_Name) anAttr;
454 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
455 TCollection_AsciiString aString(anAttr->Get());
456 if(strcmp(aString.ToCString(),theObjectName) == 0){
457 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab)._retn();
460 aListOfSObj->length(aLength);
461 aListOfSObj[aLength-1] = aRefSO;
466 return aListOfSObj._retn() ;
471 //============================================================================
472 /*! Function : FindObjectIOR
473 * Purpose : Find an Object with IOR = anObjectIOR
475 //============================================================================
476 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
478 SALOMEDS::Locker lock;
480 // firstly searching in the datamap for optimization
481 char* anIOR = const_cast<char*>(theObjectIOR);
482 if(myIORLabels.IsBound(anIOR)){
483 TDF_Label aLabel = myIORLabels.Find(anIOR);
484 TSObjectHolder aSObjectHolder = SALOMEDS_SObject_i::New(this,aLabel);
485 SALOMEDS_SObject_i* aSObjectPtr = aSObjectHolder.first;
486 SALOMEDS::SObject_var aSObject = aSObjectHolder.second;
487 // 11 oct 2002: forbidden attributes must be checked here
488 SALOMEDS::GenericAttribute_var anAttr;
489 if(!aSObjectPtr->FindAttribute(anAttr,"AttributeIOR")){
490 myIORLabels.UnBind(anIOR);
492 return aSObject._retn();
496 // Iterate to all components defined in the study
497 // After testing the component name, iterate in all objects defined under
498 // components (function _FindObject)
499 bool aIsFound = false;
500 SALOMEDS::SObject_var aRefSO;
501 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
502 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
503 TDF_Label aLab = aComponentIter.GetValue();
504 Handle(SALOMEDS_IORAttribute) anAttr;
505 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
506 TCollection_AsciiString aString(anAttr->Get());
507 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
508 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab);
513 aRefSO = _FindObjectIOR(aLab,theObjectIOR,aIsFound);
516 if(!aRefSO->_is_nil())
517 MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
519 return aRefSO._retn();
522 //============================================================================
523 /*! Function : FindObjectByPath
524 * Purpose : Find an Object by its path = thePath
526 //============================================================================
527 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
529 SALOMEDS::Locker lock;
531 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
532 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
533 int i = 1, aLength = aPath.Length();
534 bool isRelative = false;
536 if(aLength == 0) { //Empty path - return the current context
537 return SALOMEDS_SObject_i::NewRef(this,_current)._retn();
540 if(aPath.Value(1) != '/') //Relative path
543 TDF_ChildIterator anIterator;
545 Handle(TDataStd_Name) anAttr;
548 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
549 anIterator.Initialize(_current, Standard_False);
552 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
553 return SALOMEDS_SObject_i::NewRef(this,_doc->Main())._retn();
555 anIterator.Initialize(_doc->Main(), Standard_False);
558 while(i <= aLength) {
560 aToken = aPath.Token("/", i);
561 if(aToken.Length() == 0) break;
563 for ( ; anIterator.More(); anIterator.Next() ) {
564 aLabel = anIterator.Value();
565 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
566 if(anAttr->Get() == aToken) {
567 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
568 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
569 return SALOMEDS_SObject_i::NewRef(this,aLabel)._retn();
572 anIterator.Initialize(aLabel, Standard_False);
584 //============================================================================
585 /*! Function : GetObjectPath
588 //============================================================================
589 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
591 SALOMEDS::Locker lock;
593 TCollection_AsciiString aPath("");
594 if(CORBA::is_nil(theObject))
595 return CORBA::string_dup(aPath.ToCString());
597 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
598 if(anObject->_is_nil()) {
599 CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
600 anObject = FindObjectIOR(anIOR);
601 if(anObject->_is_nil())
602 return CORBA::string_dup(aPath.ToCString());
605 SALOMEDS::GenericAttribute_var anAttr;
606 if(anObject->FindAttribute(anAttr, "AttributeName")) {
607 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
608 if(anAttr->_is_nil())
609 return CORBA::string_dup(aPath.ToCString());
610 TCollection_AsciiString aValue(aName->Value());
614 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
615 if(!aFather->_is_nil()) {
617 Handle(TDataStd_Name) aNameAttrib;
618 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
619 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
620 aValue = GetObjectPath(aFather);
621 aPath = aValue + aPath;
626 return CORBA::string_dup(aPath.ToCString());
630 //============================================================================
631 /*! Function : SetContext
632 * Purpose : Sets the current context
634 //============================================================================
635 void SALOMEDS_Study_i::SetContext(const char* thePath)
637 SALOMEDS::Locker lock;
639 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
640 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
641 bool isInvalid = false;
642 SALOMEDS::SObject_var aSO;
644 if(aPath.Value(1) != '/') { //Relative path
645 aContext = TCollection_AsciiString(GetContext());
653 aSO = FindObjectByPath(aContext.ToCString());
659 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
662 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
663 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
665 _current = aLabel; //Set the current context
669 //============================================================================
670 /*! Function : GetContext
671 * Purpose : Gets the current context
673 //============================================================================
674 char* SALOMEDS_Study_i::GetContext()
676 SALOMEDS::Locker lock;
678 if(_current.IsNull())
679 throw SALOMEDS::Study::StudyInvalidContext();
681 SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(this,_current);
682 return GetObjectPath(aSObject);
685 //============================================================================
686 /*! Function : GetObjectNames
687 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
689 //============================================================================
690 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
691 SALOMEDS::Locker lock;
693 TColStd_SequenceOfExtendedString aResultSeq;
694 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
696 if (strlen(theContext) == 0) {
697 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
700 TDF_Label aTmp = _current;
701 SetContext(theContext);
705 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
706 for(; anIter.More(); anIter.Next()) {
707 TDF_Label aLabel = anIter.Value();
708 // Handle(TDF_Attribute) anAttribute;
709 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
710 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
711 Handle(TDataStd_Name) aName;
712 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
715 // fill the result table
716 int anIndex, aLength = aResultSeq.Length();
717 aResult->length(aLength);
718 for(anIndex = 0; anIndex < aLength; anIndex++) {
719 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
721 return aResult._retn();
724 //============================================================================
725 /*! Function : GetDirectoryNames
726 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
728 //============================================================================
729 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
730 SALOMEDS::Locker lock;
732 TColStd_SequenceOfExtendedString aResultSeq;
733 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
735 if (strlen(theContext) == 0) {
736 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
739 TDF_Label aTmp = _current;
740 SetContext(theContext);
744 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
745 for(; anIter.More(); anIter.Next()) {
746 TDF_Label aLabel = anIter.Value();
747 Handle(SALOMEDS_LocalIDAttribute) anID;
748 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
749 if (anID->Get() == DIRECTORYID) {
750 Handle(TDataStd_Name) aName;
751 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
752 aResultSeq.Append(aName->Get());
757 // fill the result table
758 int anIndex, aLength = aResultSeq.Length();
759 aResult->length(aLength);
760 for(anIndex = 0; anIndex < aLength; anIndex++) {
761 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
763 return aResult._retn();
766 //============================================================================
767 /*! Function : GetFileNames
768 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
770 //============================================================================
771 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
772 SALOMEDS::Locker lock;
774 TColStd_SequenceOfExtendedString aResultSeq;
775 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
777 if (strlen(theContext) == 0) {
778 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
781 TDF_Label aTmp = _current;
782 SetContext(theContext);
786 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
787 for(; anIter.More(); anIter.Next()) {
788 TDF_Label aLabel = anIter.Value();
789 Handle(SALOMEDS_LocalIDAttribute) anID;
790 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
791 if (anID->Get() == FILELOCALID) {
792 Handle(SALOMEDS_PersRefAttribute) aName;
793 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
794 TCollection_ExtendedString aFileName = aName->Get();
795 if(aFileName.Length() > 0)
796 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
802 // fill the result table
803 int anIndex, aLength = aResultSeq.Length();
804 aResult->length(aLength);
805 for(anIndex = 0; anIndex < aLength; anIndex++) {
806 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
808 return aResult._retn();
811 //============================================================================
812 /*! Function : GetComponentNames
813 * Purpose : method to get all components names
815 //============================================================================
816 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
817 SALOMEDS::Locker lock;
819 TColStd_SequenceOfExtendedString aResultSeq;
820 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
821 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
822 for(; anIter.More(); anIter.Next()) {
823 TDF_Label aLabel = anIter.Value();
824 Handle(TDataStd_Name) aName;
825 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
827 // fill the result table
828 int anIndex, aLength = aResultSeq.Length();
829 aResult->length(aLength);
830 for(anIndex = 0; anIndex < aLength; anIndex++) {
831 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
833 return aResult._retn();
836 //============================================================================
837 /*! Function : NewChildIterator
838 * Purpose : Create a ChildIterator from an SObject
840 //============================================================================
841 SALOMEDS::ChildIterator_ptr
842 SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr theSObject)
844 SALOMEDS::Locker lock;
846 SALOMEDS_ChildIterator_i* aServant =
847 new SALOMEDS_ChildIterator_i(GetChildIterator(theSObject));
849 return aServant->_this();
852 SALOMEDS_ChildIterator_i
853 SALOMEDS_Study_i::GetChildIterator(SALOMEDS::SObject_ptr theSObject)
856 TDF_Tool::Label(_doc->GetData(),theSObject->GetID(),aLab);
857 return SALOMEDS_ChildIterator_i(this,aLab);
860 //============================================================================
861 /*! Function : NewComponentIterator
862 * Purpose : Create a SComponentIterator
864 //============================================================================
865 SALOMEDS::SComponentIterator_ptr
866 SALOMEDS_Study_i::NewComponentIterator()
868 SALOMEDS::Locker lock;
870 SALOMEDS_SComponentIterator_i* aServant =
871 new SALOMEDS_SComponentIterator_i(GetComponentIterator());
873 return aServant->_this();
876 SALOMEDS_SComponentIterator_i
877 SALOMEDS_Study_i::GetComponentIterator()
879 return SALOMEDS_SComponentIterator_i(this,_doc);
882 //============================================================================
883 /*! Function : GetUseCaseBuilder
884 * Purpose : Returns a UseCase builder
886 //============================================================================
887 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
889 SALOMEDS::Locker lock;
891 return _UseCaseBuilder->_this();
894 //============================================================================
895 /*! Function : NewBuilder
896 * Purpose : Create a StudyBuilder
898 //============================================================================
899 SALOMEDS_StudyBuilder_i* SALOMEDS_Study_i::GetBuilder()
904 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
906 SALOMEDS::Locker lock;
908 return GetBuilder()->_this();
911 //============================================================================
913 * Purpose : get study name
915 //============================================================================
916 char* SALOMEDS_Study_i::Name()
918 SALOMEDS::Locker lock;
920 return CORBA::string_dup(_name);
923 //============================================================================
925 * Purpose : set study name
927 //============================================================================
928 void SALOMEDS_Study_i::Name(const char* name)
930 SALOMEDS::Locker lock;
932 _name = new char[strlen(name) +1];
936 //============================================================================
937 /*! Function : IsSaved
938 * Purpose : get if study has been saved
940 //============================================================================
941 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
943 SALOMEDS::Locker lock;
948 //============================================================================
949 /*! Function : IsSaved
950 * Purpose : set if study has been saved
952 //============================================================================
953 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
955 SALOMEDS::Locker lock;
960 //============================================================================
961 /*! Function : IsModified
962 * Purpose : Detect if a Study has been modified since it has been saved
964 //============================================================================
965 CORBA::Boolean SALOMEDS_Study_i::IsModified()
967 SALOMEDS::Locker lock;
969 // True if is modified and not saved
970 if (_doc->IsModified())
971 if (!_isSaved) return true;
976 //============================================================================
978 * Purpose : get URL of the study (persistent reference of the study)
980 //============================================================================
981 char* SALOMEDS_Study_i::URL()
983 SALOMEDS::Locker lock;
989 return CORBA::string_dup(_URL);
992 //============================================================================
994 * Purpose : set URL of the study (persistent reference of the study)
996 //============================================================================
997 void SALOMEDS_Study_i::URL(const char* url)
999 SALOMEDS::Locker lock;
1001 if (_URL) delete [] _URL;
1002 _URL = new char[strlen(url) +1];
1007 char *adr = strtok(aName, "/");
1011 adr = strtok(NULL, "/");
1018 //============================================================================
1019 /*! Function : _FindObject
1020 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
1022 //============================================================================
1023 SALOMEDS::SObject_ptr
1024 SALOMEDS_Study_i::_FindObject(TDF_Label theLabel,
1025 const char* theObjectName,
1029 // Iterate on each objects and subobjects of the component
1030 // If objectName find, stop the loop and get the object reference
1031 SALOMEDS::SObject_var aRefSO;
1032 TDF_ChildIterator aChildIter(theLabel,true);
1033 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
1034 TDF_Label aLab = aChildIter.Value();
1035 Handle(TDataStd_Name) anAttr;
1036 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
1037 TCollection_AsciiString aString(anAttr->Get());
1038 if(strcmp(aString.ToCString(),theObjectName) == 0){
1039 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
1044 return aRefSO._retn();
1047 //============================================================================
1048 /*! Function : _FindObject
1049 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
1051 //============================================================================
1052 SALOMEDS::SObject_ptr
1053 SALOMEDS_Study_i::_FindObjectIOR(TDF_Label theLabel,
1054 const char* theObjectIOR,
1057 // Iterate on each objects and subobjects of the component
1058 // If objectName find, stop the loop and get the object reference
1059 SALOMEDS::SObject_var aRefSO;
1060 TDF_ChildIterator aChildIter(theLabel,true);
1061 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
1062 TDF_Label aLab = aChildIter.Value();
1063 Handle(SALOMEDS_IORAttribute) anAttr;
1064 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
1065 TCollection_AsciiString aString(anAttr->Get());
1066 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
1067 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
1072 return aRefSO._retn();
1075 CORBA::Short SALOMEDS_Study_i::StudyId()
1077 SALOMEDS::Locker lock;
1082 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
1084 SALOMEDS::Locker lock;
1089 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
1090 SALOMEDS::Locker lock;
1093 CORBA::String_var anEn = CORBA::string_dup(anEntry);
1094 CORBA::String_var IOR = CORBA::string_dup(anIOR);
1095 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
1096 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
1097 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
1100 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute) {
1101 TCollection_AsciiString aString;
1102 TDF_Tool::Entry(theAttribute->Label(),aString);
1103 TCollection_AsciiString aValue(theAttribute->Get());
1104 UpdateIORLabelMap(aValue.ToCString(),aString.ToCString());
1107 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
1108 SALOMEDS::Locker lock;
1110 SALOMEDS::GenericAttribute_ptr aTarget;
1111 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
1112 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
1114 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
1120 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties(){
1121 SALOMEDS::Locker lock;
1123 SALOMEDS::SObject_var aSObject = FindObjectID("0:1");
1125 SALOMEDS::GenericAttribute_var anAttr =
1126 GetBuilder()->FindOrCreateAttribute(aSObject,"AttributeStudyProperties");
1128 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
1131 char* SALOMEDS_Study_i::GetLastModificationDate() {
1132 SALOMEDS::Locker lock;
1134 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1135 SALOMEDS::StringSeq_var aNames;
1136 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1137 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1138 int aLastIndex = aNames->length() - 1;
1140 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
1141 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
1142 CORBA::String_var aResStr = CORBA::string_dup(aResult);
1143 return aResStr._retn();
1146 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
1147 SALOMEDS::Locker lock;
1149 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1150 SALOMEDS::StringSeq_var aNames;
1151 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1152 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
1154 int anIndex, aLength = aNames->length();
1155 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
1156 aDates->length(aLength);
1158 for(anIndex = 0; anIndex < aLength; anIndex++) {
1160 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
1161 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
1162 aDates[anIndex] = CORBA::string_dup(aDate);
1164 return aDates._retn();
1169 //============================================================================
1170 /*! Function : Close
1173 //============================================================================
1174 void SALOMEDS_Study_i::Close()
1176 SALOMEDS::Locker lock;
1178 SALOMEDS_SComponentIterator_i itcomponent(this,_doc);
1180 const CORBA::ORB_var& anORB = GetORB();
1181 for (; itcomponent.More(); itcomponent.Next()) {
1182 SALOMEDS::SComponent_var sco = itcomponent.Value();
1184 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
1185 // if there is an associated Engine call its method for closing
1186 CORBA::String_var IOREngine;
1187 if (sco->ComponentIOR(IOREngine)) {
1188 // we have found the associated engine to write the data
1189 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
1190 CORBA::Object_var obj = anORB->string_to_object(IOREngine);
1191 if (!CORBA::is_nil(obj)) {
1192 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
1194 if (!anEngine->_is_nil()){
1196 anEngine->Close(sco);
1203 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1204 // Handle(TDocStd_Owner) anOwner;
1205 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1206 // Handle(TDocStd_Document) anEmptyDoc;
1207 // anOwner->SetDocument(anEmptyDoc);
1209 if(!anApp.IsNull()) anApp->Close(_doc);
1213 //============================================================================
1214 /*! Function : AddPostponed
1217 //============================================================================
1218 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1219 SALOMEDS::Locker lock;
1221 if (!GetBuilder()->HasOpenCommand()) return;
1223 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1224 if (!CORBA::is_nil(obj)) {
1225 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1226 if (!CORBA::is_nil(aGeneric)) {
1227 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1229 myPostponedIORs.Append(anIOR); // add prefix: deleted
1230 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1236 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1237 SALOMEDS::Locker lock;
1239 if (!GetBuilder()->HasOpenCommand()) return;
1241 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1242 if (!CORBA::is_nil(obj)) {
1243 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1244 if (!CORBA::is_nil(aGeneric)) {
1245 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1247 myPostponedIORs.Append(anIOR); // add prefix: created
1248 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1254 //============================================================================
1255 /*! Function : RemovePostponed
1258 //============================================================================
1259 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1260 SALOMEDS::Locker lock;
1265 int aUndoLimit = theUndoLimit;
1266 if (theUndoLimit < 0) aUndoLimit = 0;
1268 const CORBA::ORB_var& anORB = GetORB();
1269 if (myNbUndos > 0) { // remove undone
1271 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1272 anOld += myNbPostponed(anIndex);
1273 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1275 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1276 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1277 if (anIOR.Value(1) == 'c') {
1278 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1279 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1280 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1283 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1284 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1289 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1291 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1292 anOld += myNbPostponed(anIndex);
1293 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1294 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1295 if (anIOR.Value(1) == 'd') {
1296 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1297 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1298 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1301 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1302 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1305 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1306 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1307 for(; anIter.More(); anIter.Next()) {
1308 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1309 CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
1311 CORBA::Object_var obj = anORB->string_to_object(anIOR);
1312 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1313 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1316 } else myNbPostponed.Append(0);
1319 //============================================================================
1320 /*! Function : UndoPostponed
1323 //============================================================================
1324 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1325 SALOMEDS::Locker lock;
1327 myNbUndos += theWay;
1328 // remove current postponed
1329 if (myNbPostponed.Last() > 0)
1330 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1331 myNbPostponed(myNbPostponed.Length()) = 0;