]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
0021478: EDF 2083 ALL: Write the version of Salome used to create the study in the...
authorvsr <vsr@opencascade.com>
Tue, 16 Oct 2012 08:17:12 +0000 (08:17 +0000)
committervsr <vsr@opencascade.com>
Tue, 16 Oct 2012 08:17:12 +0000 (08:17 +0000)
21 files changed:
idl/SALOMEDS_Attributes.idl
idl/SALOME_Component.idl
src/Container/Component_i.cxx
src/Container/SALOME_ComponentPy.py
src/Container/SALOME_Component_i.hxx
src/KERNEL_PY/salome_study.py
src/SALOMEDS/SALOMEDS_AttributeStudyProperties.cxx
src/SALOMEDS/SALOMEDS_AttributeStudyProperties.hxx
src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.cxx
src/SALOMEDS/SALOMEDS_AttributeStudyProperties_i.hxx
src/SALOMEDS/SALOMEDS_Driver_i.cxx
src/SALOMEDS/SALOMEDS_Driver_i.hxx
src/SALOMEDS/SALOMEDS_StudyBuilder.cxx
src/SALOMEDS/SALOMEDS_StudyManager.cxx
src/SALOMEDS/SALOMEDS_StudyManager_i.cxx
src/SALOMEDS/SALOME_DriverPy.py
src/SALOMEDSClient/SALOMEDSClient_AttributeStudyProperties.hxx
src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.cxx
src/SALOMEDSImpl/SALOMEDSImpl_AttributeStudyProperties.hxx
src/SALOMEDSImpl/SALOMEDSImpl_Driver.hxx
src/SALOMEDSImpl/SALOMEDSImpl_StudyManager.cxx

index fbc70d655e6b138b88760bb516bd23001b0e626f..9941794cb783be60df0344ac0f96b5e27998b5e8 100644 (file)
@@ -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 );
   };
 
   //==========================================================================
index 9d55e154be208f748d5bf1ae95028f4479bf6f42..4a1701ddf9b2d32f8d601fbbd23fec35c0cf86c5 100644 (file)
@@ -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();
   } ;
 
   /*!
index 3e77256aa25fa7c1023bd741dde2b2d727c3eecf..ed5b16b6db2df507561088e32aee722f824e36e3 100644 (file)
@@ -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( "" );
+}
index 55ec0ff55f1941947372e880726c61dee1cb564d..66c9de6344fd56018de913aa2d6a98a960c3099f 100755 (executable)
@@ -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
index 94fd62ce8824d3c147ec9947b47672dc6033e77d..3581cd9d24facd62af396c96417f9bd9c7daaccd 100644 (file)
@@ -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(); 
index 5de40bc3a3d4e10b8b2b8bf3c286313b54c3f5cb..f6ebc622a71d825535007ce684fae80ea641b6e2 100644 (file)
@@ -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")
index af20553fa6aa63ed704ec1f44d4e8662e52efa2c..bdb5760d79c25f9ab00f4459864a0e50a0c394b4 100644 (file)
@@ -319,3 +319,49 @@ std::string SALOMEDS_AttributeStudyProperties::GetUnits()
     anUnits = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetUnits();
   return anUnits;
 }
+
+std::vector<std::string> SALOMEDS_AttributeStudyProperties::GetStoredComponents()
+{
+  std::vector<std::string> aComponents;
+  if (_isLocal) {
+    SALOMEDS::Locker lock;
+    aComponents = dynamic_cast<SALOMEDSImpl_AttributeStudyProperties*>(_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<SALOMEDSImpl_AttributeStudyProperties*>(_local_impl)->GetComponentVersion(theComponent);
+  }
+  else 
+    aVersion = ((SALOMEDS::AttributeStudyProperties_var)SALOMEDS::AttributeStudyProperties::_narrow(_corba_impl))->GetComponentVersion(theComponent.c_str());
+  return aVersion;
+}
+
+std::vector<std::string> SALOMEDS_AttributeStudyProperties::GetComponentVersions( const std::string& theComponent )
+{
+  std::vector<std::string> aVersions;
+  if (_isLocal) {
+    SALOMEDS::Locker lock;
+    aVersions = dynamic_cast<SALOMEDSImpl_AttributeStudyProperties*>(_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;
+}
index 4ebd180bda4274fc7960a89972d4774aa6ce809c..b02e0fbff1663fba426a72422ceb1b21b658343a 100644 (file)
@@ -82,7 +82,9 @@ public:
   virtual void SetComment(const std::string& theComment);
   virtual std::string GetComment();
 
-
+  virtual std::vector<std::string> GetStoredComponents();
+  virtual std::string GetComponentVersion( const std::string& theComponent );
+  virtual std::vector<std::string> GetComponentVersions( const std::string& theComponent );
 };
 
 
index a6bd88294a1b68e919c509a0ea1cbd7a5fd3c83d..3c02784deba87b89d11ddad8268d0b38cbd83d4c 100644 (file)
@@ -218,3 +218,34 @@ char* SALOMEDS_AttributeStudyProperties_i::GetUnits()
   return c_s._retn();
 }
 
+SALOMEDS::StringSeq* SALOMEDS_AttributeStudyProperties_i::GetStoredComponents()
+{
+  SALOMEDS::Locker lock;
+  std::vector<std::string> components = dynamic_cast<SALOMEDSImpl_AttributeStudyProperties*>(_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<SALOMEDSImpl_AttributeStudyProperties*>(_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<std::string> versions = dynamic_cast<SALOMEDSImpl_AttributeStudyProperties*>(_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();
+}
index 7c6198ee1fe43ece3e807225c7858623581959b1..ead14d9e8207dccfe6d0366d3edbfeceb0b6f406 100644 (file)
@@ -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);
 };
 
 
index 87bdec277349f2cf3fca8e2fa92301ddf64da393..ae2db2077fcfb73511880303cbb5026d424f4459 100644 (file)
 #include "SALOMEDS.hxx"
 #include <stdlib.h>
 
-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;
index a17b9b8464c478aa77ca1e6ec25283b5756c215d..e4de665be123d505ad93b23a948d91b5ad511ef3 100644 (file)
@@ -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,
index 5e54ef02e2280a8eb5177db9f73a55af3d28cbb4..fb6ee94c03224079cf3493a776a0eca6f88b3b17 100644 (file)
@@ -194,12 +194,13 @@ void SALOMEDS_StudyBuilder::LoadWith(const _PTR(SComponent)& theSCO, const std::
 
   SALOMEDS_SComponent* aSCO = dynamic_cast<SALOMEDS_SComponent*>(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<SALOMEDSImpl_SComponent*>(aSCO->GetLocalImpl()));
     bool isDone = _local_impl->LoadWith(aSCO_impl, drv);
     delete drv;
index 813d0820e89192f559314464c1e7c3addbb28b09..814f58bc30a55a2b7a03ea86a53343138e029d2a 100644 (file)
@@ -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);
     }
   }
index c26919c8e064900b6bae25a062fea87ac34fdd10..9ba8b7e71fb18de21b455d6af3f5541834b122bd 100644 (file)
@@ -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);
     }
   }
index 7e820dd2752411a23c404366e3463e3504e8e8ae..e879aeb6931efd09beffa1ef3f5e7e1e4e1113ad 100644 (file)
@@ -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 ""
 
index de3f9a5cbd70c3b926b69523c31559e6bb074292..41284ca6eae887bdd0b9d2d0886158b5173325a3 100644 (file)
@@ -67,7 +67,9 @@ public:
   virtual void SetComment(const std::string& theComment) = 0;
   virtual std::string GetComment() = 0;
 
-
+  virtual std::vector<std::string> GetStoredComponents() = 0;
+  virtual std::string GetComponentVersion( const std::string& theComponent ) = 0;
+  virtual std::vector<std::string> GetComponentVersions( const std::string& theComponent ) = 0;
 };
 
 
index 60e44a608adbcf72066230cc498dd21d65cd4ff2..16ba9c285af7bc52d5b61621b2e94dccc4eeb515 100644 (file)
@@ -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<std::string, std::string> 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<std::string, std::string>::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<std::string> SALOMEDSImpl_AttributeStudyProperties::GetStoredComponents() const
+{
+  std::vector<std::string> 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<std::string> 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<std::string> > SALOMEDSImpl_AttributeStudyProperties::GetComponentsVersions() const
+{
+  return myComponentVersions;
+}
+
+void SALOMEDSImpl_AttributeStudyProperties::SetComponentsVersions( const std::map< std::string, std::vector<std::string> >& 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') {
index 4be09cd2728c8144c769055771e9223d1e090a31..8cb4b69bbe2b06c5ccc58361a229afedc707f9c3 100644 (file)
@@ -32,6 +32,7 @@
 #include "DF_Label.hxx"
 #include <string>
 #include <vector>
+#include <map>
 #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<std::string> >& theVersions );
+  void SetComponentVersion(const std::string& theComponent, const std::string& theVersion);
+  std::vector<std::string> GetStoredComponents() const;
+  std::string GetComponentVersion(const std::string& theComponent) const;
+  std::vector<std::string> GetComponentVersions(const std::string& theComponent) const;
+  std::map< std::string, std::vector<std::string> > GetComponentsVersions() const;
+
   void Restore(DF_Attribute* with);
   DF_Attribute* NewEmpty() const;
   void Paste(DF_Attribute* into);
 
 private:
+  typedef std::vector<std::string> versionList;
+  typedef std::map<std::string, versionList> versionMap;
 
   std::vector<std::string> myUserName;
   std::vector<int> myMinute;
@@ -103,11 +113,11 @@ private:
   std::vector<int> 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
index 84be82bcb6162030721502faec065b9352392149..b204337bb336ca862dc0a060a535c7fdcf31a37f 100644 (file)
@@ -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,
index d52b629ebdb8fd43272d80e2b0e16d6979bb1f5d..efa5daf1263eb92b7e57e659ef786ed91b48f0ff 100644 (file)
@@ -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<std::string> aNames;
   std::vector<int> 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<std::string> > allVersions = aProp->GetComponentsVersions();
+  std::map<std::string, std::string> 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<std::string> >::const_iterator it;
+  for (it = allVersions.begin(); it != allVersions.end(); ++it ) {
+    std::string vlist = "";
+    std::vector<std::string> vl = it->second;
+    std::vector<std::string>::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<std::string, std::string>::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<std::string, std::string> 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<std::string, SALOMEDSImpl_Driver*> 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<std::string, std::string>::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
       //-----------------------------------------------------------------------