diff --git a/Core/Code/Interfaces/mitkIPersistenceService.h b/Core/Code/Interfaces/mitkIPersistenceService.h index 568cefc235..14a9fd361e 100644 --- a/Core/Code/Interfaces/mitkIPersistenceService.h +++ b/Core/Code/Interfaces/mitkIPersistenceService.h @@ -1,339 +1,339 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkIPersistenceService_h #define mitkIPersistenceService_h // mitk #include "mitkPropertyListReplacedObserver.h" #include "usServiceReference.h" #include "usModuleContext.h" #include "usGetModuleContext.h" //for microservices #include #include "mitkDataStorage.h" namespace mitk { /** * The central service for the persistence module * Basic idea is to create PropertyLists with a unique id using AddPropertyList(). A consumer * of this interface can write arbitrary information into this propertylist * Calling Save() and Load() will cause the Service to save and load the current set of propertlists from * a file in the user directory. * Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application * start/stop. * Moreover, depending on the backend type, the service is connected to the SceneSerialization module, i.e. * the user will be asked whether to save/load the propertlists in/from the current ".mitk" file that is selected * by the user. */ class MITK_CORE_EXPORT IPersistenceService { public: /** * If PropertyList with the given id exists, returns it. Otherwise creates a new one and returns it. * If id is empty a UUID will be created and set on the variable * If existed was passed, it is true if the PropertyList with that id existed, false otherwise * \return a valid PropertyList with a StringProperty "Id" containing the passed id */ virtual mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ) = 0; /** * removes the PropertyList with the given id * \return true if PropertyList existed and could be removed, false otherwise */ virtual bool RemovePropertyList( std::string& id ) = 0; /** * Get the default name of the PersistenceFile (the one that is loaded at startup) */ - virtual std::string GetDefaultPersistenceFile() const = 0; + virtual std::string GetDefaultPersistenceFile() = 0; /** * \return The name of the Bool Property that specifies whether a DataNode is a Node carrying Persistence PropertyLists */ - virtual std::string GetPersistenceNodePropertyName() const = 0; + virtual std::string GetPersistenceNodePropertyName() = 0; /** * Creates a vector of DataNodes that contain all PropertyLists. Additionally, the DataNodes * will have the property name set to the PropertyList's id and a BoolProperty equal to GetPersistenceNodePropertyName() set to true. If ds is set the returned DataNodes will also be added to that DS. * \return vector of DataNodes with the described attributes */ - virtual DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) const = 0; + virtual DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) = 0; /** * Searches storage for persistent DataNodes, extracts and inserts the appended property lists to this service * \return true if at least one node was found from which a PropertyList could be restored */ virtual bool RestorePropertyListsFromPersistentDataNodes(const DataStorage* storage) = 0; /** * Save the current PropertyLists to fileName. If fileName is empty, a special file in the users home directory will be used. * if appendchanges is true, the file will not replaced but first loaded, then overwritten and then replaced * \return false if an error occured (cannot write to file), true otherwise */ virtual bool Save(const std::string& fileName="", bool appendChanges=false) = 0; /** * Load PropertyLists from fileName. If fileName is empty, a special file in the users home directory will be used. * If enforeReload is false, the service will take care of modified time flags, i.e. it will not load a file * that was loaded before and did not change in the meantime or that was modified by the service itself * *ATTENTION*: If there are PropertyLists with the same id contained in the file, existing PropertyLists will be overwritten! * \see AddPropertyListReplacedObserver() * \return false if an error occured (cannot load from file), true otherwise */ virtual bool Load(const std::string& fileName="", bool enforeReload=true) = 0; /** * Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application * start/stop. */ virtual void SetAutoLoadAndSave(bool autoLoadAndSave) = 0; /** * \return whether AutoLoading is activated or not */ - virtual bool GetAutoLoadAndSave() const = 0; + virtual bool GetAutoLoadAndSave() = 0; /** * adds a observer which is informed if a propertyList gets replaced during a Load() procedure */ virtual void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ) = 0; /** * removes a specific observer */ virtual void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ) = 0; /** * nothing to do here */ virtual ~IPersistenceService(); }; } // MACROS FOR AUTOMATIC SAVE FUNCTION #define PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION\ us::GetModuleContext() #define PERSISTENCE_GET_SERVICE_MACRO\ mitk::IPersistenceService* persistenceService = 0;\ us::ModuleContext* context = PERSISTENCE_GET_MODULE_CONTEXT_FUNCTION;\ if( context )\ {\ us::ServiceReference persistenceServiceRef = context->GetServiceReference();\ if( persistenceServiceRef )\ {\ persistenceService\ = dynamic_cast ( context->GetService(persistenceServiceRef) );\ }\ } #define PERSISTENCE_GET_SERVICE_METHOD_MACRO\ mitk::IPersistenceService* GetPeristenceService() const\ {\ PERSISTENCE_GET_SERVICE_MACRO\ return persistenceService;\ } #define PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ public:\ bool Save(const std::string& fileName="", bool appendChanges=false)\ {\ mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ bool noError = persistenceService != 0;\ if( noError )\ this->ToPropertyList();\ if(noError)\ noError = persistenceService->Save(fileName, appendChanges);\ return noError;\ }\ bool Load(const std::string& fileName="", bool enforeReload=true)\ {\ mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ bool noError = persistenceService != 0 && persistenceService->Load(fileName, enforeReload);\ if( noError )\ {\ this->FromPropertyList();\ }\ return noError;\ }\ void ToPropertyList()\ {\ mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ this->InitializePropertyListReplacedObserver(persistenceService);\ if( !persistenceService )\ return;\ mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME); #define PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ }\ void FromPropertyList()\ {\ mitk::IPersistenceService* persistenceService = this->GetPeristenceService();\ this->InitializePropertyListReplacedObserver(persistenceService);\ if( !persistenceService )\ return;\ mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(ID_MEMBER_NAME); #define PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME)\ }\ std::string GetId() const\ {\ return ID_MEMBER_NAME;\ }\ private:\ PERSISTENCE_GET_SERVICE_METHOD_MACRO\ struct MyPropertyListReplacedObserver: public mitk::PropertyListReplacedObserver\ {\ MyPropertyListReplacedObserver()\ : m_##THE_CLASS_NAME(0), m_PersistenceService(0)\ {\ }\ ~MyPropertyListReplacedObserver()\ {\ if( m_PersistenceService )\ m_PersistenceService->RemovePropertyListReplacedObserver(this);\ }\ void AfterPropertyListReplaced( const std::string& id, mitk::PropertyList* propertyList )\ {\ if( m_##THE_CLASS_NAME && m_##THE_CLASS_NAME->GetId() == id )\ m_##THE_CLASS_NAME->FromPropertyList();\ }\ void Initialize( THE_CLASS_NAME * _##THE_CLASS_NAME, mitk::IPersistenceService* persistenceService )\ {\ m_##THE_CLASS_NAME = _##THE_CLASS_NAME;\ m_PersistenceService = persistenceService;\ if( m_PersistenceService )\ m_PersistenceService->AddPropertyListReplacedObserver(this);\ }\ private:\ THE_CLASS_NAME * m_##THE_CLASS_NAME;\ mitk::IPersistenceService* m_PersistenceService;\ };\ MyPropertyListReplacedObserver m_MyPropertyListReplacedObserver;\ void InitializePropertyListReplacedObserver(mitk::IPersistenceService* persistenceService)\ {\ static bool observerInitialized = false;\ if( observerInitialized == false && persistenceService )\ {\ m_MyPropertyListReplacedObserver.Initialize( this, persistenceService );\ observerInitialized = true;\ }\ } #define PERSISTENCE_CREATE(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE2(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE3(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE4(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE5(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE6(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE7(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME, PARAM7_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ propList->Set( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ propList->Get( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) #define PERSISTENCE_CREATE8(THE_CLASS_NAME, ID_MEMBER_NAME, PARAM_MEMBER_NAME, PARAM2_MEMBER_NAME, PARAM3_MEMBER_NAME, PARAM4_MEMBER_NAME, PARAM5_MEMBER_NAME, PARAM6_MEMBER_NAME, PARAM7_MEMBER_NAME, PARAM8_MEMBER_NAME)\ PERSISTENCE_MACRO_START_PART(ID_MEMBER_NAME)\ propList->Set( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Set( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Set( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Set( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Set( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Set( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ propList->Set( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ propList->Set( #PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME );\ PERSISTENCE_MACRO_MIDDLE_PART(ID_MEMBER_NAME)\ propList->Get( #PARAM_MEMBER_NAME, PARAM_MEMBER_NAME );\ propList->Get( #PARAM2_MEMBER_NAME, PARAM2_MEMBER_NAME );\ propList->Get( #PARAM3_MEMBER_NAME, PARAM3_MEMBER_NAME );\ propList->Get( #PARAM4_MEMBER_NAME, PARAM4_MEMBER_NAME );\ propList->Get( #PARAM5_MEMBER_NAME, PARAM5_MEMBER_NAME );\ propList->Get( #PARAM6_MEMBER_NAME, PARAM6_MEMBER_NAME );\ propList->Get( #PARAM7_MEMBER_NAME, PARAM7_MEMBER_NAME );\ propList->Get( #PARAM8_MEMBER_NAME, PARAM8_MEMBER_NAME );\ PERSISTENCE_MACRO_END_PART(THE_CLASS_NAME, ID_MEMBER_NAME) US_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService") #endif diff --git a/Modules/Persistence/CMakeLists.txt b/Modules/Persistence/CMakeLists.txt index 66b52eaabc..b0e15b403a 100644 --- a/Modules/Persistence/CMakeLists.txt +++ b/Modules/Persistence/CMakeLists.txt @@ -1,6 +1,6 @@ MITK_CREATE_MODULE( Persistence INCLUDE_DIRS DEPENDS SceneSerialization - AUTOLOAD_WITH SceneSerialization + AUTOLOAD_WITH Mitk ) add_subdirectory(Testing) diff --git a/Modules/Persistence/mitkPersistenceActivator.cpp b/Modules/Persistence/mitkPersistenceActivator.cpp index d8865e3a9f..2af8ef6b36 100644 --- a/Modules/Persistence/mitkPersistenceActivator.cpp +++ b/Modules/Persistence/mitkPersistenceActivator.cpp @@ -1,84 +1,93 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkPersistenceActivator_h #define mitkPersistenceActivator_h // Microservices #include #include "mitkPersistenceService.h" #include namespace mitk { /// /// installs the PersistenceService /// runs all initial commands (setting env paths etc) /// class PersistenceActivator : public us::ModuleActivator { public: + PersistenceActivator() + { + } void Load(us::ModuleContext* context) { MITK_DEBUG << "PersistenceActivator::Load"; - // Registering PersistenceService as MicroService - m_PersistenceService = itk::SmartPointer(new PersistenceService()); - us::ServiceProperties _PersistenceServiceProps; - _PersistenceServiceProps["Name"] = std::string("PersistenceService"); - m_PersistenceServiceRegistration = context->RegisterService(m_PersistenceService, _PersistenceServiceProps); + mitk::IPersistenceService* persistenceService = 0; + us::ServiceReference persistenceServiceRef + = context->GetServiceReference(); + if( persistenceServiceRef ) + { + persistenceService = dynamic_cast ( context->GetService(persistenceServiceRef) ); + } - // Load Default File in any case - m_PersistenceService->Load(); - std::string id = mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME; - mitk::PropertyList::Pointer propList = m_PersistenceService->GetPropertyList( id ); - bool autoLoadAndSave = true; - propList->GetBoolProperty("m_AutoLoadAndSave", autoLoadAndSave); + bool instanceAlreadyAdded = persistenceService != 0; + if( instanceAlreadyAdded ) + instanceAlreadyAdded = dynamic_cast(persistenceService) != 0; - if( autoLoadAndSave == false ) + if( instanceAlreadyAdded == false ) { - MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; - m_PersistenceService->SetAutoLoadAndSave(false); - m_PersistenceService->Clear(); - } + // Registering PersistenceService as MicroService + m_PersistenceService = itk::SmartPointer(new PersistenceService()); + us::ServiceProperties _PersistenceServiceProps; + _PersistenceServiceProps["Name"] = std::string("PersistenceService"); + + m_PersistenceServiceRegistration = context->RegisterService(m_PersistenceService, _PersistenceServiceProps); + } + else + { + MITK_ERROR << "Another Persistence instance already installed. Library was loaded twice. Please check configuration!"; + } } void Unload(us::ModuleContext* context) { + if( m_PersistenceService.IsNull() ) + return; + MITK_DEBUG("PersistenceActivator") << "PersistenceActivator::Unload"; MITK_DEBUG("PersistenceActivator") << "m_PersistenceService GetReferenceCount " << m_PersistenceService->GetReferenceCount(); - if(m_PersistenceService->GetAutoLoadAndSave()) - m_PersistenceService->Save(); - - m_PersistenceServiceRegistration.Unregister(); + //m_PersistenceServiceRegistration.Unregister(); + m_PersistenceService->Unitialize(); m_PersistenceService->Delete(); - MITK_DEBUG("PersistenceActivator") << "m_PersistenceService GetReferenceCount " << m_PersistenceService->GetReferenceCount(); } virtual ~PersistenceActivator() { } private: itk::SmartPointer m_PersistenceService; us::ServiceRegistration m_PersistenceServiceRegistration; }; } US_EXPORT_MODULE_ACTIVATOR(Persistence, mitk::PersistenceActivator) #endif diff --git a/Modules/Persistence/mitkPersistenceService.cpp b/Modules/Persistence/mitkPersistenceService.cpp index 2fa4b531ea..6db16c8897 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,340 +1,386 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPersistenceService.h" #include "mitkStandaloneDataStorage.h" #include "mitkUIDGenerator.h" #include "mitkNodePredicateProperty.h" #include "mitkProperties.h" #include "usModuleContext.h" #include "usGetModuleContext.h" #include const std::string mitk::PersistenceService::PERSISTENCE_PROPERTY_NAME("PersistenceNode"); const std::string mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME("PersistenceService"); mitk::PersistenceService::PersistenceService() -: m_AutoLoadAndSave( true ), m_SceneIO( SceneIO::New() ), m_PropertyListsXmlFileReaderAndWriter( PropertyListsXmlFileReaderAndWriter::New() ) +: m_AutoLoadAndSave( true ), m_Initialized(false), m_InInitialized(false) { } void mitk::PersistenceService::Clear() { - m_PropertyLists.clear(); - m_FileNamesToModifiedTimes.clear(); + this->Initialize(); + m_PropertyLists.clear(); + m_FileNamesToModifiedTimes.clear(); } mitk::PersistenceService::~PersistenceService() { MITK_DEBUG("mitk::PersistenceService") << "destructing PersistenceService"; } -std::string mitk::PersistenceService::GetDefaultPersistenceFile() const +std::string mitk::PersistenceService::GetDefaultPersistenceFile() { - std::string file = "PersistentData.mitk"; - us::ModuleContext* context = us::GetModuleContext(); - std::string contextDataFile = context->GetDataFile("PersistentData.mitk"); - if( !contextDataFile.empty() ) - { - file = contextDataFile; - } - return file; + this->Initialize(); + std::string file = "PersistentData.mitk"; + us::ModuleContext* context = us::GetModuleContext(); + std::string contextDataFile = context->GetDataFile("PersistentData.mitk"); + if( !contextDataFile.empty() ) + { + file = contextDataFile; + } + return file; } mitk::PropertyList::Pointer mitk::PersistenceService::GetPropertyList( std::string& id, bool* existed ) { - mitk::PropertyList::Pointer propList; - - if( id.empty() ) - { - UIDGenerator uidGen; - id = uidGen.GetUID(); - } - - std::map::iterator it = m_PropertyLists.find( id ); - if( it == m_PropertyLists.end() ) - { - propList = PropertyList::New(); - m_PropertyLists[id] = propList; - if( existed ) - *existed = false; - } - else - { - propList = (*it).second; - if( existed ) - *existed = true; - } - - return propList; + this->Initialize(); + mitk::PropertyList::Pointer propList; + + if( id.empty() ) + { + UIDGenerator uidGen; + id = uidGen.GetUID(); + } + + std::map::iterator it = m_PropertyLists.find( id ); + if( it == m_PropertyLists.end() ) + { + propList = PropertyList::New(); + m_PropertyLists[id] = propList; + if( existed ) + *existed = false; + } + else + { + propList = (*it).second; + if( existed ) + *existed = true; + } + + return propList; } void mitk::PersistenceService::ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ) const { - to->Clear(); - - const std::map< std::string, BaseProperty::Pointer>* propMap = from->GetMap(); - std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin(); - while( propMapIt != propMap->end() ) - { - mitk::BaseProperty::Pointer clonedProp = (*propMapIt).second->Clone(); - to->SetProperty( (*propMapIt).first, clonedProp ); - ++propMapIt; - } + to->Clear(); + + const std::map< std::string, BaseProperty::Pointer>* propMap = from->GetMap(); + std::map< std::string, BaseProperty::Pointer>::const_iterator propMapIt = propMap->begin(); + while( propMapIt != propMap->end() ) + { + mitk::BaseProperty::Pointer clonedProp = (*propMapIt).second->Clone(); + to->SetProperty( (*propMapIt).first, clonedProp ); + ++propMapIt; + } } bool mitk::PersistenceService::Save(const std::string& fileName, bool appendChanges) { - bool save = false; - std::string theFile = fileName; - if(theFile.empty()) - theFile = PersistenceService::GetDefaultPersistenceFile(); - - bool xmlFile = false; - if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) - xmlFile = true; - - mitk::DataStorage::Pointer tempDs; - if( appendChanges ) - { - if(xmlFile == false) - { - if( itksys::SystemTools::FileExists(theFile.c_str()) ) - { - - bool load = false; - DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); - load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); - if( !load ) - return false; - - tempDs = ds; - - } - } - else - { - tempDs = mitk::StandaloneDataStorage::New(); - if( xmlFile && appendChanges && itksys::SystemTools::FileExists(theFile.c_str()) ) - { - if( !m_PropertyListsXmlFileReaderAndWriter->ReadLists( theFile, m_PropertyLists ) ) - return false; - } - } - - this->RestorePropertyListsFromPersistentDataNodes( tempDs ); - } - else if( xmlFile == false ) - { - tempDs = mitk::StandaloneDataStorage::New(); - } - - if( xmlFile ) - { - save = m_PropertyListsXmlFileReaderAndWriter->WriteLists(theFile, m_PropertyLists); - } - - else - { - DataStorage::SetOfObjects::Pointer sceneNodes = this->GetDataNodes(tempDs); - save = m_SceneIO->SaveScene( sceneNodes.GetPointer(), tempDs, theFile ); - } - if( save ) - { - long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); - m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; - } - - return save; + this->Initialize(); + bool save = false; + std::string theFile = fileName; + if(theFile.empty()) + theFile = PersistenceService::GetDefaultPersistenceFile(); + + bool xmlFile = false; + if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) + xmlFile = true; + + mitk::DataStorage::Pointer tempDs; + if( appendChanges ) + { + if(xmlFile == false) + { + if( itksys::SystemTools::FileExists(theFile.c_str()) ) + { + + bool load = false; + DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); + load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); + if( !load ) + return false; + + tempDs = ds; + + } + } + else + { + tempDs = mitk::StandaloneDataStorage::New(); + if( xmlFile && appendChanges && itksys::SystemTools::FileExists(theFile.c_str()) ) + { + if( !m_PropertyListsXmlFileReaderAndWriter->ReadLists( theFile, m_PropertyLists ) ) + return false; + } + } + + this->RestorePropertyListsFromPersistentDataNodes( tempDs ); + } + else if( xmlFile == false ) + { + tempDs = mitk::StandaloneDataStorage::New(); + } + + if( xmlFile ) + { + save = m_PropertyListsXmlFileReaderAndWriter->WriteLists(theFile, m_PropertyLists); + } + + else + { + DataStorage::SetOfObjects::Pointer sceneNodes = this->GetDataNodes(tempDs); + save = m_SceneIO->SaveScene( sceneNodes.GetPointer(), tempDs, theFile ); + } + if( save ) + { + long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); + m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; + } + + return save; } bool mitk::PersistenceService::Load(const std::string& fileName, bool enforceReload) { - bool load = false; - - std::string theFile = fileName; - if(theFile.empty()) - theFile = PersistenceService::GetDefaultPersistenceFile(); - - if( !itksys::SystemTools::FileExists(theFile.c_str()) ) - return false; - - bool xmlFile = false; - if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) - xmlFile = true; - - if( enforceReload == false ) - { - bool loadTheFile = true; - std::map::iterator it = m_FileNamesToModifiedTimes.find( theFile ); - - long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); - if( it != m_FileNamesToModifiedTimes.end() ) - { - long int knownModifiedTime = (*it).second; - if( knownModifiedTime >= currentModifiedTime ) - { - loadTheFile = false; - } - } - if( loadTheFile ) - m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; - else - return true; - } - - if( xmlFile ) - { - load = m_PropertyListsXmlFileReaderAndWriter->ReadLists(theFile, m_PropertyLists); - } - else - { - DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); - load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); - if( load ) - { - this->RestorePropertyListsFromPersistentDataNodes( ds ); - } - } - if( !load ) - { - MITK_DEBUG("mitk::PersistenceService") << "loading of scene files failed"; - return load; - } - - return load; + this->Initialize(); + bool load = false; + + std::string theFile = fileName; + if(theFile.empty()) + theFile = PersistenceService::GetDefaultPersistenceFile(); + + if( !itksys::SystemTools::FileExists(theFile.c_str()) ) + return false; + + bool xmlFile = false; + if( itksys::SystemTools::GetFilenameLastExtension(theFile.c_str()) == ".xml" ) + xmlFile = true; + + if( enforceReload == false ) + { + bool loadTheFile = true; + std::map::iterator it = m_FileNamesToModifiedTimes.find( theFile ); + + long int currentModifiedTime = itksys::SystemTools::ModifiedTime( theFile.c_str() ); + if( it != m_FileNamesToModifiedTimes.end() ) + { + long int knownModifiedTime = (*it).second; + if( knownModifiedTime >= currentModifiedTime ) + { + loadTheFile = false; + } + } + if( loadTheFile ) + m_FileNamesToModifiedTimes[theFile] = currentModifiedTime; + else + return true; + } + + if( xmlFile ) + { + load = m_PropertyListsXmlFileReaderAndWriter->ReadLists(theFile, m_PropertyLists); + } + else + { + DataStorage::Pointer ds = m_SceneIO->LoadScene( theFile ); + load = (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedNodes()->size() == 0) && (m_SceneIO->GetFailedNodes() == 0 || m_SceneIO->GetFailedProperties()->IsEmpty()); + if( load ) + { + this->RestorePropertyListsFromPersistentDataNodes( ds ); + } + } + if( !load ) + { + MITK_DEBUG("mitk::PersistenceService") << "loading of scene files failed"; + return load; + } + + return load; } void mitk::PersistenceService::SetAutoLoadAndSave(bool autoLoadAndSave) { - m_AutoLoadAndSave = autoLoadAndSave; - std::string id = PERSISTENCE_PROPERTYLIST_NAME; - mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); - propList->Set("m_AutoLoadAndSave", m_AutoLoadAndSave); - this->Save(); + this->Initialize(); + m_AutoLoadAndSave = autoLoadAndSave; + std::string id = PERSISTENCE_PROPERTYLIST_NAME; + mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); + propList->Set("m_AutoLoadAndSave", m_AutoLoadAndSave); + this->Save(); } void mitk::PersistenceService::AddPropertyListReplacedObserver(PropertyListReplacedObserver* observer) { - m_PropertyListReplacedObserver.insert( observer ); + this->Initialize(); + m_PropertyListReplacedObserver.insert( observer ); } void mitk::PersistenceService::RemovePropertyListReplacedObserver(PropertyListReplacedObserver* observer) { - m_PropertyListReplacedObserver.erase( observer ); + this->Initialize(); + m_PropertyListReplacedObserver.erase( observer ); } us::ModuleContext* mitk::PersistenceService::GetModuleContext() { - return us::GetModuleContext(); + return us::GetModuleContext(); } -std::string mitk::PersistenceService::GetPersistenceNodePropertyName() const +std::string mitk::PersistenceService::GetPersistenceNodePropertyName() { - return PERSISTENCE_PROPERTY_NAME; + this->Initialize(); + return PERSISTENCE_PROPERTY_NAME; } -mitk::DataStorage::SetOfObjects::Pointer mitk::PersistenceService::GetDataNodes(mitk::DataStorage* ds) const +mitk::DataStorage::SetOfObjects::Pointer mitk::PersistenceService::GetDataNodes(mitk::DataStorage* ds) { - DataStorage::SetOfObjects::Pointer set = DataStorage::SetOfObjects::New(); + this->Initialize(); + DataStorage::SetOfObjects::Pointer set = DataStorage::SetOfObjects::New(); - std::map::const_iterator it = m_PropertyLists.begin(); - while( it != m_PropertyLists.end() ) - { - mitk::DataNode::Pointer node = mitk::DataNode::New(); - const std::string& name = (*it).first; + std::map::const_iterator it = m_PropertyLists.begin(); + while( it != m_PropertyLists.end() ) + { + mitk::DataNode::Pointer node = mitk::DataNode::New(); + const std::string& name = (*it).first; - this->ClonePropertyList( (*it).second, node->GetPropertyList() ); + this->ClonePropertyList( (*it).second, node->GetPropertyList() ); - node->SetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), true ); - node->SetName( name ); + node->SetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), true ); + node->SetName( name ); - ds->Add(node); - set->push_back( node ); - ++it; - } + ds->Add(node); + set->push_back( node ); + ++it; + } - return set; + return set; } bool mitk::PersistenceService::RestorePropertyListsFromPersistentDataNodes( const DataStorage* storage ) { - bool oneFound = false; - DataStorage::SetOfObjects::ConstPointer allNodes = storage->GetAll(); - for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); - sourceIter != allNodes->end(); - ++sourceIter ) - { - mitk::DataNode* node = *sourceIter; - bool isPersistenceNode = false; - node->GetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), isPersistenceNode ); - - if( isPersistenceNode ) - { - oneFound = true; - MITK_DEBUG("mitk::PersistenceService") << "isPersistenceNode was true"; - std::string name = node->GetName(); - - bool existed = false; - mitk::PropertyList::Pointer propList = this->GetPropertyList( name, &existed ); - - if( existed ) - { - MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; - std::set::iterator it = m_PropertyListReplacedObserver.begin(); - while( it != m_PropertyListReplacedObserver.end() ) - { - (*it)->BeforePropertyListReplaced( name, propList ); - ++it; - } - } // if( existed ) - - MITK_DEBUG("mitk::PersistenceService") << "replacing values"; - - this->ClonePropertyList( node->GetPropertyList(), propList ); - - if( existed ) - { - MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; - std::set::iterator it = m_PropertyListReplacedObserver.begin(); - while( it != m_PropertyListReplacedObserver.end() ) - { - (*it)->AfterPropertyListReplaced( name, propList ); - ++it; - } - } // if( existed ) - } // if( isPersistenceNode ) - } // for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); ... - - return oneFound; + this->Initialize(); + bool oneFound = false; + DataStorage::SetOfObjects::ConstPointer allNodes = storage->GetAll(); + for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); + sourceIter != allNodes->end(); + ++sourceIter ) + { + mitk::DataNode* node = *sourceIter; + bool isPersistenceNode = false; + node->GetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), isPersistenceNode ); + + if( isPersistenceNode ) + { + oneFound = true; + MITK_DEBUG("mitk::PersistenceService") << "isPersistenceNode was true"; + std::string name = node->GetName(); + + bool existed = false; + mitk::PropertyList::Pointer propList = this->GetPropertyList( name, &existed ); + + if( existed ) + { + MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; + std::set::iterator it = m_PropertyListReplacedObserver.begin(); + while( it != m_PropertyListReplacedObserver.end() ) + { + (*it)->BeforePropertyListReplaced( name, propList ); + ++it; + } + } // if( existed ) + + MITK_DEBUG("mitk::PersistenceService") << "replacing values"; + + this->ClonePropertyList( node->GetPropertyList(), propList ); + + if( existed ) + { + MITK_DEBUG("mitk::PersistenceService") << "calling replace observer before replacing values"; + std::set::iterator it = m_PropertyListReplacedObserver.begin(); + while( it != m_PropertyListReplacedObserver.end() ) + { + (*it)->AfterPropertyListReplaced( name, propList ); + ++it; + } + } // if( existed ) + } // if( isPersistenceNode ) + } // for ( mitk::DataStorage::SetOfObjects::const_iterator sourceIter = allNodes->begin(); ... + + return oneFound; } -bool mitk::PersistenceService::GetAutoLoadAndSave() const +bool mitk::PersistenceService::GetAutoLoadAndSave() { - return m_AutoLoadAndSave; + this->Initialize(); + return m_AutoLoadAndSave; } bool mitk::PersistenceService::RemovePropertyList( std::string& id ) { - std::map::iterator it = m_PropertyLists.find( id ); - if( it != m_PropertyLists.end() ) - { - m_PropertyLists.erase(it); - return true; - } - return false; + this->Initialize(); + std::map::iterator it = m_PropertyLists.find( id ); + if( it != m_PropertyLists.end() ) + { + m_PropertyLists.erase(it); + return true; + } + return false; +} + +void mitk::PersistenceService::Initialize() +{ + if( m_Initialized || m_InInitialized) + return; + m_InInitialized = true; + + m_SceneIO = SceneIO::New(); + m_PropertyListsXmlFileReaderAndWriter = PropertyListsXmlFileReaderAndWriter::New(); + + // Load Default File in any case + this->Load(); + std::string id = mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME; + mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); + bool autoLoadAndSave = true; + propList->GetBoolProperty("m_AutoLoadAndSave", autoLoadAndSave); + + if( autoLoadAndSave == false ) + { + MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; + this->SetAutoLoadAndSave(false); + this->Clear(); + } + + m_InInitialized = false; + m_Initialized = true; +} + +void mitk::PersistenceService::Unitialize() +{ + if(this->GetAutoLoadAndSave()) + this->Save(); } diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h index e48775c725..1a1c6ff14f 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,76 +1,81 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkPersistenceService_h #define mitkPersistenceService_h #include "mitkIPersistenceService.h" #include "mitkPropertyListsXmlFileReaderAndWriter.h" #include #include "mitkSceneIO.h" namespace mitk { /// /// implementation of the IPersistenceService /// \see IPersistenceService class PersistenceService: public itk::LightObject, public mitk::IPersistenceService { public: static const std::string PERSISTENCE_PROPERTY_NAME; static const std::string PERSISTENCE_PROPERTYLIST_NAME; static us::ModuleContext* GetModuleContext(); PersistenceService(); ~PersistenceService(); - std::string GetDefaultPersistenceFile() const; + std::string GetDefaultPersistenceFile(); mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ); bool RemovePropertyList( std::string& id ); - std::string GetPersistenceNodePropertyName() const; + std::string GetPersistenceNodePropertyName(); - DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) const; + DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0); bool Save(const std::string& fileName="", bool appendChanges=false); bool Load(const std::string& fileName="", bool enforeReload=true); void SetAutoLoadAndSave(bool autoLoadAndSave); - bool GetAutoLoadAndSave() const; + bool GetAutoLoadAndSave(); void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); bool RestorePropertyListsFromPersistentDataNodes(const DataStorage* storage); void Clear(); + + void Unitialize(); private: void ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ) const; + void Initialize(); std::map m_PropertyLists; bool m_AutoLoadAndSave; std::set m_PropertyListReplacedObserver; SceneIO::Pointer m_SceneIO; PropertyListsXmlFileReaderAndWriter::Pointer m_PropertyListsXmlFileReaderAndWriter; std::map m_FileNamesToModifiedTimes; + bool m_Initialized; + bool m_InInitialized; }; } #endif