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();
165 //============================================================================
166 /*! Function : SetOnAddSObject
169 //============================================================================
170 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
172 SALOMEDS::Callback_var aRet = _callbackOnAdd;
173 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
177 //============================================================================
178 /*! Function : SetOnNewSObject
181 //============================================================================
182 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
184 SALOMEDS::Callback_var aRet = _callbackOnRemove;
185 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
189 //============================================================================
190 void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
192 if(!CORBA::is_nil(_callbackOnAdd.in()))
193 _callbackOnAdd->OnAddSObject(theObject);
196 //============================================================================
197 void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
199 if(!CORBA::is_nil(_callbackOnRemove.in()))
200 _callbackOnRemove->OnRemoveSObject(theObject);
203 //============================================================================
204 void SALOMEDS_Study_i::CheckLocked()
206 if(_doc->HasOpenCommand())
209 Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
210 if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
211 if(anAttr->IsLocked())
212 throw SALOMEDS::StudyBuilder::LockProtection();
216 //============================================================================
217 char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
219 return GetORB()->object_to_string(theObject);
223 //============================================================================
224 CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR)
226 return GetORB()->string_to_object(theIOR);
230 //============================================================================
231 /*! Function : GetPersistentReference
232 * Purpose : Get persistent reference of study (idem URL())
234 //============================================================================
235 char* SALOMEDS_Study_i::GetPersistentReference()
239 //============================================================================
240 /*! Function : GetTransientReference
241 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
243 //============================================================================
244 char* SALOMEDS_Study_i::GetTransientReference()
246 CORBA::String_var IOR;
248 Handle(SALOMEDS_IORAttribute) Att;
249 TDF_Label _lab = _doc->GetData()->Root();
250 if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
252 TCollection_AsciiString ch(Att->Get());
253 IOR = CORBA::string_dup(ch.ToCString());
255 else IOR = CORBA::string_dup(""); // NULL ?
257 return CORBA::string_dup(IOR);
260 //============================================================================
261 /*! Function : IsEmpty
262 * Purpose : Detect if study is empty
264 //============================================================================
265 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
267 if (_doc.IsNull()) return true;
268 return _doc->IsEmpty();
271 //============================================================================
272 /*! Function : FindComponent
273 * Purpose : Find a Component with ComponentDataType = aComponentName
275 //============================================================================
276 SALOMEDS::SComponent_ptr
277 SALOMEDS_Study_i::FindComponent(const char* theComponentName)
279 bool anIsFound = false;
280 SALOMEDS::SComponent_var aSComponent;
281 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
282 for(; aComponentIter.More() && !anIsFound; aComponentIter.Next()){
283 SALOMEDS::SComponent_var aSComp = aComponentIter.Value();
284 CORBA::String_var aName = aSComp->ComponentDataType();
285 if(strcmp(theComponentName,aName.in()) == 0){
286 aSComponent = aSComp;
290 return aSComponent._retn();
293 //============================================================================
294 /*! Function : FindComponentID
295 * Purpose : Find a Component from it's ID
297 //============================================================================
298 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
300 // Iterate on each components defined in the study
301 // Get the component ID and compare with aComponentID
304 SALOMEDS::SComponent_ptr compo;
306 SALOMEDS_SComponentIterator_i itcomp(this,_doc);
307 for (; itcomp.More(); itcomp.Next()) {
308 SALOMEDS::SComponent_var SC = itcomp.Value();
310 if(strcmp(aComponentID,ID)==0)
314 compo = SALOMEDS::SComponent::_narrow(SC);
319 compo = SALOMEDS::SComponent::_nil();
324 //============================================================================
325 /*! Function : FindObject
326 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
328 //============================================================================
329 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* theObjectName)
331 // Iterate to all components defined in the study
332 // After testing the component name, iterate in all objects defined under
333 // components (function _FindObject)
334 bool aIsFound = false;
335 SALOMEDS::SObject_var aRefSO;
336 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
337 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
338 TDF_Label aLab = aComponentIter.GetValue();
339 Handle(TDataStd_Name) anAttr;
340 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
341 TCollection_AsciiString aString(anAttr->Get());
342 if(strcmp(aString.ToCString(),theObjectName) == 0){
343 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab)._retn();
348 aRefSO = _FindObject(aLab,theObjectName,aIsFound);
351 return aRefSO._retn();
354 //============================================================================
355 /*! Function : FindObjectID
356 * Purpose : Find an Object with ID = anObjectID
358 //============================================================================
359 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
361 // Convert aSO->GetID in TDF_Label.
363 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
366 return SALOMEDS::SObject::_nil();
368 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
372 //============================================================================
373 /*! Function : CreateObjectID
374 * Purpose : Creates an Object with ID = anObjectID
376 //============================================================================
377 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
379 // Convert aSO->GetID in TDF_Label.
381 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
384 return SALOMEDS::SObject::_nil();
386 return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
389 //============================================================================
390 /*! Function : FindObjectByName
391 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
392 * : with ComponentDataType = aComponentName
394 //============================================================================
395 SALOMEDS::Study::ListOfSObject*
396 SALOMEDS_Study_i::FindObjectByName(const char* theObjectName,
397 const char* theComponentName)
399 SALOMEDS::Study::ListOfSObject_var aListOfSObj = new SALOMEDS::Study::ListOfSObject ;
400 aListOfSObj->length(0);
402 SALOMEDS::SComponent_ptr aSComponent = FindComponent(theComponentName) ;
403 if(aSComponent->_is_nil()){
404 MESSAGE ("In FindObjectByName() : Component named " << theComponentName << " not found ");
405 return aListOfSObj._retn();
408 // Iterate on each object and subobject of the component
409 // If objectName is found add it to the list of SObjects
411 CORBA::String_var anEntry = aSComponent->GetID();
412 TDF_Tool::Label(_doc->GetData(),const_cast<char*>(anEntry.in()),aLabel);
415 SALOMEDS::SObject_var aRefSO;
416 TDF_ChildIterator aChildIter(aLabel,true);
417 for(; aChildIter.More(); aChildIter.Next()){
418 TDF_Label aLab = aChildIter.Value();
419 Handle(TDataStd_Name) anAttr;
420 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
421 TCollection_AsciiString aString(anAttr->Get());
422 if(strcmp(aString.ToCString(),theObjectName) == 0){
423 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab)._retn();
426 aListOfSObj->length(aLength);
427 aListOfSObj[aLength-1] = aRefSO;
432 return aListOfSObj._retn() ;
437 //============================================================================
438 /*! Function : FindObjectIOR
439 * Purpose : Find an Object with IOR = anObjectIOR
441 //============================================================================
442 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
444 // firstly searching in the datamap for optimization
445 char* anIOR = const_cast<char*>(theObjectIOR);
446 if (myIORLabels.IsBound(anIOR)) {
447 SALOMEDS::SObject_var aResult = SALOMEDS_SObject_i::NewRef(this,myIORLabels.Find(anIOR));
448 // 11 oct 2002: forbidden attributes must be checked here
449 SALOMEDS::GenericAttribute_var anAttr;
450 if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
451 myIORLabels.UnBind(anIOR);
453 return aResult._retn();
456 // Iterate to all components defined in the study
457 // After testing the component name, iterate in all objects defined under
458 // components (function _FindObject)
459 bool aIsFound = false;
460 SALOMEDS::SObject_var aRefSO;
461 SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
462 for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
463 TDF_Label aLab = aComponentIter.GetValue();
464 Handle(SALOMEDS_IORAttribute) anAttr;
465 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
466 TCollection_AsciiString aString(anAttr->Get());
467 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
468 aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab);
473 aRefSO = _FindObjectIOR(aLab,theObjectIOR,aIsFound);
476 if(!aRefSO->_is_nil())
477 MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
479 return aRefSO._retn();
482 //============================================================================
483 /*! Function : FindObjectByPath
484 * Purpose : Find an Object by its path = thePath
486 //============================================================================
487 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
489 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
490 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
491 int i = 1, aLength = aPath.Length();
492 bool isRelative = false;
494 if(aLength == 0) { //Empty path - return the current context
495 return SALOMEDS_SObject_i::NewRef(this,_current)._retn();
498 if(aPath.Value(1) != '/') //Relative path
501 TDF_ChildIterator anIterator;
503 Handle(TDataStd_Name) anAttr;
506 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
507 anIterator.Initialize(_current, Standard_False);
510 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
511 return SALOMEDS_SObject_i::NewRef(this,_doc->Main())._retn();
513 anIterator.Initialize(_doc->Main(), Standard_False);
516 while(i <= aLength) {
518 aToken = aPath.Token("/", i);
519 if(aToken.Length() == 0) break;
521 for ( ; anIterator.More(); anIterator.Next() ) {
522 aLabel = anIterator.Value();
523 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
524 if(anAttr->Get() == aToken) {
525 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
526 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
527 return SALOMEDS_SObject_i::NewRef(this,aLabel)._retn();
530 anIterator.Initialize(aLabel, Standard_False);
542 //============================================================================
543 /*! Function : GetObjectPath
546 //============================================================================
547 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
549 TCollection_AsciiString aPath("");
550 if(CORBA::is_nil(theObject))
551 return CORBA::string_dup(aPath.ToCString());
553 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
554 if(anObject->_is_nil()) {
555 CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
556 anObject = FindObjectIOR(anIOR);
557 if(anObject->_is_nil())
558 return CORBA::string_dup(aPath.ToCString());
561 SALOMEDS::GenericAttribute_var anAttr;
562 if(anObject->FindAttribute(anAttr, "AttributeName")) {
563 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
564 if(anAttr->_is_nil())
565 return CORBA::string_dup(aPath.ToCString());
566 TCollection_AsciiString aValue(aName->Value());
570 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
571 if(!aFather->_is_nil()) {
573 Handle(TDataStd_Name) aNameAttrib;
574 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
575 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
576 aValue = GetObjectPath(aFather);
577 aPath = aValue + aPath;
582 return CORBA::string_dup(aPath.ToCString());
586 //============================================================================
587 /*! Function : SetContext
588 * Purpose : Sets the current context
590 //============================================================================
591 void SALOMEDS_Study_i::SetContext(const char* thePath)
593 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
594 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
595 bool isInvalid = false;
596 SALOMEDS::SObject_var aSO;
598 if(aPath.Value(1) != '/') { //Relative path
599 aContext = TCollection_AsciiString(GetContext());
607 aSO = FindObjectByPath(aContext.ToCString());
613 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
616 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
617 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
619 _current = aLabel; //Set the current context
623 //============================================================================
624 /*! Function : GetContext
625 * Purpose : Gets the current context
627 //============================================================================
628 char* SALOMEDS_Study_i::GetContext()
630 if(_current.IsNull())
631 throw SALOMEDS::Study::StudyInvalidContext();
633 SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(this,_current);
634 return GetObjectPath(aSObject);
637 //============================================================================
638 /*! Function : GetObjectNames
639 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
641 //============================================================================
642 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
643 TColStd_SequenceOfExtendedString aResultSeq;
644 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
646 if (strlen(theContext) == 0) {
647 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
650 TDF_Label aTmp = _current;
651 SetContext(theContext);
655 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
656 for(; anIter.More(); anIter.Next()) {
657 TDF_Label aLabel = anIter.Value();
658 // Handle(TDF_Attribute) anAttribute;
659 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
660 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
661 Handle(TDataStd_Name) aName;
662 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
665 // fill the result table
666 int anIndex, aLength = aResultSeq.Length();
667 aResult->length(aLength);
668 for(anIndex = 0; anIndex < aLength; anIndex++) {
669 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
671 return aResult._retn();
674 //============================================================================
675 /*! Function : GetDirectoryNames
676 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
678 //============================================================================
679 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
680 TColStd_SequenceOfExtendedString aResultSeq;
681 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
683 if (strlen(theContext) == 0) {
684 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
687 TDF_Label aTmp = _current;
688 SetContext(theContext);
692 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
693 for(; anIter.More(); anIter.Next()) {
694 TDF_Label aLabel = anIter.Value();
695 Handle(SALOMEDS_LocalIDAttribute) anID;
696 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
697 if (anID->Get() == DIRECTORYID) {
698 Handle(TDataStd_Name) aName;
699 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
700 aResultSeq.Append(aName->Get());
705 // fill the result table
706 int anIndex, aLength = aResultSeq.Length();
707 aResult->length(aLength);
708 for(anIndex = 0; anIndex < aLength; anIndex++) {
709 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
711 return aResult._retn();
714 //============================================================================
715 /*! Function : GetFileNames
716 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
718 //============================================================================
719 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
720 TColStd_SequenceOfExtendedString aResultSeq;
721 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
723 if (strlen(theContext) == 0) {
724 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
727 TDF_Label aTmp = _current;
728 SetContext(theContext);
732 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
733 for(; anIter.More(); anIter.Next()) {
734 TDF_Label aLabel = anIter.Value();
735 Handle(SALOMEDS_LocalIDAttribute) anID;
736 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
737 if (anID->Get() == FILELOCALID) {
738 Handle(SALOMEDS_PersRefAttribute) aName;
739 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
740 TCollection_ExtendedString aFileName = aName->Get();
741 if(aFileName.Length() > 0)
742 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
748 // fill the result table
749 int anIndex, aLength = aResultSeq.Length();
750 aResult->length(aLength);
751 for(anIndex = 0; anIndex < aLength; anIndex++) {
752 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
754 return aResult._retn();
757 //============================================================================
758 /*! Function : GetComponentNames
759 * Purpose : method to get all components names
761 //============================================================================
762 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
763 TColStd_SequenceOfExtendedString aResultSeq;
764 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
765 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
766 for(; anIter.More(); anIter.Next()) {
767 TDF_Label aLabel = anIter.Value();
768 Handle(TDataStd_Name) aName;
769 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
771 // fill the result table
772 int anIndex, aLength = aResultSeq.Length();
773 aResult->length(aLength);
774 for(anIndex = 0; anIndex < aLength; anIndex++) {
775 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
777 return aResult._retn();
780 //============================================================================
781 /*! Function : NewChildIterator
782 * Purpose : Create a ChildIterator from an SObject
784 //============================================================================
785 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
787 //Convert aSO->GetID in TDF_Label.
789 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), Lab);
792 SALOMEDS_ChildIterator_i* aServant = new SALOMEDS_ChildIterator_i(this,Lab);
793 return aServant->_this();
797 //============================================================================
798 /*! Function : NewComponentIterator
799 * Purpose : Create a SComponentIterator
801 //============================================================================
802 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
804 SALOMEDS_SComponentIterator_i* aServant = new SALOMEDS_SComponentIterator_i(this,_doc);
805 return aServant->_this();
808 //============================================================================
809 /*! Function : GetUseCaseBuilder
810 * Purpose : Returns a UseCase builder
812 //============================================================================
813 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
815 return _UseCaseBuilder->_this();
818 //============================================================================
819 /*! Function : NewBuilder
820 * Purpose : Create a StudyBuilder
822 //============================================================================
823 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
825 return _Builder->_this();
828 //============================================================================
830 * Purpose : get study name
832 //============================================================================
833 char* SALOMEDS_Study_i::Name()
835 return CORBA::string_dup(_name);
838 //============================================================================
840 * Purpose : set study name
842 //============================================================================
843 void SALOMEDS_Study_i::Name(const char* name)
845 _name = new char[strlen(name) +1];
849 //============================================================================
850 /*! Function : IsSaved
851 * Purpose : get if study has been saved
853 //============================================================================
854 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
859 //============================================================================
860 /*! Function : IsSaved
861 * Purpose : set if study has been saved
863 //============================================================================
864 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
869 //============================================================================
870 /*! Function : IsModified
871 * Purpose : Detect if a Study has been modified since it has been saved
873 //============================================================================
874 CORBA::Boolean SALOMEDS_Study_i::IsModified()
876 // True if is modified and not saved
877 if (_doc->IsModified())
878 if (!_isSaved) return true;
883 //============================================================================
885 * Purpose : get URL of the study (persistent reference of the study)
887 //============================================================================
888 char* SALOMEDS_Study_i::URL()
894 return CORBA::string_dup(_URL);
897 //============================================================================
899 * Purpose : set URL of the study (persistent reference of the study)
901 //============================================================================
902 void SALOMEDS_Study_i::URL(const char* url)
904 if (_URL) delete [] _URL;
905 _URL = new char[strlen(url) +1];
910 char *adr = strtok(aName, "/");
914 adr = strtok(NULL, "/");
921 //============================================================================
922 /*! Function : _FindObject
923 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
925 //============================================================================
926 SALOMEDS::SObject_ptr
927 SALOMEDS_Study_i::_FindObject(TDF_Label theLabel,
928 const char* theObjectName,
932 // Iterate on each objects and subobjects of the component
933 // If objectName find, stop the loop and get the object reference
934 SALOMEDS::SObject_var aRefSO;
935 TDF_ChildIterator aChildIter(theLabel,true);
936 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
937 TDF_Label aLab = aChildIter.Value();
938 Handle(TDataStd_Name) anAttr;
939 if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
940 TCollection_AsciiString aString(anAttr->Get());
941 if(strcmp(aString.ToCString(),theObjectName) == 0){
942 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
947 return aRefSO._retn();
950 //============================================================================
951 /*! Function : _FindObject
952 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
954 //============================================================================
955 SALOMEDS::SObject_ptr
956 SALOMEDS_Study_i::_FindObjectIOR(TDF_Label theLabel,
957 const char* theObjectIOR,
960 // Iterate on each objects and subobjects of the component
961 // If objectName find, stop the loop and get the object reference
962 SALOMEDS::SObject_var aRefSO;
963 TDF_ChildIterator aChildIter(theLabel,true);
964 for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
965 TDF_Label aLab = aChildIter.Value();
966 Handle(SALOMEDS_IORAttribute) anAttr;
967 if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
968 TCollection_AsciiString aString(anAttr->Get());
969 if(strcmp(aString.ToCString(),theObjectIOR) == 0){
970 aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
975 return aRefSO._retn();
978 CORBA::Short SALOMEDS_Study_i::StudyId()
983 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
988 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
990 CORBA::String_var anEn = CORBA::string_dup(anEntry);
991 CORBA::String_var IOR = CORBA::string_dup(anIOR);
992 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
993 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
994 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
997 SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const TDF_Label theLabel, CORBA::ORB_ptr orb) {
998 Handle(SALOMEDS_IORAttribute) Att;
999 if (theLabel.Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
1000 char* IOR = CORBA::string_dup(TCollection_AsciiString(Att->Get()).ToCString());
1001 CORBA::Object_var obj = orb->string_to_object(IOR);
1002 SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
1003 ASSERT(!CORBA::is_nil(aStudy));
1004 return SALOMEDS::Study::_duplicate(aStudy);
1006 MESSAGE("GetStudy: Problem to get study");
1008 return SALOMEDS::Study::_nil();
1011 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
1012 TCollection_AsciiString aString;
1013 TDF_Tool::Entry(theAttribute->Label(), aString);
1014 GetStudy(theAttribute->Label(), orb)->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(),
1015 aString.ToCString());
1018 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
1019 SALOMEDS::GenericAttribute_ptr aTarget;
1020 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
1021 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
1023 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
1029 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
1030 SALOMEDS::GenericAttribute_ptr anAttr = NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
1031 "AttributeStudyProperties");
1032 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
1035 char* SALOMEDS_Study_i::GetLastModificationDate() {
1036 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1037 SALOMEDS::StringSeq_var aNames;
1038 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1039 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1040 int aLastIndex = aNames->length() - 1;
1042 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
1043 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
1044 CORBA::String_var aResStr = CORBA::string_dup(aResult);
1045 return aResStr._retn();
1048 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
1049 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1050 SALOMEDS::StringSeq_var aNames;
1051 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1052 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
1054 int anIndex, aLength = aNames->length();
1055 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
1056 aDates->length(aLength);
1058 for(anIndex = 0; anIndex < aLength; anIndex++) {
1060 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
1061 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
1062 aDates[anIndex] = CORBA::string_dup(aDate);
1064 return aDates._retn();
1069 //============================================================================
1070 /*! Function : Close
1073 //============================================================================
1074 void SALOMEDS_Study_i::Close()
1076 SALOMEDS_SComponentIterator_i itcomponent(this,_doc);
1078 const CORBA::ORB_var& anORB = GetORB();
1079 for (; itcomponent.More(); itcomponent.Next()) {
1080 SALOMEDS::SComponent_var sco = itcomponent.Value();
1082 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
1083 // if there is an associated Engine call its method for closing
1084 CORBA::String_var IOREngine;
1085 if (sco->ComponentIOR(IOREngine)) {
1086 // we have found the associated engine to write the data
1087 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
1088 CORBA::Object_var obj = anORB->string_to_object(IOREngine);
1089 if (!CORBA::is_nil(obj)) {
1090 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
1092 if (!anEngine->_is_nil())
1093 anEngine->Close(sco);
1098 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1099 // Handle(TDocStd_Owner) anOwner;
1100 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1101 // Handle(TDocStd_Document) anEmptyDoc;
1102 // anOwner->SetDocument(anEmptyDoc);
1104 if(!anApp.IsNull()) anApp->Close(_doc);
1108 //============================================================================
1109 /*! Function : AddPostponed
1112 //============================================================================
1113 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1114 if (!NewBuilder()->HasOpenCommand()) return;
1116 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1117 if (!CORBA::is_nil(obj)) {
1118 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1119 if (!CORBA::is_nil(aGeneric)) {
1120 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1122 myPostponedIORs.Append(anIOR); // add prefix: deleted
1123 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1129 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1130 if (!NewBuilder()->HasOpenCommand()) return;
1132 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1133 if (!CORBA::is_nil(obj)) {
1134 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1135 if (!CORBA::is_nil(aGeneric)) {
1136 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1138 myPostponedIORs.Append(anIOR); // add prefix: created
1139 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1145 //============================================================================
1146 /*! Function : RemovePostponed
1149 //============================================================================
1150 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1154 int aUndoLimit = theUndoLimit;
1155 if (theUndoLimit < 0) aUndoLimit = 0;
1157 const CORBA::ORB_var& anORB = GetORB();
1158 if (myNbUndos > 0) { // remove undone
1160 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1161 anOld += myNbPostponed(anIndex);
1162 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1164 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1165 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1166 if (anIOR.Value(1) == 'c') {
1167 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1168 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1169 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1172 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1173 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1178 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1180 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1181 anOld += myNbPostponed(anIndex);
1182 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1183 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1184 if (anIOR.Value(1) == 'd') {
1185 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1186 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1187 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1190 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1191 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1194 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1195 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1196 for(; anIter.More(); anIter.Next()) {
1197 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1198 CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
1200 CORBA::Object_var obj = anORB->string_to_object(anIOR);
1201 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1202 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1205 } else myNbPostponed.Append(0);
1208 //============================================================================
1209 /*! Function : UndoPostponed
1212 //============================================================================
1213 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1214 myNbUndos += theWay;
1215 // remove current postponed
1216 if (myNbPostponed.Last() > 0)
1217 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1218 myNbPostponed(myNbPostponed.Length()) = 0;