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
30 #include "utilities.h"
31 #include "SALOMEDS_Study_i.hxx"
33 #include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
34 #include <TColStd_SequenceOfExtendedString.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <TCollection_ExtendedString.hxx>
37 #include <TDataStd_ChildNodeIterator.hxx>
38 #include <TDocStd_Application.hxx>
39 #include <TDocStd_Owner.hxx>
40 #include <CDM_Document.hxx>
41 #include <CDM_Application.hxx>
42 #include <TDF_ChildIDIterator.hxx>
43 #include <SALOME_GenericObj_i.hh>
44 #include "SALOMEDS_LocalIDAttribute.hxx"
45 #include "SALOMEDS_PersRefAttribute.hxx"
46 #include "SALOMEDS_UseCaseIterator_i.hxx"
49 #define DIRECTORYID 16661
50 #define FILEID "FILE: "
51 #define FILELOCALID 26662
53 //============================================================================
54 /*! Function : SALOMEDS_Study_i
55 * Purpose : SALOMEDS_Study_i constructor
57 //============================================================================
58 SALOMEDS_Study_i::SALOMEDS_Study_i(const Handle(TDocStd_Document) doc,
60 const char* study_name)
62 _orb = CORBA::ORB::_duplicate(orb);
64 _name = new char[strlen(study_name) +1];
65 strcpy(_name,study_name);
70 myNbPostponed.Append(0);
74 //============================================================================
75 /*! Function : ~SALOMEDS_Study_i
76 * Purpose : SALOMEDS_Study_i destructor
78 //============================================================================
79 SALOMEDS_Study_i::~SALOMEDS_Study_i()
85 //============================================================================
86 /*! Function : GetPersistentReference
87 * Purpose : Get persistent reference of study (idem URL())
89 //============================================================================
90 char* SALOMEDS_Study_i::GetPersistentReference()
94 //============================================================================
95 /*! Function : GetTransientReference
96 * Purpose : Get IOR of the Study (registred in OCAF document in doc->Root)
98 //============================================================================
99 char* SALOMEDS_Study_i::GetTransientReference()
101 CORBA::String_var IOR;
103 Handle(SALOMEDS_IORAttribute) Att;
104 TDF_Label _lab = _doc->GetData()->Root();
105 if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
107 TCollection_AsciiString ch(Att->Get());
108 IOR = CORBA::string_dup(ch.ToCString());
110 else IOR = CORBA::string_dup(""); // NULL ?
112 return CORBA::string_dup(IOR);
115 //============================================================================
116 /*! Function : IsEmpty
117 * Purpose : Detect if study is empty
119 //============================================================================
120 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
122 if (_doc.IsNull()) return true;
123 return _doc->IsEmpty();
126 //============================================================================
127 /*! Function : FindComponent
128 * Purpose : Find a Component with ComponentDataType = aComponentName
130 //============================================================================
131 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
134 Standard_CString name;
135 SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
136 SALOMEDS::SComponent_var compo;
138 for (; itcomp->More(); itcomp->Next()) {
139 SALOMEDS::SComponent_var SC = itcomp->Value();
140 name = SC->ComponentDataType();
141 //ED if ( TCollection_AsciiString(name).IsEqual(TCollection_AsciiString(strdup(aComponentName))) ) {
142 if(strcmp(aComponentName,name) == 0){
144 return SALOMEDS::SComponent::_narrow(SC);
149 return SALOMEDS::SComponent::_nil();
154 //============================================================================
155 /*! Function : FindComponentID
156 * Purpose : Find a Component from it's ID
158 //============================================================================
159 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
161 // Iterate on each components defined in the study
162 // Get the component ID and compare with aComponentID
165 SALOMEDS::SComponent_ptr compo;
167 SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
168 for (; itcomp->More(); itcomp->Next()) {
169 SALOMEDS::SComponent_var SC = itcomp->Value();
171 if(strcmp(aComponentID,ID)==0)
175 compo = SALOMEDS::SComponent::_narrow(SC);
180 compo = SALOMEDS::SComponent::_nil();
185 //============================================================================
186 /*! Function : FindObject
187 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
189 //============================================================================
190 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
192 // Iterate to all components defined in the study
193 // After testing the component name, iterate in all objects defined under
194 // components (function _FindObject)
196 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
198 SALOMEDS::SComponentIterator_var it = NewComponentIterator();
199 for (; it->More();it->Next()){
202 SALOMEDS::SComponent_var SC = it->Value();
203 SALOMEDS::GenericAttribute_var anAttr;
204 if (SC->FindAttribute(anAttr,"AttributeName"))
206 SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
207 CORBA::String_var Val = Name->Value();
208 if (strcmp(Val, anObjectName) == 0)
211 RefSO = SALOMEDS::SObject::_narrow(SC);
214 if (!_find) RefSO = _FindObject(SC,anObjectName, _find);
220 //============================================================================
221 /*! Function : FindObjectID
222 * Purpose : Find an Object with ID = anObjectID
224 //============================================================================
225 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
227 // Convert aSO->GetID in TDF_Label.
229 TDF_Tool::Label(_doc->GetData(), strdup(anObjectID), Lab);
231 if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
232 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (Lab,_orb);
233 SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this());
238 //============================================================================
239 /*! Function : FindObjectByName
240 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
241 * : with ComponentDataType = aComponentName
243 //============================================================================
244 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
245 const char* aComponentName )
247 SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
250 SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
251 if ( compo->_is_nil() ) {
252 MESSAGE ("In FindObjectByName() : Component named " << aComponentName << " not found ");
253 return listSO._retn();
256 // Iterate on each object and subobject of the component
257 // If objectName is found add it to the list of SObjects
260 SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
262 CORBA::String_var compoId = compo->GetID();
263 SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
265 for ( ; it->More();it->Next() ) {
267 SALOMEDS::SObject_var CSO = it->Value();
268 SALOMEDS::GenericAttribute_var anAttr;
269 SALOMEDS::AttributeName_var aName;
270 if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
271 aName = SALOMEDS::AttributeName::_narrow(anAttr);
272 name = aName->Value();
273 if ( strcmp( name, anObjectName ) == 0) {
274 addSO = SALOMEDS::SObject::_narrow(CSO);
277 listSO->length(length);
278 listSO[length-1] = addSO ;
281 /* looks also for eventual children */
283 addSO = _FindObject( CSO, anObjectName, found ) ;
286 listSO->length(length);
287 listSO[length-1] = addSO ;
291 return listSO._retn() ;
296 //============================================================================
297 /*! Function : FindObjectIOR
298 * Purpose : Find an Object with IOR = anObjectIOR
300 //============================================================================
301 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
303 // firstly searching in the datamap for optimization
304 CORBA::String_var anIOR = CORBA::string_dup(anObjectIOR);
305 if (myIORLabels.IsBound(TCollection_ExtendedString(anIOR))) {
306 SALOMEDS_SObject_i* aResult = new SALOMEDS_SObject_i(myIORLabels.Find(TCollection_ExtendedString(anIOR)),_orb);
307 // 11 oct 2002: forbidden attributes must be checked here
308 SALOMEDS::GenericAttribute_var anAttr;
309 if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
310 myIORLabels.UnBind(TCollection_ExtendedString(anIOR));
311 } else return aResult->_this();
313 // Iterate to all components defined in the study
314 // After testing the component name, iterate in all objects defined under
315 // components (function _FindObject)
317 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
319 SALOMEDS::SComponentIterator_var it = NewComponentIterator();
320 for (; it->More();it->Next()){
323 SALOMEDS::SComponent_var SC = it->Value();
324 SALOMEDS::GenericAttribute_var anAttr;
325 if (SC->FindAttribute(anAttr,"AttributeIOR"))
327 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
328 CORBA::String_var Val = IOR->Value();
329 if (strcmp(Val, anObjectIOR) == 0)
332 RefSO = SALOMEDS::SObject::_narrow(SC);
336 RefSO = _FindObjectIOR(SC,anObjectIOR, _find);
339 if (!RefSO->_is_nil()) INFOS("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
344 //============================================================================
345 /*! Function : FindObjectByPath
346 * Purpose : Find an Object by its path = thePath
348 //============================================================================
349 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
351 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
352 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
353 int i = 1, aLength = aPath.Length();
354 bool isRelative = false;
356 if(aLength == 0) { //Empty path - return the current context
357 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_current, _orb);
358 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
362 if(aPath.Value(1) != '/') //Relative path
365 TDF_ChildIterator anIterator;
367 Handle(TDataStd_Name) anAttr;
370 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
371 anIterator.Initialize(_current, Standard_False);
374 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
375 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_doc->Main(), _orb);
376 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
379 anIterator.Initialize(_doc->Main(), Standard_False);
382 while(i <= aLength) {
384 aToken = aPath.Token("/", i);
385 if(aToken.Length() == 0) break;
387 for ( ; anIterator.More(); anIterator.Next() ) {
388 aLabel = anIterator.Value();
389 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
390 if(anAttr->Get() == aToken) {
391 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
392 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
393 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (aLabel, _orb);
394 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
398 anIterator.Initialize(aLabel, Standard_False);
410 //============================================================================
411 /*! Function : GetObjectPath
414 //============================================================================
415 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
417 TCollection_AsciiString aPath("");
418 if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.ToCString());
420 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
421 if(anObject->_is_nil()) {
422 anObject = FindObjectIOR(_orb->object_to_string(theObject));
423 if(anObject->_is_nil()) return CORBA::string_dup(aPath.ToCString());
426 SALOMEDS::GenericAttribute_var anAttr;
427 if(anObject->FindAttribute(anAttr, "AttributeName")) {
428 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
429 if(anAttr->_is_nil()) return CORBA::string_dup(aPath.ToCString());
430 TCollection_AsciiString aValue(aName->Value());
434 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
435 if(!aFather->_is_nil()) {
437 Handle(TDataStd_Name) aNameAttrib;
438 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
439 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
440 aValue = GetObjectPath(aFather);
441 aPath = aValue + aPath;
446 return CORBA::string_dup(aPath.ToCString());
450 //============================================================================
451 /*! Function : SetContext
452 * Purpose : Sets the current context
454 //============================================================================
455 void SALOMEDS_Study_i::SetContext(const char* thePath)
457 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
458 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
459 bool isInvalid = false, isFound = false;
460 SALOMEDS::SObject_var aSO;
462 if(aPath.Value(1) != '/') { //Relative path
463 aContext = TCollection_AsciiString(GetContext());
471 aSO = FindObjectByPath(aContext.ToCString());
477 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
480 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
481 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
483 _current = aLabel; //Set the current context
487 //============================================================================
488 /*! Function : GetContext
489 * Purpose : Gets the current context
491 //============================================================================
492 char* SALOMEDS_Study_i::GetContext()
494 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
495 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_current, _orb);
496 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
497 return GetObjectPath(aSO._retn());
500 //============================================================================
501 /*! Function : GetObjectNames
502 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
504 //============================================================================
505 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
506 TColStd_SequenceOfExtendedString aResultSeq;
507 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
509 if (strlen(theContext) == 0) {
510 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
513 TDF_Label aTmp = _current;
514 SetContext(theContext);
518 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
519 for(; anIter.More(); anIter.Next()) {
520 TDF_Label aLabel = anIter.Value();
521 // Handle(TDF_Attribute) anAttribute;
522 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
523 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
524 Handle(TDataStd_Name) aName;
525 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
528 // fill the result table
529 int anIndex, aLength = aResultSeq.Length();
530 aResult->length(aLength);
531 for(anIndex = 0; anIndex < aLength; anIndex++) {
532 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
534 return aResult._retn();
537 //============================================================================
538 /*! Function : GetDirectoryNames
539 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
541 //============================================================================
542 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
543 TColStd_SequenceOfExtendedString aResultSeq;
544 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
546 if (strlen(theContext) == 0) {
547 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
550 TDF_Label aTmp = _current;
551 SetContext(theContext);
555 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
556 for(; anIter.More(); anIter.Next()) {
557 TDF_Label aLabel = anIter.Value();
558 Handle(SALOMEDS_LocalIDAttribute) anID;
559 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
560 if (anID->Get() == DIRECTORYID) {
561 Handle(TDataStd_Name) aName;
562 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
563 aResultSeq.Append(aName->Get());
568 // fill the result table
569 int anIndex, aLength = aResultSeq.Length();
570 aResult->length(aLength);
571 for(anIndex = 0; anIndex < aLength; anIndex++) {
572 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
574 return aResult._retn();
577 //============================================================================
578 /*! Function : GetFileNames
579 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
581 //============================================================================
582 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
583 TColStd_SequenceOfExtendedString aResultSeq;
584 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
586 if (strlen(theContext) == 0) {
587 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
590 TDF_Label aTmp = _current;
591 SetContext(theContext);
595 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
596 for(; anIter.More(); anIter.Next()) {
597 TDF_Label aLabel = anIter.Value();
598 Handle(SALOMEDS_LocalIDAttribute) anID;
599 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
600 if (anID->Get() == FILELOCALID) {
601 Handle(SALOMEDS_PersRefAttribute) aName;
602 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
603 TCollection_ExtendedString aFileName = aName->Get();
604 if(aFileName.Length() > 0)
605 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
611 // fill the result table
612 int anIndex, aLength = aResultSeq.Length();
613 aResult->length(aLength);
614 for(anIndex = 0; anIndex < aLength; anIndex++) {
615 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
617 return aResult._retn();
620 //============================================================================
621 /*! Function : GetComponentNames
622 * Purpose : method to get all components names
624 //============================================================================
625 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
626 TColStd_SequenceOfExtendedString aResultSeq;
627 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
628 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
629 for(; anIter.More(); anIter.Next()) {
630 TDF_Label aLabel = anIter.Value();
631 Handle(TDataStd_Name) aName;
632 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
634 // fill the result table
635 int anIndex, aLength = aResultSeq.Length();
636 aResult->length(aLength);
637 for(anIndex = 0; anIndex < aLength; anIndex++) {
638 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
640 return aResult._retn();
643 //============================================================================
644 /*! Function : NewChildIterator
645 * Purpose : Create a ChildIterator from an SObject
647 //============================================================================
648 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
650 //Convert aSO->GetID in TDF_Label.
652 TDF_Tool::Label(_doc->GetData(), strdup(aSO->GetID()), Lab);
655 SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(Lab,_orb);
656 SALOMEDS::ChildIterator_var it = SALOMEDS::ChildIterator::_narrow(it_servant->_this());
662 //============================================================================
663 /*! Function : NewComponentIterator
664 * Purpose : Create a SComponentIterator
666 //============================================================================
667 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
669 SALOMEDS_SComponentIterator_i* it_servant = new SALOMEDS_SComponentIterator_i(_doc,_orb);
670 SALOMEDS::SComponentIterator_var it = SALOMEDS::SComponentIterator::_narrow(it_servant->_this());
675 //============================================================================
676 /*! Function : NewBuilder
677 * Purpose : Create a StudyBuilder
679 //============================================================================
680 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
682 SALOMEDS_StudyBuilder_i* it_servant = new SALOMEDS_StudyBuilder_i(_doc,_orb);
683 SALOMEDS::StudyBuilder_var it = SALOMEDS::StudyBuilder::_narrow(it_servant->_this());
686 SALOMEDS_Callback_i* callback = new SALOMEDS_Callback_i(GetUseCaseBuilder(), _orb);
687 SALOMEDS::Callback_var cb = SALOMEDS::Callback::_narrow(callback->_this());
689 it->SetOnAddSObject(cb);
690 it->SetOnRemoveSObject(cb);
697 //============================================================================
699 * Purpose : get study name
701 //============================================================================
702 char* SALOMEDS_Study_i::Name()
704 return CORBA::string_dup(_name);
707 //============================================================================
709 * Purpose : set study name
711 //============================================================================
712 void SALOMEDS_Study_i::Name(const char* name)
714 _name = new char[strlen(name) +1];
718 //============================================================================
719 /*! Function : IsSaved
720 * Purpose : get if study has been saved
722 //============================================================================
723 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
728 //============================================================================
729 /*! Function : IsSaved
730 * Purpose : set if study has been saved
732 //============================================================================
733 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
738 //============================================================================
739 /*! Function : IsModified
740 * Purpose : Detect if a Study has been modified since it has been saved
742 //============================================================================
743 CORBA::Boolean SALOMEDS_Study_i::IsModified()
745 // True if is modified and not saved
746 if (_doc->IsModified())
747 if (!_isSaved) return true;
752 //============================================================================
754 * Purpose : get URL of the study (persistent reference of the study)
756 //============================================================================
757 char* SALOMEDS_Study_i::URL()
763 return CORBA::string_dup(_URL);
766 //============================================================================
768 * Purpose : set URL of the study (persistent reference of the study)
770 //============================================================================
771 void SALOMEDS_Study_i::URL(const char* url)
773 if (_URL) delete [] _URL;
774 _URL = new char[strlen(url) +1];
779 char *adr = strtok(aName, "/");
783 adr = strtok(NULL, "/");
790 //============================================================================
791 /*! Function : _FindObject
792 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
794 //============================================================================
795 SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
796 const char* anObjectName,
799 // Iterate on each objects and subobjects of the component
800 // If objectName find, stop the loop and get the object reference
801 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
803 CORBA::String_var soid = SO->GetID();
804 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
805 for (; it->More();it->Next()){
808 SALOMEDS::SObject_var CSO = it->Value();
809 SALOMEDS::GenericAttribute_var anAttr;
810 if (CSO->FindAttribute(anAttr,"AttributeName"))
812 SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
813 CORBA::String_var Val = Name->Value();
814 if (strcmp(Val, anObjectName) == 0)
816 RefSO = SALOMEDS::SObject::_narrow(CSO);
820 if (!_find) RefSO = _FindObject(CSO, anObjectName, _find);
826 //============================================================================
827 /*! Function : _FindObject
828 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
830 //============================================================================
831 SALOMEDS::SObject_ptr
832 SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
833 const char* anObjectIOR,
836 // Iterate on each objects and subobjects of the component
837 // If objectName find, stop the loop and get the object reference
838 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
840 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
841 for (; it->More();it->Next()){
844 SALOMEDS::SObject_var CSO = it->Value();
845 SALOMEDS::GenericAttribute_var anAttr;
846 if (CSO->FindAttribute(anAttr,"AttributeIOR"))
848 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
849 CORBA::String_var Val = IOR->Value();
850 if (strcmp(Val, anObjectIOR) == 0)
852 RefSO = SALOMEDS::SObject::_narrow(CSO);
856 if (!_find) RefSO = _FindObjectIOR(CSO, anObjectIOR, _find);
862 CORBA::Short SALOMEDS_Study_i::StudyId()
867 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
872 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
874 CORBA::String_var anEn = CORBA::string_dup(anEntry);
875 CORBA::String_var IOR = CORBA::string_dup(anIOR);
876 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
877 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
878 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
881 SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const TDF_Label theLabel, CORBA::ORB_ptr orb) {
882 Handle(SALOMEDS_IORAttribute) Att;
883 if (theLabel.Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
884 char* IOR = CORBA::string_dup(TCollection_AsciiString(Att->Get()).ToCString());
885 CORBA::Object_var obj = orb->string_to_object(IOR);
886 SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
887 ASSERT(!CORBA::is_nil(aStudy));
888 return SALOMEDS::Study::_duplicate(aStudy);
890 INFOS("GetStudy: Problem to get study");
892 return SALOMEDS::Study::_nil();
895 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
896 TCollection_AsciiString aString;
897 TDF_Tool::Entry(theAttribute->Label(), aString);
898 GetStudy(theAttribute->Label(), orb)->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(),
899 aString.ToCString());
902 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
903 SALOMEDS::GenericAttribute_ptr aTarget;
904 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
905 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
907 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
913 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
914 SALOMEDS::GenericAttribute_ptr anAttr = NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
915 "AttributeStudyProperties");
916 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
919 char* SALOMEDS_Study_i::GetLastModificationDate() {
920 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
921 SALOMEDS::StringSeq_var aNames;
922 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
923 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
924 int aLastIndex = aNames->length() - 1;
926 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
927 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
928 CORBA::String_var aResStr = CORBA::string_dup(aResult);
929 return aResStr._retn();
932 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
933 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
934 SALOMEDS::StringSeq_var aNames;
935 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
936 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
938 int anIndex, aLength = aNames->length();
939 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
940 aDates->length(aLength);
942 for(anIndex = 0; anIndex < aLength; anIndex++) {
944 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
945 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
946 aDates[anIndex] = CORBA::string_dup(aDate);
948 return aDates._retn();
953 //============================================================================
954 /*! Function : GetUseCaseBuilder
955 * Purpose : Returns a UseCase builder
957 //============================================================================
958 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
960 SALOMEDS_UseCaseBuilder_i* _caseBuilder = new SALOMEDS_UseCaseBuilder_i(_doc, _orb);
961 SALOMEDS::UseCaseBuilder_var aBuilder = SALOMEDS::UseCaseBuilder::_narrow(_caseBuilder->_this());
962 return aBuilder._retn();
966 //============================================================================
970 //============================================================================
971 void SALOMEDS_Study_i::Close()
973 SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
975 for (; itcomponent->More(); itcomponent->Next()) {
976 SALOMEDS::SComponent_var sco = itcomponent->Value();
978 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
979 // if there is an associated Engine call its method for closing
980 CORBA::String_var IOREngine;
981 if (sco->ComponentIOR(IOREngine)) {
982 // we have found the associated engine to write the data
983 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
984 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
985 if (!CORBA::is_nil(obj)) {
986 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
988 if (!anEngine->_is_nil())
989 anEngine->Close(sco);
994 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
995 // Handle(TDocStd_Owner) anOwner;
996 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
997 // Handle(TDocStd_Document) anEmptyDoc;
998 // anOwner->SetDocument(anEmptyDoc);
1000 if(!anApp.IsNull()) anApp->Close(_doc);
1004 //============================================================================
1005 /*! Function : AddPostponed
1008 //============================================================================
1009 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1010 if (!NewBuilder()->HasOpenCommand()) return;
1012 CORBA::Object_var obj = _orb->string_to_object(theIOR);
1013 if (!CORBA::is_nil(obj)) {
1014 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1015 if (!CORBA::is_nil(aGeneric)) {
1016 TCollection_AsciiString anIOR(strdup(theIOR));
1018 myPostponedIORs.Append(anIOR); // add prefix: deleted
1019 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1025 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1026 if (!NewBuilder()->HasOpenCommand()) return;
1028 CORBA::Object_var obj = _orb->string_to_object(theIOR);
1029 if (!CORBA::is_nil(obj)) {
1030 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1031 if (!CORBA::is_nil(aGeneric)) {
1032 TCollection_AsciiString anIOR(strdup(theIOR));
1034 myPostponedIORs.Append(anIOR); // add prefix: created
1035 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1041 //============================================================================
1042 /*! Function : RemovePostponed
1045 //============================================================================
1046 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1050 int aUndoLimit = theUndoLimit;
1051 if (theUndoLimit < 0) aUndoLimit = 0;
1053 if (myNbUndos > 0) { // remove undone
1055 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1056 anOld += myNbPostponed(anIndex);
1057 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1059 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1060 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1061 if (anIOR.Value(1) == 'c') {
1062 CORBA::Object_var obj = _orb->string_to_object(strdup(anIOR.Split(1).ToCString()));
1063 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1064 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1067 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1068 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1073 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1075 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1076 anOld += myNbPostponed(anIndex);
1077 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1078 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1079 if (anIOR.Value(1) == 'd') {
1080 CORBA::Object_var obj = _orb->string_to_object(strdup(anIOR.Split(1).ToCString()));
1081 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1082 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1085 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1086 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1089 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1090 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1091 for(; anIter.More(); anIter.Next()) {
1092 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1093 CORBA::String_var anIOR = strdup(TCollection_AsciiString(anAttr->Get()).ToCString());
1095 CORBA::Object_var obj = _orb->string_to_object(anIOR);
1096 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1097 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1100 } else myNbPostponed.Append(0);
1103 //============================================================================
1104 /*! Function : UndoPostponed
1107 //============================================================================
1108 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1109 myNbUndos += theWay;
1110 // remove current postponed
1111 if (myNbPostponed.Last() > 0)
1112 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1113 myNbPostponed(myNbPostponed.Length()) = 0;