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(), (char*)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 : CreateObjectID
240 * Purpose : Creates an Object with ID = anObjectID
242 //============================================================================
243 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
245 // Convert aSO->GetID in TDF_Label.
247 TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
249 if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
250 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (Lab,_orb);
251 SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this());
256 //============================================================================
257 /*! Function : FindObjectByName
258 * Purpose : Find Objects with SALOMEDS::Name = anObjectName in a Component
259 * : with ComponentDataType = aComponentName
261 //============================================================================
262 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
263 const char* aComponentName )
265 SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
268 SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
269 if ( compo->_is_nil() ) {
270 MESSAGE ("In FindObjectByName() : Component named " << aComponentName << " not found ");
271 return listSO._retn();
274 // Iterate on each object and subobject of the component
275 // If objectName is found add it to the list of SObjects
278 SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
280 CORBA::String_var compoId = compo->GetID();
281 SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
283 for ( ; it->More();it->Next() ) {
285 SALOMEDS::SObject_var CSO = it->Value();
286 SALOMEDS::GenericAttribute_var anAttr;
287 SALOMEDS::AttributeName_var aName;
288 if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
289 aName = SALOMEDS::AttributeName::_narrow(anAttr);
290 name = aName->Value();
291 if ( strcmp( name, anObjectName ) == 0) {
292 addSO = SALOMEDS::SObject::_narrow(CSO);
295 listSO->length(length);
296 listSO[length-1] = addSO ;
299 /* looks also for eventual children */
301 addSO = _FindObject( CSO, anObjectName, found ) ;
304 listSO->length(length);
305 listSO[length-1] = addSO ;
309 return listSO._retn() ;
314 //============================================================================
315 /*! Function : FindObjectIOR
316 * Purpose : Find an Object with IOR = anObjectIOR
318 //============================================================================
319 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
321 // firstly searching in the datamap for optimization
322 CORBA::String_var anIOR = CORBA::string_dup(anObjectIOR);
323 if (myIORLabels.IsBound(TCollection_ExtendedString(anIOR))) {
324 SALOMEDS_SObject_i* aResult = new SALOMEDS_SObject_i(myIORLabels.Find(TCollection_ExtendedString(anIOR)),_orb);
325 // 11 oct 2002: forbidden attributes must be checked here
326 SALOMEDS::GenericAttribute_var anAttr;
327 if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
328 myIORLabels.UnBind(TCollection_ExtendedString(anIOR));
329 } else return aResult->_this();
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)
335 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
337 SALOMEDS::SComponentIterator_var it = NewComponentIterator();
338 for (; it->More();it->Next()){
341 SALOMEDS::SComponent_var SC = it->Value();
342 SALOMEDS::GenericAttribute_var anAttr;
343 if (SC->FindAttribute(anAttr,"AttributeIOR"))
345 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
346 CORBA::String_var Val = IOR->Value();
347 if (strcmp(Val, anObjectIOR) == 0)
350 RefSO = SALOMEDS::SObject::_narrow(SC);
354 RefSO = _FindObjectIOR(SC,anObjectIOR, _find);
357 if (!RefSO->_is_nil()) MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
362 //============================================================================
363 /*! Function : FindObjectByPath
364 * Purpose : Find an Object by its path = thePath
366 //============================================================================
367 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
369 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
370 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
371 int i = 1, aLength = aPath.Length();
372 bool isRelative = false;
374 if(aLength == 0) { //Empty path - return the current context
375 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_current, _orb);
376 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
380 if(aPath.Value(1) != '/') //Relative path
383 TDF_ChildIterator anIterator;
385 Handle(TDataStd_Name) anAttr;
388 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
389 anIterator.Initialize(_current, Standard_False);
392 if(aPath.Length() == 1 && aPath.Value(1) == '/') { //Root
393 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_doc->Main(), _orb);
394 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
397 anIterator.Initialize(_doc->Main(), Standard_False);
400 while(i <= aLength) {
402 aToken = aPath.Token("/", i);
403 if(aToken.Length() == 0) break;
405 for ( ; anIterator.More(); anIterator.Next() ) {
406 aLabel = anIterator.Value();
407 if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
408 if(anAttr->Get() == aToken) {
409 aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
410 if(aToken.Length() == 0) { //The searched label is found (no part of the path is left)
411 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (aLabel, _orb);
412 aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
416 anIterator.Initialize(aLabel, Standard_False);
428 //============================================================================
429 /*! Function : GetObjectPath
432 //============================================================================
433 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
435 TCollection_AsciiString aPath("");
436 if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.ToCString());
438 SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
439 if(anObject->_is_nil()) {
440 anObject = FindObjectIOR(_orb->object_to_string(theObject));
441 if(anObject->_is_nil()) return CORBA::string_dup(aPath.ToCString());
444 SALOMEDS::GenericAttribute_var anAttr;
445 if(anObject->FindAttribute(anAttr, "AttributeName")) {
446 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
447 if(anAttr->_is_nil()) return CORBA::string_dup(aPath.ToCString());
448 TCollection_AsciiString aValue(aName->Value());
452 SALOMEDS::SObject_ptr aFather = anObject->GetFather();
453 if(!aFather->_is_nil()) {
455 Handle(TDataStd_Name) aNameAttrib;
456 TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
457 if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
458 aValue = GetObjectPath(aFather);
459 aPath = aValue + aPath;
464 return CORBA::string_dup(aPath.ToCString());
468 //============================================================================
469 /*! Function : SetContext
470 * Purpose : Sets the current context
472 //============================================================================
473 void SALOMEDS_Study_i::SetContext(const char* thePath)
475 if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
476 TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
477 bool isInvalid = false, isFound = false;
478 SALOMEDS::SObject_var aSO;
480 if(aPath.Value(1) != '/') { //Relative path
481 aContext = TCollection_AsciiString(GetContext());
489 aSO = FindObjectByPath(aContext.ToCString());
495 if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
498 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
499 if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
501 _current = aLabel; //Set the current context
505 //============================================================================
506 /*! Function : GetContext
507 * Purpose : Gets the current context
509 //============================================================================
510 char* SALOMEDS_Study_i::GetContext()
512 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
513 SALOMEDS_SObject_i * so_servant = new SALOMEDS_SObject_i (_current, _orb);
514 SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
515 return GetObjectPath(aSO._retn());
518 //============================================================================
519 /*! Function : GetObjectNames
520 * Purpose : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
522 //============================================================================
523 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
524 TColStd_SequenceOfExtendedString aResultSeq;
525 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
527 if (strlen(theContext) == 0) {
528 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
531 TDF_Label aTmp = _current;
532 SetContext(theContext);
536 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
537 for(; anIter.More(); anIter.Next()) {
538 TDF_Label aLabel = anIter.Value();
539 // Handle(TDF_Attribute) anAttribute;
540 // if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
541 // aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
542 Handle(TDataStd_Name) aName;
543 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
546 // fill the result table
547 int anIndex, aLength = aResultSeq.Length();
548 aResult->length(aLength);
549 for(anIndex = 0; anIndex < aLength; anIndex++) {
550 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
552 return aResult._retn();
555 //============================================================================
556 /*! Function : GetDirectoryNames
557 * Purpose : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
559 //============================================================================
560 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
561 TColStd_SequenceOfExtendedString aResultSeq;
562 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
564 if (strlen(theContext) == 0) {
565 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
568 TDF_Label aTmp = _current;
569 SetContext(theContext);
573 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
574 for(; anIter.More(); anIter.Next()) {
575 TDF_Label aLabel = anIter.Value();
576 Handle(SALOMEDS_LocalIDAttribute) anID;
577 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
578 if (anID->Get() == DIRECTORYID) {
579 Handle(TDataStd_Name) aName;
580 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
581 aResultSeq.Append(aName->Get());
586 // fill the result table
587 int anIndex, aLength = aResultSeq.Length();
588 aResult->length(aLength);
589 for(anIndex = 0; anIndex < aLength; anIndex++) {
590 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
592 return aResult._retn();
595 //============================================================================
596 /*! Function : GetFileNames
597 * Purpose : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
599 //============================================================================
600 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
601 TColStd_SequenceOfExtendedString aResultSeq;
602 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
604 if (strlen(theContext) == 0) {
605 if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
608 TDF_Label aTmp = _current;
609 SetContext(theContext);
613 TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
614 for(; anIter.More(); anIter.Next()) {
615 TDF_Label aLabel = anIter.Value();
616 Handle(SALOMEDS_LocalIDAttribute) anID;
617 if (aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anID)) {
618 if (anID->Get() == FILELOCALID) {
619 Handle(SALOMEDS_PersRefAttribute) aName;
620 if(aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
621 TCollection_ExtendedString aFileName = aName->Get();
622 if(aFileName.Length() > 0)
623 aResultSeq.Append(aFileName.Split(strlen(FILEID)));
629 // fill the result table
630 int anIndex, aLength = aResultSeq.Length();
631 aResult->length(aLength);
632 for(anIndex = 0; anIndex < aLength; anIndex++) {
633 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
635 return aResult._retn();
638 //============================================================================
639 /*! Function : GetComponentNames
640 * Purpose : method to get all components names
642 //============================================================================
643 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
644 TColStd_SequenceOfExtendedString aResultSeq;
645 SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
646 TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
647 for(; anIter.More(); anIter.Next()) {
648 TDF_Label aLabel = anIter.Value();
649 Handle(TDataStd_Name) aName;
650 if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
652 // fill the result table
653 int anIndex, aLength = aResultSeq.Length();
654 aResult->length(aLength);
655 for(anIndex = 0; anIndex < aLength; anIndex++) {
656 aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
658 return aResult._retn();
661 //============================================================================
662 /*! Function : NewChildIterator
663 * Purpose : Create a ChildIterator from an SObject
665 //============================================================================
666 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
668 //Convert aSO->GetID in TDF_Label.
670 TDF_Tool::Label(_doc->GetData(), aSO->GetID(), Lab);
673 SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(Lab,_orb);
674 SALOMEDS::ChildIterator_var it = SALOMEDS::ChildIterator::_narrow(it_servant->_this());
680 //============================================================================
681 /*! Function : NewComponentIterator
682 * Purpose : Create a SComponentIterator
684 //============================================================================
685 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
687 SALOMEDS_SComponentIterator_i* it_servant = new SALOMEDS_SComponentIterator_i(_doc,_orb);
688 SALOMEDS::SComponentIterator_var it = SALOMEDS::SComponentIterator::_narrow(it_servant->_this());
693 //============================================================================
694 /*! Function : NewBuilder
695 * Purpose : Create a StudyBuilder
697 //============================================================================
698 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
700 SALOMEDS_StudyBuilder_i* it_servant = new SALOMEDS_StudyBuilder_i(_doc,_orb);
701 SALOMEDS::StudyBuilder_var it = SALOMEDS::StudyBuilder::_narrow(it_servant->_this());
704 SALOMEDS_Callback_i* callback = new SALOMEDS_Callback_i(GetUseCaseBuilder(), _orb);
705 SALOMEDS::Callback_var cb = SALOMEDS::Callback::_narrow(callback->_this());
707 it->SetOnAddSObject(cb);
708 it->SetOnRemoveSObject(cb);
715 //============================================================================
717 * Purpose : get study name
719 //============================================================================
720 char* SALOMEDS_Study_i::Name()
722 return CORBA::string_dup(_name);
725 //============================================================================
727 * Purpose : set study name
729 //============================================================================
730 void SALOMEDS_Study_i::Name(const char* name)
732 _name = new char[strlen(name) +1];
736 //============================================================================
737 /*! Function : IsSaved
738 * Purpose : get if study has been saved
740 //============================================================================
741 CORBA::Boolean SALOMEDS_Study_i::IsSaved()
746 //============================================================================
747 /*! Function : IsSaved
748 * Purpose : set if study has been saved
750 //============================================================================
751 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
756 //============================================================================
757 /*! Function : IsModified
758 * Purpose : Detect if a Study has been modified since it has been saved
760 //============================================================================
761 CORBA::Boolean SALOMEDS_Study_i::IsModified()
763 // True if is modified and not saved
764 if (_doc->IsModified())
765 if (!_isSaved) return true;
770 //============================================================================
772 * Purpose : get URL of the study (persistent reference of the study)
774 //============================================================================
775 char* SALOMEDS_Study_i::URL()
781 return CORBA::string_dup(_URL);
784 //============================================================================
786 * Purpose : set URL of the study (persistent reference of the study)
788 //============================================================================
789 void SALOMEDS_Study_i::URL(const char* url)
791 if (_URL) delete [] _URL;
792 _URL = new char[strlen(url) +1];
797 char *adr = strtok(aName, "/");
801 adr = strtok(NULL, "/");
808 //============================================================================
809 /*! Function : _FindObject
810 * Purpose : Find an Object with SALOMEDS::Name = anObjectName
812 //============================================================================
813 SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
814 const char* anObjectName,
817 // Iterate on each objects and subobjects of the component
818 // If objectName find, stop the loop and get the object reference
819 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
821 CORBA::String_var soid = SO->GetID();
822 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
823 for (; it->More();it->Next()){
826 SALOMEDS::SObject_var CSO = it->Value();
827 SALOMEDS::GenericAttribute_var anAttr;
828 if (CSO->FindAttribute(anAttr,"AttributeName"))
830 SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
831 CORBA::String_var Val = Name->Value();
832 if (strcmp(Val, anObjectName) == 0)
834 RefSO = SALOMEDS::SObject::_narrow(CSO);
838 if (!_find) RefSO = _FindObject(CSO, anObjectName, _find);
844 //============================================================================
845 /*! Function : _FindObject
846 * Purpose : Find an Object with SALOMEDS::IOR = anObjectIOR
848 //============================================================================
849 SALOMEDS::SObject_ptr
850 SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
851 const char* anObjectIOR,
854 // Iterate on each objects and subobjects of the component
855 // If objectName find, stop the loop and get the object reference
856 SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
858 SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
859 for (; it->More();it->Next()){
862 SALOMEDS::SObject_var CSO = it->Value();
863 SALOMEDS::GenericAttribute_var anAttr;
864 if (CSO->FindAttribute(anAttr,"AttributeIOR"))
866 SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
867 CORBA::String_var Val = IOR->Value();
868 if (strcmp(Val, anObjectIOR) == 0)
870 RefSO = SALOMEDS::SObject::_narrow(CSO);
874 if (!_find) RefSO = _FindObjectIOR(CSO, anObjectIOR, _find);
880 CORBA::Short SALOMEDS_Study_i::StudyId()
885 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
890 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
892 CORBA::String_var anEn = CORBA::string_dup(anEntry);
893 CORBA::String_var IOR = CORBA::string_dup(anIOR);
894 TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
895 if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
896 myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
899 SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const TDF_Label theLabel, CORBA::ORB_ptr orb) {
900 Handle(SALOMEDS_IORAttribute) Att;
901 if (theLabel.Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
902 char* IOR = CORBA::string_dup(TCollection_AsciiString(Att->Get()).ToCString());
903 CORBA::Object_var obj = orb->string_to_object(IOR);
904 SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
905 ASSERT(!CORBA::is_nil(aStudy));
906 return SALOMEDS::Study::_duplicate(aStudy);
908 MESSAGE("GetStudy: Problem to get study");
910 return SALOMEDS::Study::_nil();
913 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
914 TCollection_AsciiString aString;
915 TDF_Tool::Entry(theAttribute->Label(), aString);
916 GetStudy(theAttribute->Label(), orb)->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(),
917 aString.ToCString());
920 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
921 SALOMEDS::GenericAttribute_ptr aTarget;
922 if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
923 return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
925 SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
931 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
932 SALOMEDS::GenericAttribute_ptr anAttr = NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
933 "AttributeStudyProperties");
934 return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
937 char* SALOMEDS_Study_i::GetLastModificationDate() {
938 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
939 SALOMEDS::StringSeq_var aNames;
940 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
941 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
942 int aLastIndex = aNames->length() - 1;
944 sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
945 (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
946 CORBA::String_var aResStr = CORBA::string_dup(aResult);
947 return aResStr._retn();
950 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
951 SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
952 SALOMEDS::StringSeq_var aNames;
953 SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
954 aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
956 int anIndex, aLength = aNames->length();
957 SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
958 aDates->length(aLength);
960 for(anIndex = 0; anIndex < aLength; anIndex++) {
962 sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
963 (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
964 aDates[anIndex] = CORBA::string_dup(aDate);
966 return aDates._retn();
971 //============================================================================
972 /*! Function : GetUseCaseBuilder
973 * Purpose : Returns a UseCase builder
975 //============================================================================
976 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
978 SALOMEDS_UseCaseBuilder_i* _caseBuilder = new SALOMEDS_UseCaseBuilder_i(_doc, _orb);
979 SALOMEDS::UseCaseBuilder_var aBuilder = SALOMEDS::UseCaseBuilder::_narrow(_caseBuilder->_this());
980 return aBuilder._retn();
984 //============================================================================
988 //============================================================================
989 void SALOMEDS_Study_i::Close()
991 SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
993 for (; itcomponent->More(); itcomponent->Next()) {
994 SALOMEDS::SComponent_var sco = itcomponent->Value();
996 MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
997 // if there is an associated Engine call its method for closing
998 CORBA::String_var IOREngine;
999 if (sco->ComponentIOR(IOREngine)) {
1000 // we have found the associated engine to write the data
1001 MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
1002 CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1003 if (!CORBA::is_nil(obj)) {
1004 SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
1006 if (!anEngine->_is_nil())
1007 anEngine->Close(sco);
1012 Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
1013 // Handle(TDocStd_Owner) anOwner;
1014 // if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1015 // Handle(TDocStd_Document) anEmptyDoc;
1016 // anOwner->SetDocument(anEmptyDoc);
1018 if(!anApp.IsNull()) anApp->Close(_doc);
1022 //============================================================================
1023 /*! Function : AddPostponed
1026 //============================================================================
1027 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
1028 if (!NewBuilder()->HasOpenCommand()) return;
1030 CORBA::Object_var obj = _orb->string_to_object(theIOR);
1031 if (!CORBA::is_nil(obj)) {
1032 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1033 if (!CORBA::is_nil(aGeneric)) {
1034 TCollection_AsciiString anIOR((char*)theIOR);
1036 myPostponedIORs.Append(anIOR); // add prefix: deleted
1037 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1043 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
1044 if (!NewBuilder()->HasOpenCommand()) return;
1046 CORBA::Object_var obj = _orb->string_to_object(theIOR);
1047 if (!CORBA::is_nil(obj)) {
1048 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
1049 if (!CORBA::is_nil(aGeneric)) {
1050 TCollection_AsciiString anIOR((char*)theIOR);
1052 myPostponedIORs.Append(anIOR); // add prefix: created
1053 myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
1059 //============================================================================
1060 /*! Function : RemovePostponed
1063 //============================================================================
1064 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
1068 int aUndoLimit = theUndoLimit;
1069 if (theUndoLimit < 0) aUndoLimit = 0;
1071 if (myNbUndos > 0) { // remove undone
1073 for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
1074 anOld += myNbPostponed(anIndex);
1075 int aNew = myPostponedIORs.Length() - myNbPostponed.Last();
1077 for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
1078 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1079 if (anIOR.Value(1) == 'c') {
1080 CORBA::Object_var obj = _orb->string_to_object(anIOR.Split(1).ToCString());
1081 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1082 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1085 if (anOld < aNew) myPostponedIORs.Remove(anOld + 1, aNew);
1086 if (myNbPostponed.Length() > 0) myNbPostponed.Remove(myNbPostponed.Length() - myNbUndos, myNbPostponed.Length() - 1);
1091 if (myNbPostponed.Length() > aUndoLimit) { // remove objects, that can not be undone
1093 for(anIndex = myNbPostponed.Length() - aUndoLimit; anIndex >= 1; anIndex--)
1094 anOld += myNbPostponed(anIndex);
1095 for(anIndex = 1; anIndex <= anOld; anIndex++) {
1096 TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
1097 if (anIOR.Value(1) == 'd') {
1098 CORBA::Object_var obj = _orb->string_to_object(anIOR.Split(1).ToCString());
1099 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1100 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1103 if (anOld > 0) myPostponedIORs.Remove(1, anOld);
1104 myNbPostponed.Remove(1, myNbPostponed.Length() - aUndoLimit);
1107 if (theUndoLimit == -1) { // remove all IORs from the study on the study close
1108 TDF_ChildIDIterator anIter(_doc->GetData()->Root(), SALOMEDS_IORAttribute::GetID(), Standard_True);
1109 for(; anIter.More(); anIter.Next()) {
1110 Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
1111 CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
1113 CORBA::Object_var obj = _orb->string_to_object(anIOR);
1114 SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
1115 if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
1118 } else myNbPostponed.Append(0);
1121 //============================================================================
1122 /*! Function : UndoPostponed
1125 //============================================================================
1126 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) {
1127 myNbUndos += theWay;
1128 // remove current postponed
1129 if (myNbPostponed.Last() > 0)
1130 myPostponedIORs.Remove(myPostponedIORs.Length() - myNbPostponed.Last() + 1, myPostponedIORs.Length());
1131 myNbPostponed(myNbPostponed.Length()) = 0;