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"
47 #include "SALOMEDS_SObject_i.hxx"
49 #include "SALOMEDS_StudyBuilder_i.hxx"
50 #include "SALOMEDS_ChildIterator_i.hxx"
52 #include "SALOMEDS_UseCaseBuilder_i.hxx"
53 #include "SALOMEDS_SComponentIterator_i.hxx"
55 #include "SALOME_GenericObj_i.hh"
56 #include "SALOMEDS_LocalIDAttribute.hxx"
57 #include "SALOMEDS_PersRefAttribute.hxx"
59 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
60 #include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
62 #include "utilities.h"
64 #define DIRECTORYID 16661
65 #define FILEID "FILE: "
66 #define FILELOCALID 26662
71 bool operator<(const TDF_Label& theLeft, const TDF_Label& theRight)
73 TColStd_ListOfInteger aTagLeftList;
74 TDF_Tool::TagList(theLeft,aTagLeftList);
75 TColStd_ListIteratorOfListOfInteger anLeftIter(aTagLeftList);
77 TColStd_ListOfInteger aTagRightList;
78 TDF_Tool::TagList(theRight,aTagRightList);
79 TColStd_ListIteratorOfListOfInteger anRightIter(aTagRightList);
82 Standard_Boolean aLeftMore = anLeftIter.More();
83 Standard_Boolean aRightMore = anRightIter.More();
85 if(!aLeftMore && !aRightMore)
86 return Standard_False;
92 return Standard_False;
94 Standard_Integer aLeftTag = anLeftIter.Value();
97 Standard_Integer aRightTag = anRightIter.Value();
100 if(aLeftTag == aRightTag)
103 return aLeftTag < aRightTag;
106 return Standard_False;
110 //============================================================================
111 /*! Function : SALOMEDS_Study_i
112 * Purpose : SALOMEDS_Study_i constructor
114 //============================================================================
115 SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDS_StudyManager_i* theStudyManager,
116 const Handle(TDocStd_Document)& theDoc,
117 const char* theStudyName):
118 _StudyManager(theStudyManager),
126 _UseCaseBuilder = new SALOMEDS_UseCaseBuilder_i(this,_doc);
127 SALOMEDS::UseCaseBuilder_var aUseCaseBuilder = _UseCaseBuilder->_this();
129 _Builder = new SALOMEDS_StudyBuilder_i(this,_doc);
130 SALOMEDS::StudyBuilder_var aStudyBuilder = _Builder->_this();
132 SALOMEDS_Callback_i* aCallBackServant = new SALOMEDS_Callback_i(aUseCaseBuilder);
133 _callbackOnAdd = aCallBackServant->_this();
134 _callbackOnRemove = _callbackOnAdd;
136 _name = new char[strlen(theStudyName) +1];
137 strcpy(_name,theStudyName);
138 myNbPostponed.Append(0);
141 //============================================================================
142 /*! Function : ~SALOMEDS_Study_i
143 * Purpose : SALOMEDS_Study_i destructor
145 //============================================================================
146 SALOMEDS_Study_i::~SALOMEDS_Study_i()
152 //============================================================================
153 CORBA::ORB_var SALOMEDS_Study_i::GetORB() const
155 return _StudyManager->GetORB();
158 //============================================================================
159 PortableServer::POA_var SALOMEDS_Study_i::GetPOA() const
161 return _StudyManager->GetPOA();
164 //============================================================================
165 /*! Function : SetOnAddSObject
168 //============================================================================
169 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
171 SALOMEDS::Callback_var aRet = _callbackOnAdd;
172 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
176 //============================================================================
177 /*! Function : SetOnNewSObject
180 //============================================================================
181 SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
183 SALOMEDS::Callback_var aRet = _callbackOnRemove;
184 _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
188 //============================================================================
189 void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
191 if(!CORBA::is_nil(_callbackOnAdd.in()))
192 _callbackOnAdd->OnAddSObject(theObject);
195 //============================================================================
196 void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
198 if(!CORBA::is_nil(_callbackOnRemove.in()))
199 _callbackOnRemove->OnRemoveSObject(theObject);
202 //============================================================================
203 void SALOMEDS_Study_i::CheckLocked()
205 if(_doc->HasOpenCommand())
208 Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
209 if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
210 if(anAttr->IsLocked())
211 throw SALOMEDS::StudyBuilder::LockProtection();
215 //============================================================================
216 char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
218 return GetORB()->object_to_string(theObject);
222 //============================================================================
223 CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR)
225 return GetORB()->string_to_object(theIOR);
229 //============================================================================
230 /*! Function : GetPersistentReference
231 * Purpose : Get persistent reference of study (idem URL())
233 //============================================================================
234 char* SALOMEDS_Study_i::GetPersistentReference()
238 //============================================================================
239 /*! Function : GetTransientReference
240 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
242 //============================================================================
243 char* SALOMEDS_Study_i::GetTransientReference()
245 CORBA::String_var IOR;
247 Handle(SALOMEDS_IORAttribute) Att;
248 TDF_Label _lab = _doc->GetData()->Root();
249 if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
251 TCollection_AsciiString ch(Att->Get());
252 IOR = CORBA::string_dup(ch.ToCString());
254 else IOR = CORBA::string_dup(""); // NULL ?
256 return CORBA::string_dup(IOR);
259 //============================================================================
260 /*! Function : IsEmpty
261 * Purpose : Detect if study is empty
263 //============================================================================
264 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
266 if (_doc.IsNull()) return true;
267 return _doc->IsEmpty();
270 //============================================================================
271 /*! Function : FindComponent
272 * Purpose : Find a Component with ComponentDataType = aComponentName
274 //============================================================================
275 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
278 Standard_CString name;
279 SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
280 SALOMEDS::SComponent_var compo;
282 for (; itcomp->More(); itcomp->Next()) {
283 SALOMEDS::SComponent_var SC = itcomp->Value();
284 name = SC->ComponentDataType();
285 if(strcmp(aComponentName,name) == 0){
287 return SALOMEDS::SComponent::_narrow(SC);
292 return SALOMEDS::SComponent::_nil();
297 //============================================================================
298 /*! Function : FindComponentID
299 * Purpose : Find a Component from it's ID
301 //============================================================================
302 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
304 // Iterate on each components defined in the study
305 // Get the component ID and compare with aComponentID
308 SALOMEDS::SComponent_ptr compo;
310 SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
311 for (; itcomp->More(); itcomp->Next()) {
312 SALOMEDS::SComponent_var SC = itcomp->Value();
314 if(strcmp(aComponentID,ID)==0)
318 compo = SALOMEDS::SComponent::_narrow(SC);
323 compo = SALOMEDS::SComponent::_nil();
328 //============================================================================
329 /*! Function : FindObject
330 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
332 //============================================================================
333 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
335 // Iterate to all components defined in the study
336 // After testing the component name, iterate in all objects defined under
337 // components (function _FindObject)
339 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
341 SALOMEDS::SComponentIterator_var it = NewComponentIterator();
342 for (; it->More();it->Next()){
345 SALOMEDS::SComponent_var SC = it->Value();
346 SALOMEDS::GenericAttribute_var anAttr;
347 if (SC->FindAttribute(anAttr,"AttributeName"))
349 SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
350 CORBA::String_var Val = Name->Value();
351 if (strcmp(Val, anObjectName) == 0)
354 RefSO = SALOMEDS::SObject::_narrow(SC);
357 if (!_find) RefSO = _FindObject(SC,anObjectName, _find);
363 //============================================================================
364 /*! Function : FindObjectID
365 * Purpose : Find an Object with ID = anObjectID
367 //============================================================================
368 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
370 // Convert aSO->GetID in TDF_Label.
372 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
375 return SALOMEDS::SObject::_nil();
377 return SALOMEDS_SObject_i::New(this,Lab)->_this();
381 //============================================================================
382 /*! Function : CreateObjectID
383 * Purpose : Creates an Object with ID = anObjectID
385 //============================================================================
386 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
388 // Convert aSO->GetID in TDF_Label.
390 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
393 return SALOMEDS::SObject::_nil();
395 return SALOMEDS_SObject_i::New(this,Lab)->_this();
398 //============================================================================
399 /*! Function : FindObjectByName
400 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
401 * : with ComponentDataType = aComponentName
403 //============================================================================
404 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
405 const char* aComponentName )
407 SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
410 SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
411 if ( compo->_is_nil() ) {
412 MESSAGE ("In FindObjectByName() : Component named " << aComponentName << " not found ");
413 return listSO._retn();
416 // Iterate on each object and subobject of the component
417 // If objectName is found add it to the list of SObjects
419 SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
421 CORBA::String_var compoId = compo->GetID();
422 SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
424 for ( ; it->More();it->Next() ) {
426 SALOMEDS::SObject_var CSO = it->Value();
427 SALOMEDS::GenericAttribute_var anAttr;
428 SALOMEDS::AttributeName_var aName;
429 if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
430 aName = SALOMEDS::AttributeName::_narrow(anAttr);
431 name = aName->Value();
432 if ( strcmp( name, anObjectName ) == 0) {
433 addSO = SALOMEDS::SObject::_narrow(CSO);
436 listSO->length(length);
437 listSO[length-1] = addSO ;
440 /* looks also for eventual children */
442 addSO = _FindObject( CSO, anObjectName, found ) ;
445 listSO->length(length);
446 listSO[length-1] = addSO ;
450 return listSO._retn() ;
455 //============================================================================
456 /*! Function : FindObjectIOR
457 * Purpose : Find an Object with IOR = anObjectIOR
459 //============================================================================
460 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
462 // firstly searching in the datamap for optimization
463 char* anIOR = const_cast<char*>(theObjectIOR);
464 if (myIORLabels.IsBound(anIOR)) {
465 SALOMEDS_SObject_i* aResult = SALOMEDS_SObject_i::New(this,myIORLabels.Find(anIOR));
466 // 11 oct 2002: forbidden attributes must be checked here
467 SALOMEDS::GenericAttribute_var anAttr;
468 if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
469 myIORLabels.UnBind(anIOR);
471 return aResult->_this();
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)
477 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
479 SALOMEDS::SComponentIterator_var it = NewComponentIterator();
480 for (; it->More();it->Next()){
482 SALOMEDS::SComponent_var SC = it->Value();
483 SALOMEDS::GenericAttribute_var anAttr;
484 if(SC->FindAttribute(anAttr,"AttributeIOR")){
485 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
486 CORBA::String_var aVal = IOR->Value();
487 if (strcmp(aVal,theObjectIOR) == 0){
489 RefSO = SALOMEDS::SObject::_narrow(SC);
493 RefSO = _FindObjectIOR(SC,theObjectIOR,_find);
496 if (!RefSO->_is_nil()) MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
501 //============================================================================
502 /*! Function : FindObjectByPath
503 * Purpose : Find an Object by its path = thePath
505 //============================================================================
506 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
508 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
509 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
510 int i = 1, aLength = aPath.Length();
511 bool isRelative = false;
513 if(aLength == 0) { //Empty path - return the current context
514 return SALOMEDS_SObject_i::New(this,_current)->_this();
517 if(aPath.Value(1) != '/') //Relative path
520 TDF_ChildIterator anIterator;
522 Handle(TDataStd_Name) anAttr;
525 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
526 anIterator.Initialize(_current, Standard_False);
529 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
530 return SALOMEDS_SObject_i::New (this,_doc->Main())->_this();
532 anIterator.Initialize(_doc->Main(), Standard_False);
535 while(i <= aLength) {
537 aToken = aPath.Token("/", i);
538 if(aToken.Length() == 0) break;
540 for ( ; anIterator.More(); anIterator.Next() ) {
541 aLabel = anIterator.Value();
542 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
543 if(anAttr->Get() == aToken) {
544 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
545 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
546 return SALOMEDS_SObject_i::New(this,aLabel)->_this();
549 anIterator.Initialize(aLabel, Standard_False);
561 //============================================================================
562 /*! Function : GetObjectPath
565 //============================================================================
566 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
568 TCollection_AsciiString aPath("");
569 if(CORBA::is_nil(theObject))
570 return CORBA::string_dup(aPath.ToCString());
572 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
573 if(anObject->_is_nil()) {
574 CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
575 anObject = FindObjectIOR(anIOR);
576 if(anObject->_is_nil())
577 return CORBA::string_dup(aPath.ToCString());
580 SALOMEDS::GenericAttribute_var anAttr;
581 if(anObject->FindAttribute(anAttr, "AttributeName")) {
582 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
583 if(anAttr->_is_nil())
584 return CORBA::string_dup(aPath.ToCString());
585 TCollection_AsciiString aValue(aName->Value());
589 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
590 if(!aFather->_is_nil()) {
592 Handle(TDataStd_Name) aNameAttrib;
593 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
594 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
595 aValue = GetObjectPath(aFather);
596 aPath = aValue + aPath;
601 return CORBA::string_dup(aPath.ToCString());
605 //============================================================================
606 /*! Function : SetContext
607 * Purpose : Sets the current context
609 //============================================================================
610 void SALOMEDS_Study_i::SetContext(const char* thePath)
612 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
613 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
614 bool isInvalid = false;
615 SALOMEDS::SObject_var aSO;
617 if(aPath.Value(1) != '/') { //Relative path
618 aContext = TCollection_AsciiString(GetContext());
626 aSO = FindObjectByPath(aContext.ToCString());
632 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
635 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
636 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
638 _current = aLabel; //Set the current context
642 //============================================================================
643 /*! Function : GetContext
644 * Purpose : Gets the current context
646 //============================================================================
647 char* SALOMEDS_Study_i::GetContext()
649 if(_current.IsNull())
650 throw SALOMEDS::Study::StudyInvalidContext();
651 SALOMEDS_SObject_i* aServant = SALOMEDS_SObject_i::New(this,_current);
652 SALOMEDS::SObject_var aSObject = aServant->_this();
653 return GetObjectPath(aSObject);
656 //============================================================================
657 /*! Function : GetObjectNames
658 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
660 //============================================================================
661 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
662 TColStd_SequenceOfExtendedString aResultSeq;
663 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
665 if (strlen(theContext) == 0) {
666 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
669 TDF_Label aTmp = _current;
670 SetContext(theContext);
674 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
675 for(; anIter.More(); anIter.Next()) {
676 TDF_Label aLabel = anIter.Value();
677 // Handle(TDF_Attribute) anAttribute;
678 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
679 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
680 Handle(TDataStd_Name) aName;
681 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
684 // fill the result table
685 int anIndex, aLength = aResultSeq.Length();
686 aResult->length(aLength);
687 for(anIndex = 0; anIndex < aLength; anIndex++) {
688 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
690 return aResult._retn();
693 //============================================================================
694 /*! Function : GetDirectoryNames
695 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
697 //============================================================================
698 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
699 TColStd_SequenceOfExtendedString aResultSeq;
700 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
702 if (strlen(theContext) == 0) {
703 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
706 TDF_Label aTmp = _current;
707 SetContext(theContext);
711 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
712 for(; anIter.More(); anIter.Next()) {
713 TDF_Label aLabel = anIter.Value();
714 Handle(SALOMEDS_LocalIDAttribute) anID;
715 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
716 if (anID->Get() == DIRECTORYID) {
717 Handle(TDataStd_Name) aName;
718 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
719 aResultSeq.Append(aName->Get());
724 // fill the result table
725 int anIndex, aLength = aResultSeq.Length();
726 aResult->length(aLength);
727 for(anIndex = 0; anIndex < aLength; anIndex++) {
728 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
730 return aResult._retn();
733 //============================================================================
734 /*! Function : GetFileNames
735 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
737 //============================================================================
738 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
739 TColStd_SequenceOfExtendedString aResultSeq;
740 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
742 if (strlen(theContext) == 0) {
743 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
746 TDF_Label aTmp = _current;
747 SetContext(theContext);
751 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
752 for(; anIter.More(); anIter.Next()) {
753 TDF_Label aLabel = anIter.Value();
754 Handle(SALOMEDS_LocalIDAttribute) anID;
755 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
756 if (anID->Get() == FILELOCALID) {
757 Handle(SALOMEDS_PersRefAttribute) aName;
758 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
759 TCollection_ExtendedString aFileName = aName->Get();
760 if(aFileName.Length() > 0)
761 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
767 // fill the result table
768 int anIndex, aLength = aResultSeq.Length();
769 aResult->length(aLength);
770 for(anIndex = 0; anIndex < aLength; anIndex++) {
771 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
773 return aResult._retn();
776 //============================================================================
777 /*! Function : GetComponentNames
778 * Purpose : method to get all components names
780 //============================================================================
781 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
782 TColStd_SequenceOfExtendedString aResultSeq;
783 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
784 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
785 for(; anIter.More(); anIter.Next()) {
786 TDF_Label aLabel = anIter.Value();
787 Handle(TDataStd_Name) aName;
788 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
790 // fill the result table
791 int anIndex, aLength = aResultSeq.Length();
792 aResult->length(aLength);
793 for(anIndex = 0; anIndex < aLength; anIndex++) {
794 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
796 return aResult._retn();
799 //============================================================================
800 /*! Function : NewChildIterator
801 * Purpose : Create a ChildIterator from an SObject
803 //============================================================================
804 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
806 //Convert aSO->GetID in TDF_Label.
808 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), Lab);
811 SALOMEDS_ChildIterator_i* aServant = new SALOMEDS_ChildIterator_i(this,Lab);
812 return aServant->_this();
816 //============================================================================
817 /*! Function : NewComponentIterator
818 * Purpose : Create a SComponentIterator
820 //============================================================================
821 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
823 SALOMEDS_SComponentIterator_i* aServant = new SALOMEDS_SComponentIterator_i(this,_doc);
824 return aServant->_this();
827 //============================================================================
828 /*! Function : GetUseCaseBuilder
829 * Purpose : Returns a UseCase builder
831 //============================================================================
832 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
834 return _UseCaseBuilder->_this();
837 //============================================================================
838 /*! Function : NewBuilder
839 * Purpose : Create a StudyBuilder
841 //============================================================================
842 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
844 return _Builder->_this();
847 //============================================================================
849 * Purpose : get study name
851 //============================================================================
852 char* SALOMEDS_Study_i::Name()
854 return CORBA::string_dup(_name);
857 //============================================================================
859 * Purpose : set study name
861 //============================================================================
862 void SALOMEDS_Study_i::Name(const char* name)
864 _name = new char[strlen(name) +1];
868 //============================================================================
869 /*! Function : IsSaved
870 * Purpose : get if study has been saved
872 //============================================================================
873 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
878 //============================================================================
879 /*! Function : IsSaved
880 * Purpose : set if study has been saved
882 //============================================================================
883 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
888 //============================================================================
889 /*! Function : IsModified
890 * Purpose : Detect if a Study has been modified since it has been saved
892 //============================================================================
893 CORBA::Boolean SALOMEDS_Study_i::IsModified()
895 // True if is modified and not saved
896 if (_doc->IsModified())
897 if (!_isSaved) return true;
902 //============================================================================
904 * Purpose : get URL of the study (persistent reference of the study)
906 //============================================================================
907 char* SALOMEDS_Study_i::URL()
913 return CORBA::string_dup(_URL);
916 //============================================================================
918 * Purpose : set URL of the study (persistent reference of the study)
920 //============================================================================
921 void SALOMEDS_Study_i::URL(const char* url)
923 if (_URL) delete [] _URL;
924 _URL = new char[strlen(url) +1];
929 char *adr = strtok(aName, "/");
933 adr = strtok(NULL, "/");
940 //============================================================================
941 /*! Function : _FindObject
942 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
944 //============================================================================
945 SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
946 const char* anObjectName,
950 // Iterate on each objects and subobjects of the component
951 // If objectName find, stop the loop and get the object reference
952 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
953 CORBA::String_var soid = SO->GetID();
954 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
955 for (; it->More();it->Next()){
958 SALOMEDS::SObject_var CSO = it->Value();
959 SALOMEDS::GenericAttribute_var anAttr;
960 if (CSO->FindAttribute(anAttr,"AttributeName"))
962 SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
963 CORBA::String_var Val = Name->Value();
964 if (strcmp(Val, anObjectName) == 0)
966 RefSO = SALOMEDS::SObject::_narrow(CSO);
970 if (!_find) RefSO = _FindObject(CSO, anObjectName, _find);
976 //============================================================================
977 /*! Function : _FindObject
978 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
980 //============================================================================
981 SALOMEDS::SObject_ptr
982 SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
983 const char* anObjectIOR,
986 // Iterate on each objects and subobjects of the component
987 // If objectName find, stop the loop and get the object reference
988 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
990 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
991 for (; it->More();it->Next()){
994 SALOMEDS::SObject_var CSO = it->Value();
995 SALOMEDS::GenericAttribute_var anAttr;
996 if (CSO->FindAttribute(anAttr,"AttributeIOR"))
998 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
999 CORBA::String_var Val = IOR->Value();
1000 if (strcmp(Val, anObjectIOR) == 0)
1002 RefSO = SALOMEDS::SObject::_narrow(CSO);
1006 if (!_find) RefSO = _FindObjectIOR(CSO, anObjectIOR, _find);
1012 CORBA::Short SALOMEDS_Study_i::StudyId()
1017 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
1022 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
1024 CORBA::String_var anEn = CORBA::string_dup(anEntry);
1025 CORBA::String_var IOR = CORBA::string_dup(anIOR);
1026 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
1027 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
1028 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
1031 SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const TDF_Label theLabel, CORBA::ORB_ptr orb) {
1032 Handle(SALOMEDS_IORAttribute) Att;
1033 if (theLabel.Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
1034 char* IOR = CORBA::string_dup(TCollection_AsciiString(Att->Get()).ToCString());
1035 CORBA::Object_var obj = orb->string_to_object(IOR);
1036 SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
1037 ASSERT(!CORBA::is_nil(aStudy));
1038 return SALOMEDS::Study::_duplicate(aStudy);
1040 MESSAGE("GetStudy: Problem to get study");
1042 return SALOMEDS::Study::_nil();
1045 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
1046 TCollection_AsciiString aString;
1047 TDF_Tool::Entry(theAttribute->Label(), aString);
1048 GetStudy(theAttribute->Label(), orb)->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(),
1049 aString.ToCString());
1052 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
1053 SALOMEDS::GenericAttribute_ptr aTarget;
1054 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
1055 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
1057 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
1063 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
1064 SALOMEDS::GenericAttribute_ptr anAttr = NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
1065 "AttributeStudyProperties");
1066 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
1069 char* SALOMEDS_Study_i::GetLastModificationDate() {
1070 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1071 SALOMEDS::StringSeq_var aNames;
1072 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1073 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1074 int aLastIndex = aNames->length() - 1;
1076 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
1077 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
1078 CORBA::String_var aResStr = CORBA::string_dup(aResult);
1079 return aResStr._retn();
1082 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
1083 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
1084 SALOMEDS::StringSeq_var aNames;
1085 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1086 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
1088 int anIndex, aLength = aNames->length();
1089 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
1090 aDates->length(aLength);
1092 for(anIndex = 0; anIndex < aLength; anIndex++) {
1094 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
1095 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
1096 aDates[anIndex] = CORBA::string_dup(aDate);
1098 return aDates._retn();
1103 //============================================================================
1104 /*! Function : Close
1107 //============================================================================
1108 void SALOMEDS_Study_i::Close()
1110 SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
1112 const CORBA::ORB_var& anORB = GetORB();
1113 for (; itcomponent->More(); itcomponent->Next()) {
1114 SALOMEDS::SComponent_var sco = itcomponent->Value();
1116 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
1117 // if there is an associated Engine call its method for closing
1118 CORBA::String_var IOREngine;
1119 if (sco->ComponentIOR(IOREngine)) {
1120 // we have found the associated engine to write the data
1121 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
1122 CORBA::Object_var obj = anORB->string_to_object(IOREngine);
1123 if (!CORBA::is_nil(obj)) {
1124 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
1126 if (!anEngine->_is_nil())
1127 anEngine->Close(sco);
1132 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1133 // Handle(TDocStd_Owner) anOwner;
1134 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1135 // Handle(TDocStd_Document) anEmptyDoc;
1136 // anOwner->SetDocument(anEmptyDoc);
1138 if(!anApp.IsNull()) anApp->Close(_doc);
1142 //============================================================================
1143 /*! Function : AddPostponed
1146 //============================================================================
1147 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1148 if (!NewBuilder()->HasOpenCommand()) return;
1150 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1151 if (!CORBA::is_nil(obj)) {
1152 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1153 if (!CORBA::is_nil(aGeneric)) {
1154 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1156 myPostponedIORs.Append(anIOR); // add prefix: deleted
1157 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1163 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1164 if (!NewBuilder()->HasOpenCommand()) return;
1166 CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
1167 if (!CORBA::is_nil(obj)) {
1168 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1169 if (!CORBA::is_nil(aGeneric)) {
1170 TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
1172 myPostponedIORs.Append(anIOR); // add prefix: created
1173 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1179 //============================================================================
1180 /*! Function : RemovePostponed
1183 //============================================================================
1184 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1188 int aUndoLimit = theUndoLimit;
1189 if (theUndoLimit < 0) aUndoLimit = 0;
1191 const CORBA::ORB_var& anORB = GetORB();
1192 if (myNbUndos > 0) { // remove undone
1194 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1195 anOld += myNbPostponed(anIndex);
1196 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1198 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1199 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1200 if (anIOR.Value(1) == 'c') {
1201 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1202 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1203 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1206 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1207 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1212 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1214 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1215 anOld += myNbPostponed(anIndex);
1216 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1217 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1218 if (anIOR.Value(1) == 'd') {
1219 CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
1220 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1221 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1224 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1225 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1228 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1229 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1230 for(; anIter.More(); anIter.Next()) {
1231 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1232 CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
1234 CORBA::Object_var obj = anORB->string_to_object(anIOR);
1235 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1236 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1239 } else myNbPostponed.Append(0);
1242 //============================================================================
1243 /*! Function : UndoPostponed
1246 //============================================================================
1247 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1248 myNbUndos += theWay;
1249 // remove current postponed
1250 if (myNbPostponed.Last() > 0)
1251 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1252 myNbPostponed(myNbPostponed.Length()) = 0;