From: vsr Date: Tue, 16 Oct 2012 08:17:12 +0000 (+0000) Subject: 0021478: EDF 2083 ALL: Write the version of Salome used to create the study in the... X-Git-Tag: V6_6_0a1~10 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=bb6c96f565ce47fbf3e4ddc1127b287cabe2006c;p=modules%2Fkernel.git 0021478: EDF 2083 ALL: Write the version of Salome used to create the study in the hdf file --- diff --git a/idl/SALOMEDS_Attributes.idl b/idl/SALOMEDS_Attributes.idl index fbc70d655..9941794cb 100644 --- a/idl/SALOMEDS_Attributes.idl +++ b/idl/SALOMEDS_Attributes.idl @@ -1650,6 +1650,27 @@ module SALOMEDS \return units */ string GetUnits(); + + /*! + \brief Returns list of components which data was stored + (after previous sessions) in the study. + \return list of component names + */ + StringSeq GetStoredComponents(); + + /*! + \brief Returns version of component data stored in the study + \param comp component name + \return version of stored component data + */ + string GetComponentVersion( in string comp ); + + /*! + \brief Returns all versions of component data stored in the study + \param comp component name + \return versions of stored component data + */ + StringSeq GetComponentVersions( in string comp ); }; //========================================================================== diff --git a/idl/SALOME_Component.idl b/idl/SALOME_Component.idl index 9d55e154b..4a1701ddf 100644 --- a/idl/SALOME_Component.idl +++ b/idl/SALOME_Component.idl @@ -453,6 +453,17 @@ module Engines \return an information about the given object. */ string getObjectInfo(in long studyId, in string entry); + + //! Get version of the component + /*! + This method is supposed to be implemented in all derived classes; default implementation + returns "unknown" string that means that no version information about the component is available. + \note The version of the component is stored to the study, as a part of general persistence + mechanism; once stored, version information in the study cannot be changed. + + \return string containing component's version, e.g. "1.0" + */ + string getVersion(); } ; /*! diff --git a/src/Container/Component_i.cxx b/src/Container/Component_i.cxx index 3e77256aa..ed5b16b6d 100644 --- a/src/Container/Component_i.cxx +++ b/src/Container/Component_i.cxx @@ -1105,3 +1105,20 @@ void Engines_Component_i::setContainerName() name[slash]='_'; _containerName=name; } + +//============================================================================= +/*! + \brief Get version of the component + + This method is supposed to be implemented in all derived classes; default implementation + returns empty string that means that no version information about the component is available. + + \note The version of the component is stored to the study, as a part of general persistence + mechanism; once stored, version information in the study cannot be changed. + + \return string containing component's version, e.g. "1.0" +*/ +char* Engines_Component_i::getVersion() +{ + return CORBA::string_dup( "" ); +} diff --git a/src/Container/SALOME_ComponentPy.py b/src/Container/SALOME_ComponentPy.py index 55ec0ff55..66c9de634 100755 --- a/src/Container/SALOME_ComponentPy.py +++ b/src/Container/SALOME_ComponentPy.py @@ -314,3 +314,9 @@ class SALOME_ComponentPy_i (Engines__POA.EngineComponent): def getObjectInfo(self, studyId, entry): return "" + #------------------------------------------------------------------------- + + def getVersion(self): + return "" # empty string means "unknown" version + + pass # end of SALOME_ComponentPy_i diff --git a/src/Container/SALOME_Component_i.hxx b/src/Container/SALOME_Component_i.hxx index 94fd62ce8..3581cd9d2 100644 --- a/src/Container/SALOME_Component_i.hxx +++ b/src/Container/SALOME_Component_i.hxx @@ -120,6 +120,9 @@ public: virtual bool hasObjectInfo() { return false; } virtual char* getObjectInfo(CORBA::Long studyId, const char* entry) { return CORBA::string_dup(""); } + // Version information + virtual char* getVersion(); + // --- local C++ methods PortableServer::ObjectId * getId(); diff --git a/src/KERNEL_PY/salome_study.py b/src/KERNEL_PY/salome_study.py index 5de40bc3a..f6ebc622a 100644 --- a/src/KERNEL_PY/salome_study.py +++ b/src/KERNEL_PY/salome_study.py @@ -227,6 +227,27 @@ def CheckCopyPaste(theSO, theInfo ,theComponentPaste): #-------------------------------------------------------------------------- +def GetComponentVersion(theComponent, all_versions = False): + # returns the document list tree (as list) + props = myStudy.GetProperties() + stored_components = props.GetStoredComponents() + version = "no component data" # vsr: better raise an exception in this case? + if theComponent in stored_components: + if all_versions: + version = props.GetComponentVersions(theComponent) + for i in range(len(version)): + if not version[i]: version[i] = "unknown" + pass + pass + else: + version = props.GetComponentVersion(theComponent) + if not version: version = "unknown" + pass + pass + return version + + #-------------------------------------------------------------------------- + def FindFileInDataDir(filename): import os datadir = os.getenv("DATA_DIR") diff --git a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.cxx b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.cxx index af20553fa..bdb5760d7 100644 --- a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.cxx +++ b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.cxx @@ -319,3 +319,49 @@ std::string SALOMEDS_AttributeStudyProperties::GetUnits() anUnits = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetUnits(); return anUnits; } + +std::vector SALOMEDS_AttributeStudyProperties::GetStoredComponents() +{ + std::vector aComponents; + if (_isLocal) { + SALOMEDS::Locker lock; + aComponents = dynamic_cast(_local_impl)->GetStoredComponents(); + } + else { + SALOMEDS::StringSeq_var components = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetStoredComponents(); + int length = components->length(); + for (int i = 0; i < length; i++) { + aComponents.push_back(components[i].in()); + } + } + return aComponents; +} + +std::string SALOMEDS_AttributeStudyProperties::GetComponentVersion( const std::string& theComponent ) +{ + std::string aVersion; + if (_isLocal) { + SALOMEDS::Locker lock; + aVersion = dynamic_cast(_local_impl)->GetComponentVersion(theComponent); + } + else + aVersion = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetComponentVersion(theComponent.c_str()); + return aVersion; +} + +std::vector SALOMEDS_AttributeStudyProperties::GetComponentVersions( const std::string& theComponent ) +{ + std::vector aVersions; + if (_isLocal) { + SALOMEDS::Locker lock; + aVersions = dynamic_cast(_local_impl)->GetComponentVersions(theComponent); + } + else { + SALOMEDS::StringSeq_var versions = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetComponentVersions(theComponent.c_str()); + int length = versions->length(); + for (int i = 0; i < length; i++) { + aVersions.push_back(versions[i].in()); + } + } + return aVersions; +} diff --git a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.hxx b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.hxx index 4ebd180bd..b02e0fbff 100644 --- a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.hxx +++ b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties.hxx @@ -82,7 +82,9 @@ public: virtual void SetComment(const std::string& theComment); virtual std::string GetComment(); - + virtual std::vector GetStoredComponents(); + virtual std::string GetComponentVersion( const std::string& theComponent ); + virtual std::vector GetComponentVersions( const std::string& theComponent ); }; diff --git a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.cxx b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.cxx index a6bd88294..3c02784de 100644 --- a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.cxx +++ b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.cxx @@ -218,3 +218,34 @@ char* SALOMEDS_AttributeStudyProperties_i::GetUnits() return c_s._retn(); } +SALOMEDS::StringSeq* SALOMEDS_AttributeStudyProperties_i::GetStoredComponents() +{ + SALOMEDS::Locker lock; + std::vector components = dynamic_cast(_impl)->GetStoredComponents(); + SALOMEDS::StringSeq_var c_components = new SALOMEDS::StringSeq(); + c_components->length(components.size()); + for (int i = 0; i < components.size(); i++) { + c_components[i] = CORBA::string_dup(components[i].c_str()); + } + return c_components._retn(); +} + +char* SALOMEDS_AttributeStudyProperties_i::GetComponentVersion(const char* theComponent) +{ + SALOMEDS::Locker lock; + std::string version = dynamic_cast(_impl)->GetComponentVersion(theComponent); + CORBA::String_var c_version = CORBA::string_dup(version.c_str()); + return c_version._retn(); +} + +SALOMEDS::StringSeq* SALOMEDS_AttributeStudyProperties_i::GetComponentVersions(const char* theComponent) +{ + SALOMEDS::Locker lock; + std::vector versions = dynamic_cast(_impl)->GetComponentVersions(theComponent); + SALOMEDS::StringSeq_var c_versions = new SALOMEDS::StringSeq(); + c_versions->length(versions.size()); + for (int i = 0; i < versions.size(); i++) { + c_versions[i] = CORBA::string_dup(versions[i].c_str()); + } + return c_versions._retn(); +} diff --git a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.hxx b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.hxx index 7c6198ee1..ead14d9e8 100644 --- a/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.hxx +++ b/src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.hxx @@ -73,6 +73,10 @@ public: virtual void SetUnits(const char* theUnits); virtual char* GetUnits(); + + virtual SALOMEDS::StringSeq* GetStoredComponents(); + virtual char* GetComponentVersion(const char* theComponent); + virtual SALOMEDS::StringSeq* GetComponentVersions(const char* theComponent); }; diff --git a/src/SALOMEDS/SALOMEDS_Driver_i.cxx b/src/SALOMEDS/SALOMEDS_Driver_i.cxx index 87bdec277..ae2db2077 100644 --- a/src/SALOMEDS/SALOMEDS_Driver_i.cxx +++ b/src/SALOMEDS/SALOMEDS_Driver_i.cxx @@ -29,9 +29,21 @@ #include "SALOMEDS.hxx" #include -SALOMEDS_Driver_i::SALOMEDS_Driver_i(SALOMEDS::Driver_ptr theDriver, CORBA::ORB_ptr theORB) +SALOMEDS_Driver_i::SALOMEDS_Driver_i(Engines::EngineComponent_ptr theEngine, CORBA::ORB_ptr theORB) { + // engine should not be null - component is supposed to be inherited from Engines::EngineComponent + _engine = Engines::EngineComponent::_duplicate(theEngine); + // driver can be null - if component interface does not inherit SALOMEDS::Driver + _driver = SALOMEDS::Driver::_narrow(theEngine); + _orb = CORBA::ORB::_duplicate(theORB); +} + +SALOMEDS_Driver_i::SALOMEDS_Driver_i(SALOMEDS::Driver_ptr theDriver, CORBA::ORB_ptr theORB) +{ + // driver can be null - if component interface does not inherit SALOMEDS::Driver _driver = SALOMEDS::Driver::_duplicate(theDriver); + // engine can be null - since it is narrowed from SALOMEDS::Driver ptr which can be null + _engine = Engines::EngineComponent::_narrow(theDriver); _orb = CORBA::ORB::_duplicate(theORB); } @@ -42,8 +54,8 @@ SALOMEDS_Driver_i::~SALOMEDS_Driver_i() std::string SALOMEDS_Driver_i::GetIOR() { std::string ior = ""; - if ( !CORBA::is_nil(_driver) ) { - CORBA::String_var cior = _orb->object_to_string(_driver); + if ( !CORBA::is_nil(_engine) ) { + CORBA::String_var cior = _orb->object_to_string(_engine); ior = cior; } return ior; @@ -163,6 +175,11 @@ std::string SALOMEDS_Driver_i::ComponentDataType() return dtype; } +std::string SALOMEDS_Driver_i::Version() +{ + return !CORBA::is_nil( _engine ) ? _engine->getVersion() : std::string(""); +} + std::string SALOMEDS_Driver_i::IORToLocalPersistentID(const SALOMEDSImpl_SObject& theSObject, const std::string& IORString, bool isMultiFile, @@ -298,9 +315,8 @@ SALOMEDSImpl_TMPFile* SALOMEDS_Driver_i::DumpPython(SALOMEDSImpl_Study* theStudy Engines::TMPFile_var aStream; CORBA::Boolean aValidScript = true; // VSR: maybe should be false by default ??? - Engines::EngineComponent_ptr aComponent = Engines::EngineComponent::_narrow(_driver); - if ( !CORBA::is_nil( aComponent ) ) - aStream = aComponent->DumpPython(st.in(), isPublished, isMultiFile, aValidScript); + if ( !CORBA::is_nil( _engine ) ) + aStream = _engine->DumpPython(st.in(), isPublished, isMultiFile, aValidScript); SALOMEDSImpl_TMPFile* aTMPFile = new Engines_TMPFile_i(aStream._retn()); theStreamLength = aTMPFile->Size(); @@ -344,8 +360,8 @@ SALOMEDSImpl_Driver* SALOMEDS_DriverFactory_i::GetDriverByType(const std::string } if (!CORBA::is_nil(obj)) { - SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(obj); - return new SALOMEDS_Driver_i(aDriver, _orb); + Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj); + return new SALOMEDS_Driver_i(anEngine, _orb); } return NULL; @@ -357,8 +373,8 @@ SALOMEDSImpl_Driver* SALOMEDS_DriverFactory_i::GetDriverByIOR(const std::string& obj = _orb->string_to_object(theIOR.c_str()); if (!CORBA::is_nil(obj)) { - SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(obj); - return new SALOMEDS_Driver_i(aDriver, _orb); + Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj); + return new SALOMEDS_Driver_i(anEngine, _orb); } return NULL; diff --git a/src/SALOMEDS/SALOMEDS_Driver_i.hxx b/src/SALOMEDS/SALOMEDS_Driver_i.hxx index a17b9b846..e4de665be 100644 --- a/src/SALOMEDS/SALOMEDS_Driver_i.hxx +++ b/src/SALOMEDS/SALOMEDS_Driver_i.hxx @@ -37,12 +37,12 @@ class Standard_EXPORT SALOMEDS_Driver_i : public virtual SALOMEDSImpl_Driver { protected: SALOMEDS::Driver_var _driver; + Engines::EngineComponent_var _engine; CORBA::ORB_var _orb; public: - + SALOMEDS_Driver_i(Engines::EngineComponent_ptr theEngine, CORBA::ORB_ptr theORB); SALOMEDS_Driver_i(SALOMEDS::Driver_ptr theDriver, CORBA::ORB_ptr theORB); - ~SALOMEDS_Driver_i(); virtual std::string GetIOR(); @@ -73,6 +73,8 @@ public: virtual std::string ComponentDataType(); + virtual std::string Version(); + virtual std::string IORToLocalPersistentID(const SALOMEDSImpl_SObject& theSObject, const std::string& IORString, bool isMultiFile, diff --git a/src/SALOMEDS/SALOMEDS_StudyBuilder.cxx b/src/SALOMEDS/SALOMEDS_StudyBuilder.cxx index 5e54ef02e..fb6ee94c0 100644 --- a/src/SALOMEDS/SALOMEDS_StudyBuilder.cxx +++ b/src/SALOMEDS/SALOMEDS_StudyBuilder.cxx @@ -194,12 +194,13 @@ void SALOMEDS_StudyBuilder::LoadWith(const _PTR(SComponent)& theSCO, const std:: SALOMEDS_SComponent* aSCO = dynamic_cast(theSCO.get()); CORBA::Object_var obj = _orb->string_to_object(theIOR.c_str()); + Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj); SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(obj); if (_isLocal) { SALOMEDS::Locker lock; - SALOMEDS_Driver_i* drv = new SALOMEDS_Driver_i(aDriver, _orb); + SALOMEDS_Driver_i* drv = new SALOMEDS_Driver_i(anEngine, _orb); SALOMEDSImpl_SComponent aSCO_impl = *(dynamic_cast(aSCO->GetLocalImpl())); bool isDone = _local_impl->LoadWith(aSCO_impl, drv); delete drv; diff --git a/src/SALOMEDS/SALOMEDS_StudyManager.cxx b/src/SALOMEDS/SALOMEDS_StudyManager.cxx index 813d0820e..814f58bc3 100644 --- a/src/SALOMEDS/SALOMEDS_StudyManager.cxx +++ b/src/SALOMEDS/SALOMEDS_StudyManager.cxx @@ -317,7 +317,7 @@ SALOMEDS_Driver_i* GetDriver(const SALOMEDSImpl_SObject& theObject, CORBA::ORB_p std::string IOREngine = aSCO.GetIOR(); if(!IOREngine.empty()) { CORBA::Object_var obj = orb->string_to_object(IOREngine.c_str()); - SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ; + Engines::EngineComponent_var Engine = Engines::EngineComponent::_narrow(obj) ; driver = new SALOMEDS_Driver_i(Engine, orb); } } diff --git a/src/SALOMEDS/SALOMEDS_StudyManager_i.cxx b/src/SALOMEDS/SALOMEDS_StudyManager_i.cxx index c26919c8e..9ba8b7e71 100644 --- a/src/SALOMEDS/SALOMEDS_StudyManager_i.cxx +++ b/src/SALOMEDS/SALOMEDS_StudyManager_i.cxx @@ -451,7 +451,7 @@ SALOMEDS_Driver_i* GetDriver(const SALOMEDSImpl_SObject& theObject, CORBA::ORB_p std::string IOREngine = aSCO.GetIOR(); if(!IOREngine.empty()) { CORBA::Object_var obj = orb->string_to_object(IOREngine.c_str()); - SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ; + Engines::EngineComponent_var Engine = Engines::EngineComponent::_narrow(obj) ; driver = new SALOMEDS_Driver_i(Engine, orb); } } diff --git a/src/SALOMEDS/SALOME_DriverPy.py b/src/SALOMEDS/SALOME_DriverPy.py index 7e820dd27..e879aeb69 100644 --- a/src/SALOMEDS/SALOME_DriverPy.py +++ b/src/SALOMEDS/SALOME_DriverPy.py @@ -46,6 +46,12 @@ class SALOME_DriverPy_i(SALOMEDS__POA.Driver): def ComponentDataType(self): return self._ComponentDataType + def Version(self): + try: + return self.getVersion() + except: + return "" + def Save(self, theComponent, theURL, isMultiFile): return "" diff --git a/src/SALOMEDSClient/SALOMEDSClient_AttributeStudyProperties.hxx b/src/SALOMEDSClient/SALOMEDSClient_AttributeStudyProperties.hxx index de3f9a5cb..41284ca6e 100644 --- a/src/SALOMEDSClient/SALOMEDSClient_AttributeStudyProperties.hxx +++ b/src/SALOMEDSClient/SALOMEDSClient_AttributeStudyProperties.hxx @@ -67,7 +67,9 @@ public: virtual void SetComment(const std::string& theComment) = 0; virtual std::string GetComment() = 0; - + virtual std::vector GetStoredComponents() = 0; + virtual std::string GetComponentVersion( const std::string& theComponent ) = 0; + virtual std::vector GetComponentVersions( const std::string& theComponent ) = 0; }; diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.cxx index 60e44a608..16ba9c285 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.cxx @@ -60,6 +60,7 @@ void SALOMEDSImpl_AttributeStudyProperties::Init() myMonth.clear(); myYear.clear(); myMode = 0; // none + myComponentVersions.clear(); } void SALOMEDSImpl_AttributeStudyProperties::SetModification(const std::string& theUserName, @@ -102,9 +103,7 @@ void SALOMEDSImpl_AttributeStudyProperties::GetModifications std::string SALOMEDSImpl_AttributeStudyProperties::GetCreatorName() const { - if (myUserName.size() == 0) - return std::string(""); - return myUserName[0]; + return myUserName.empty() ? std::string("") : myUserName[0]; } bool SALOMEDSImpl_AttributeStudyProperties::GetCreationDate @@ -136,6 +135,7 @@ void SALOMEDSImpl_AttributeStudyProperties::ChangeCreatorName(const std::string& void SALOMEDSImpl_AttributeStudyProperties::SetCreationMode(const int theMode) { + if (theMode == myMode) return; CheckLocked(); Backup(); myMode = theMode; @@ -175,7 +175,8 @@ bool SALOMEDSImpl_AttributeStudyProperties::IsLocked() const return myLocked; } -bool SALOMEDSImpl_AttributeStudyProperties::IsLockChanged(const bool theErase) { +bool SALOMEDSImpl_AttributeStudyProperties::IsLockChanged(const bool theErase) +{ if (!myLockChanged) return false; if (theErase) myLockChanged = false; return true; @@ -204,6 +205,7 @@ void SALOMEDSImpl_AttributeStudyProperties::Restore(DF_Attribute* with) myYear.push_back(aYears[i]); } myMode = aProp->GetCreationMode(); + myComponentVersions = aProp->GetComponentsVersions(); // myModified = aProp->GetModified(); // myLocked = aProp->IsLocked(); } @@ -227,6 +229,7 @@ void SALOMEDSImpl_AttributeStudyProperties::Paste(DF_Attribute* into) } aProp->SetCreationMode(myMode); + aProp->SetComponentsVersions( myComponentVersions ); // aProp->SetModified(myModified); // aProp->SetLocked(myLocked); } @@ -244,11 +247,26 @@ std::string SALOMEDSImpl_AttributeStudyProperties::Save() std::string units = GetUnits(); std::string comment = GetComment(); + + int aLength1 = 0; + std::map versions; + versionMap::const_iterator it; + for (aLength1 = 0, it = myComponentVersions.begin(); it != myComponentVersions.end(); ++it ) { + std::string vlist = ""; + versionList vl = it->second; + versionList::const_iterator vlit; + for ( vlit = vl.begin(); vlit != vl.end(); ++vlit ) { + if ( vlist != "" ) vlist += ";"; + vlist += *vlit; + } + versions[ it->first ] = vlist; + aLength1 += it->first.size() + vlist.size() + 2; + } unitsSize = units.size(); commentSize = comment.size(); - char* aProperty = new char[3 + aLength + 12 * aNames.size() + 1 + unitsSize + 1 + commentSize]; + char* aProperty = new char[3 + aLength + 12 * aNames.size() + 1 + unitsSize + 1 + commentSize + 1 + aLength1 ]; char crMode = (char)GetCreationMode(); @@ -283,9 +301,19 @@ std::string SALOMEDSImpl_AttributeStudyProperties::Save() if(comment.size() > 0) { sprintf(&(aProperty[a]),"%s",comment.c_str()); a = strlen(aProperty); - a++; } + aProperty[a++] = 30; //delimeter of the component versions + + std::map::const_iterator versionsIt; + for ( versionsIt = versions.begin(); versionsIt != versions.end(); ++versionsIt ) { + sprintf(&(aProperty[a]),"%s=%s", + (char*)(versionsIt->first.c_str()), + (char*)(versionsIt->second.c_str())); + a = strlen(aProperty); + aProperty[a++] = 1; + } + aProperty[a] = 0; std::string prop(aProperty); delete aProperty; @@ -293,26 +321,80 @@ std::string SALOMEDSImpl_AttributeStudyProperties::Save() return prop; } -void SALOMEDSImpl_AttributeStudyProperties::SetUnits(const std::string& theUnits) { +void SALOMEDSImpl_AttributeStudyProperties::SetUnits(const std::string& theUnits) +{ if(myUnits == theUnits) return; + + CheckLocked(); + Backup(); + myUnits = theUnits; } -std::string SALOMEDSImpl_AttributeStudyProperties::GetUnits() { +std::string SALOMEDSImpl_AttributeStudyProperties::GetUnits() const +{ return myUnits; } -void SALOMEDSImpl_AttributeStudyProperties::SetComment(const std::string& theComment) { +void SALOMEDSImpl_AttributeStudyProperties::SetComment(const std::string& theComment) +{ if(myComment == theComment) return; + + CheckLocked(); + Backup(); + myComment = theComment; } -std::string SALOMEDSImpl_AttributeStudyProperties::GetComment() { +std::string SALOMEDSImpl_AttributeStudyProperties::GetComment() const +{ return myComment; } +void SALOMEDSImpl_AttributeStudyProperties::SetComponentVersion(const std::string& theComponent, const std::string& theVersion) +{ + if (!theComponent.empty()) { + CheckLocked(); + Backup(); + if (myComponentVersions.find(theComponent) == myComponentVersions.end()) myComponentVersions[theComponent] = versionList(); + if (myComponentVersions[theComponent].empty() || myComponentVersions[theComponent].back() != theVersion) + myComponentVersions[theComponent].push_back(theVersion); + } +} + +std::vector SALOMEDSImpl_AttributeStudyProperties::GetStoredComponents() const +{ + std::vector components; + versionMap::const_iterator it; + for (it = myComponentVersions.begin(); it != myComponentVersions.end(); ++it) + components.push_back(it->first); + return components; +} + +std::string SALOMEDSImpl_AttributeStudyProperties::GetComponentVersion(const std::string& theComponent) const +{ + versionList versions = GetComponentVersions(theComponent); + return versions.size() > 0 ? versions[0] : std::string(""); +} + +std::vector SALOMEDSImpl_AttributeStudyProperties::GetComponentVersions(const std::string& theComponent) const +{ + versionList versions; + if ( myComponentVersions.find(theComponent) != myComponentVersions.end() ) versions = myComponentVersions.at(theComponent); + return versions; +} + +std::map< std::string, std::vector > SALOMEDSImpl_AttributeStudyProperties::GetComponentsVersions() const +{ + return myComponentVersions; +} + +void SALOMEDSImpl_AttributeStudyProperties::SetComponentsVersions( const std::map< std::string, std::vector >& theVersions ) +{ + myComponentVersions = theVersions; +} void SALOMEDSImpl_AttributeStudyProperties::Load(const std::string& value) { @@ -322,7 +404,16 @@ void SALOMEDSImpl_AttributeStudyProperties::Load(const std::string& value) SetCreationMode(crMode); int anIndex; - for (anIndex = 2; anIndex + 2 < value.size() ;) { + // number 13 below is minimal size of modification data record, which has form: + // mmhhddMMyyyyname1, where + // - mm: minute = 2 bytes + // - hh: hour = 2 bytes + // - dd: day = 2 bytes + // - MM: month = 2 bytes + // - yyyy: year = 4 bytes + // - name: user's name = arbitrary value, minimal length is 0 bytes + // - 1 : records delimiter = 1 byte + for (anIndex = 2; anIndex + 13 < value.size() ;) { char str[10]; int aMinute, aHour, aDay, aMonth, aYear; str[0] = aCopy[anIndex++]; @@ -359,7 +450,7 @@ void SALOMEDSImpl_AttributeStudyProperties::Load(const std::string& value) break; } - //Case then study contains units and comment properties + //Case when study contains units and comment properties if( anIndex < value.size() ) { anIndex++; //skip the delimeter of the sections: char(30) int unitsSize; @@ -375,7 +466,7 @@ void SALOMEDSImpl_AttributeStudyProperties::Load(const std::string& value) anIndex += unitsSize + 1; int commentSize; - for(commentSize = 0; aCopy[anIndex+commentSize] != 0; commentSize++); + for(commentSize = 0; aCopy[anIndex+commentSize] != 0 && aCopy[anIndex+commentSize] != 30; commentSize++); if(commentSize > 0) { char *aComment = new char[commentSize+1]; @@ -384,7 +475,40 @@ void SALOMEDSImpl_AttributeStudyProperties::Load(const std::string& value) SetComment(aComment); delete [] (aComment); } - anIndex += commentSize; + anIndex += commentSize + 1; + } + + //Case when study contains components versions + if( anIndex < value.size() ) { + while ( anIndex < value.size() && aCopy[anIndex] != 0 ) { + int modSize; + for(modSize = 0; aCopy[anIndex+modSize] != '='; modSize++); + int verSize; + for(verSize = 0; aCopy[anIndex+modSize+1+verSize] != 1; verSize++); + + if(modSize > 0) { + char *aModule = new char[modSize+1]; + strncpy(aModule, &(aCopy[anIndex]), modSize); + aModule[modSize] = 0; + char *aVersions = new char[verSize+1]; + if ( verSize > 0 ) + strncpy(aVersions, &(aCopy[anIndex+modSize+1]), verSize); + aVersions[verSize] = 0; + + std::string mVersions = aVersions; + int start = 0, idx = mVersions.find( ';', start ); + while ( idx != std::string::npos ) { + SetComponentVersion( aModule, mVersions.substr( start, idx-start ) ); + start = idx + 1; + idx = mVersions.find( ';', start ); + } + SetComponentVersion( aModule, mVersions.substr( start ) ); + + delete [] (aModule); + delete [] (aVersions); + anIndex += modSize + 1 + verSize + 1; + } + } } if (aCopy[1] == 'l') { diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.hxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.hxx index 4be09cd27..8cb4b69bb 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.hxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.hxx @@ -32,6 +32,7 @@ #include "DF_Label.hxx" #include #include +#include #include "SALOMEDSImpl_GenericAttribute.hxx" class SALOMEDSIMPL_EXPORT SALOMEDSImpl_AttributeStudyProperties : public SALOMEDSImpl_GenericAttribute @@ -73,10 +74,10 @@ public: void ChangeCreatorName(const std::string& theUserName); void SetUnits(const std::string& theUnits); - std::string GetUnits(); + std::string GetUnits() const; void SetComment(const std::string& theComment); - std::string GetComment(); + std::string GetComment() const; void SetCreationMode(const int theMode); int GetCreationMode() const; @@ -89,11 +90,20 @@ public: bool IsLocked() const; bool IsLockChanged(const bool theErase); + void SetComponentsVersions( const std::map< std::string, std::vector >& theVersions ); + void SetComponentVersion(const std::string& theComponent, const std::string& theVersion); + std::vector GetStoredComponents() const; + std::string GetComponentVersion(const std::string& theComponent) const; + std::vector GetComponentVersions(const std::string& theComponent) const; + std::map< std::string, std::vector > GetComponentsVersions() const; + void Restore(DF_Attribute* with); DF_Attribute* NewEmpty() const; void Paste(DF_Attribute* into); private: + typedef std::vector versionList; + typedef std::map versionMap; std::vector myUserName; std::vector myMinute; @@ -103,11 +113,11 @@ private: std::vector myYear; std::string myUnits; std::string myComment; - int myMode; - int myModified; - bool myLocked; - bool myLockChanged; - + int myMode; + int myModified; + bool myLocked; + bool myLockChanged; + versionMap myComponentVersions; }; #endif diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_Driver.hxx b/src/SALOMEDSImpl/SALOMEDSImpl_Driver.hxx index 84be82bcb..b204337bb 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_Driver.hxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_Driver.hxx @@ -62,6 +62,7 @@ public: virtual std::string ComponentDataType() = 0; + virtual std::string Version() = 0; virtual std::string IORToLocalPersistentID(const SALOMEDSImpl_SObject& theSObject, const std::string& IORString, diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_StudyManager.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_StudyManager.cxx index d52b629eb..efa5daf12 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_StudyManager.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_StudyManager.cxx @@ -56,6 +56,42 @@ static void Translate_IOR_to_persistentID (const SALOMEDSImpl_SObject&, SALOMEDSImpl_Driver*, bool isMultiFile, bool isASCII); static void ReadNoteBookVariables(SALOMEDSImpl_Study* theStudy, HDFgroup* theGroup); +namespace { + class StudyUnlocker + { + public: + StudyUnlocker( SALOMEDSImpl_Study* study ): myStudy( study ), myLocked( false ) + { + myPrevLocked = myStudy->GetProperties()->IsLocked(); + resume(); + } + ~StudyUnlocker() + { + suspend(); + } + void suspend() + { + if (myLocked) { + myStudy->GetProperties()->SetLocked(true); + myPrevLocked = myLocked; + myLocked = false; + } + } + void resume() + { + if (myPrevLocked) { + myStudy->GetProperties()->SetLocked(false); + myLocked = myPrevLocked; + myPrevLocked = false; + } + } + private: + SALOMEDSImpl_Study* myStudy; + bool myLocked; + bool myPrevLocked; + }; +} + //============================================================================ /*! Function : SALOMEDSImpl_StudyManager * Purpose : SALOMEDSImpl_StudyManager constructor @@ -398,15 +434,17 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveProperties(SALOMEDSImpl_Study* aStudy, // add modifications list (user and date of save) SALOMEDSImpl_AttributeStudyProperties* aProp = aStudy->GetProperties(); - int aLocked = aProp->IsLocked(); - if (aLocked) aProp->SetLocked(false); + // unlock study if it is locked, to set modification date + StudyUnlocker unlock(aStudy); + int month=0,day=0,year=0,hh=0,mn=0,ss=0; SALOMEDSImpl_Tool::GetSystemDate(year, month, day, hh, mn, ss); aProp->SetModification(SALOMEDSImpl_Tool::GetUserName(), - mn, hh, day, month, year); - - if (aLocked) aProp->SetLocked(true); + mn, hh, day, month, year); + + // lock study back if it was locked initially, to write correct value of Locked flag + unlock.suspend(); std::vector aNames; std::vector aMinutes, aHours, aDays, aMonths, aYears; @@ -416,10 +454,27 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveProperties(SALOMEDSImpl_Study* aStudy, std::string units = aProp->GetUnits(); std::string comment = aProp->GetComment(); - int aLength = 0, anIndex, i, unitsSize = 0, commentSize = 0; + std::map< std::string, std::vector > allVersions = aProp->GetComponentsVersions(); + std::map versions; + + int aLength = 0, aLength1 = 0, anIndex, i, unitsSize = 0, commentSize = 0; + for(i=1; i<=aNames.size(); i++) aLength += aNames[i-1].size() + 1; - + + std::map< std::string, std::vector >::const_iterator it; + for (it = allVersions.begin(); it != allVersions.end(); ++it ) { + std::string vlist = ""; + std::vector vl = it->second; + std::vector::const_iterator vlit; + for ( vlit = vl.begin(); vlit != vl.end(); ++vlit ) { + if ( vlist != "" ) vlist += ";"; + vlist += *vlit; + } + versions[ it->first ] = vlist; + aLength1 += it->first.size() + vlist.size() + 2; + } + unitsSize = units.size(); commentSize = comment.size(); @@ -431,13 +486,16 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveProperties(SALOMEDSImpl_Study* aStudy, //....................................................., //....................................................., //minutes, hours, day, months, year, user name, char(1), char(30) <- !!!! used to define end of section with modifications !!!! - //units, char(1), comment, char(0) + //units, char(1), comment, char(30) <- !!!! used to define start of section with components' versions !!!! + //component=versions, char(1), + //component=versions, char(1), + //..........................., + //component=versions, char(1), char(0) //string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, 1 byte (char(30) section delimeter) // unit length + 1, comment length, "zero" byte - char* aProperty = new char[3 + aLength + 12 * aNames.size() + 1 + unitsSize + 1 + commentSize ]; - + char* aProperty = new char[3 + aLength + 12 * aNames.size() + 1 + unitsSize + 1 + commentSize + 1 + aLength1 ]; sprintf(aProperty,"%c%c", (char)aProp->GetCreationMode(), (aProp->IsLocked())?'l':'u'); @@ -470,11 +528,21 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveProperties(SALOMEDSImpl_Study* aStudy, if(comment.size() > 0) { sprintf(&(aProperty[a]),"%s",comment.c_str()); a = strlen(aProperty); - a++; + } + + aProperty[a++] = 30; //delimeter of the component versions + + std::map::const_iterator versionsIt; + for ( versionsIt = versions.begin(); versionsIt != versions.end(); ++versionsIt ) { + sprintf(&(aProperty[a]),"%s=%s", + (char*)(versionsIt->first.c_str()), + (char*)(versionsIt->second.c_str())); + a = a + versionsIt->first.size() + versionsIt->second.size() + 1; + aProperty[a++] = 1; } aProperty[a] = 0; - + name_len = (hdf_int32) a; size[0] = name_len + 1 ; hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1); @@ -531,11 +599,14 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, // Store previous URL std::string anOldName = aStudy->Name(); + // Map to store components' versions + std::map componentVersions; + //Create a temporary url to which the study is saved std::string aUrl = SALOMEDSImpl_Tool::GetTmpDir() + SALOMEDSImpl_Tool::GetNameFromPath(aStudyUrl); - int aLocked = aStudy->GetProperties()->IsLocked(); - if (aLocked) aStudy->GetProperties()->SetLocked(false); + // unlock study if it is locked, as some attributes need to be modified + StudyUnlocker unlock(aStudy); SALOMEDSImpl_StudyBuilder* SB= aStudy->NewBuilder(); std::map aMapTypeDriver; @@ -543,19 +614,19 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, try { // mpv 15.12.2003: for saving components we have to load all data from all modules - SALOMEDSImpl_SComponentIterator itcomponent1 = aStudy->NewComponentIterator(); - for (; itcomponent1.More(); itcomponent1.Next()) + SALOMEDSImpl_SComponentIterator itcomponent = aStudy->NewComponentIterator(); + for (; itcomponent.More(); itcomponent.Next()) { - SALOMEDSImpl_SComponent sco = itcomponent1.Value(); + SALOMEDSImpl_SComponent sco = itcomponent.Value(); // if there is an associated Engine call its method for saving std::string IOREngine; try { + SALOMEDSImpl_Driver* aDriver = NULL; + std::string aCompType = sco.GetComment(); if (!sco.ComponentIOR(IOREngine)) { - std::string aCompType = sco.GetComment(); if (!aCompType.empty()) { - SALOMEDSImpl_Driver* aDriver = aFactory->GetDriverByType(aCompType); - aMapTypeDriver[aCompType] = aDriver; + aDriver = aFactory->GetDriverByType(aCompType); if (aDriver != NULL) { if(!SB->LoadWith(sco, aDriver)) { @@ -565,6 +636,10 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, } } } + else { + aDriver = aFactory->GetDriverByIOR(IOREngine); + } + aMapTypeDriver[aCompType] = aDriver; } catch(...) { _errorCode = "Can not restore information to resave it"; return false; @@ -586,9 +661,7 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file); hdf_group_datacomponent->CreateOnDisk(); - SALOMEDSImpl_SComponentIterator itcomponent = aStudy->NewComponentIterator(); - - for (; itcomponent.More(); itcomponent.Next()) + for (itcomponent.Init(); itcomponent.More(); itcomponent.Next()) { SALOMEDSImpl_SComponent sco = itcomponent.Value(); @@ -600,20 +673,15 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, std::string IOREngine; if (sco.ComponentIOR(IOREngine)) { - SALOMEDSImpl_Driver* Engine = NULL; - if(aMapTypeDriver.find(componentDataType) != aMapTypeDriver.end()) { - // we have found the associated engine to write the data - Engine = aMapTypeDriver[componentDataType]; - } - else { - Engine = aFactory->GetDriverByIOR(IOREngine); - } - + // Engine should be already in the map as it was to added before + SALOMEDSImpl_Driver* Engine = aMapTypeDriver[componentDataType]; if (Engine != NULL) { SALOMEDSImpl_TMPFile* aStream = NULL; long length = 0; + componentVersions[ componentDataType ] = Engine->Version(); + if (theASCII) aStream = Engine->SaveASCII(sco, SALOMEDSImpl_Tool::GetDirFromPath(aUrl), length, @@ -666,10 +734,9 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file); hdf_group_study_structure->CreateOnDisk(); // save component attributes - SALOMEDSImpl_SComponentIterator itcomp = aStudy->NewComponentIterator(); - for (; itcomp.More(); itcomp.Next()) + for (itcomponent.Init(); itcomponent.More(); itcomponent.Next()) { - SALOMEDSImpl_SComponent SC = itcomp.Value(); + SALOMEDSImpl_SComponent SC = itcomponent.Value(); std::string scid = SC.GetID(); hdf_sco_group2 = new HDFgroup((char*)scid.c_str(), hdf_group_study_structure); hdf_sco_group2->CreateOnDisk(); @@ -752,8 +819,15 @@ bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl, } hdf_notebook_vars->CloseOnDisk(); hdf_notebook_vars = 0; //will be deleted by hdf_sco_group destructor - - if (aLocked) aStudy->GetProperties()->SetLocked(true); + + // record component versions + std::map::const_iterator itVersions; + for ( itVersions = componentVersions.begin(); itVersions != componentVersions.end(); ++itVersions ) + aStudy->GetProperties()->SetComponentVersion( itVersions->first, itVersions->second ); + + // lock study back if it was locked initially, to write correct value of Locked flag + unlock.suspend(); + //----------------------------------------------------------------------- //6 - Write the Study Properties //-----------------------------------------------------------------------