diff --git a/Modules/Persistence/Testing/mitkPersistenceTest.cpp b/Modules/Persistence/Testing/mitkPersistenceTest.cpp index 2ffdbff379..ace9971b72 100644 --- a/Modules/Persistence/Testing/mitkPersistenceTest.cpp +++ b/Modules/Persistence/Testing/mitkPersistenceTest.cpp @@ -1,65 +1,65 @@ /*=================================================================== 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 #include #include #include #include #include // redefine get module context macro #define PERSISTENCE_GET_MODULE_CONTEXT\ us::ModuleContext* context = mitk::PersistenceService::GetModuleContext(); struct PersistenceTestClass { PersistenceTestClass() : id(""), param1(1), param2(2), param3(false) { } std::string id; int param1; double param2; bool param3; PERSISTENCE_CREATE_SAVE3(id, param1, param2, param3) PERSISTENCE_CREATE_LOAD3(id, param1, param2, param3) }; int mitkPersistenceTest(int /*argc*/, char* /*argv*/[]) { MITK_TEST_BEGIN("PersistenceTest") PersistenceTestClass testClass; testClass.id = "testClass"; testClass.param1 = 100; testClass.param2 = 200.56; testClass.param3 = true; MITK_TEST_CONDITION_REQUIRED( testClass.Save(), "testClass.Save()"); PersistenceTestClass testClass2; - testClass.id = "testClass"; - MITK_TEST_CONDITION_REQUIRED( testClass2.Load(), "testClass.Save()"); + testClass2.id = "testClass"; + MITK_TEST_CONDITION_REQUIRED( testClass2.Load(), "testClass.Load()"); MITK_TEST_CONDITION_REQUIRED( testClass.param1 == testClass2.param1, "testClass.param1 == testClass2.param1" ); MITK_TEST_CONDITION_REQUIRED( testClass.param2 == testClass2.param2, "testClass.param2 == testClass2.param2" ); MITK_TEST_CONDITION_REQUIRED( testClass.param3 == testClass2.param3, "testClass.param3 == testClass2.param3" ); MITK_TEST_END() } diff --git a/Modules/Persistence/mitkIPersistenceService.h b/Modules/Persistence/mitkIPersistenceService.h index 4b12426478..f666f84251 100644 --- a/Modules/Persistence/mitkIPersistenceService.h +++ b/Modules/Persistence/mitkIPersistenceService.h @@ -1,190 +1,179 @@ /*=================================================================== 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 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 Persistence_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; /// /// Save the current PropertyLists to fileName. If fileName is empty, a special file in the users home directory will be used. /// \return false if an error occured (cannot write to file), true otherwise /// virtual bool Save(const std::string& fileName="") = 0; /// /// Load PropertyLists from fileName. If fileName is empty, a special file in the users home directory will be used. /// *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="") = 0; /// /// Using SetAutoLoadAndSave(true) will cause the service to load/save the property lists at application /// start/stop. /// virtual void SetAutoLoadAndSave(bool autoLoadAndSave) = 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\ us::ModuleContext* context = GetModuleContext(); #define PERSISTENCE_GET_SERVICE\ PERSISTENCE_GET_MODULE_CONTEXT\ us::ServiceReference persistenceServiceRef = context->GetServiceReference();\ mitk::IPersistenceService* persistenceService = dynamic_cast ( context->GetService(persistenceServiceRef) ); #define PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ bool Save() { \ PERSISTENCE_GET_SERVICE\ bool noError = persistenceService != 0;\ mitk::PropertyList::Pointer propList;\ if( noError ) {\ propList = persistenceService->GetPropertyList(IdMemberName); #define PERSISTENCE_CREATE_SAVE_END\ }\ noError = persistenceService->Save();\ return noError;\ } #define PERSISTENCE_CREATE_SAVE(IdMemberName, ParamMemberName)\ PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( "ParamMemberName", ParamMemberName );\ + propList->Set( #ParamMemberName, ParamMemberName );\ PERSISTENCE_CREATE_SAVE_END -#define PERSISTENCE_CREATE_SAVE2(IdMemberName, ParamMemberName, ParamMember2Name)\ +#define PERSISTENCE_CREATE_SAVE2(IdMemberName, ParamMemberName, Param2MemberName)\ PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( "ParamMemberName", ParamMemberName );\ - propList->Set( "ParamMember2Name", ParamMember2Name );\ + propList->Set( #ParamMemberName, ParamMemberName );\ + propList->Set( #Param2MemberName, Param2MemberName );\ PERSISTENCE_CREATE_SAVE_END -#define PERSISTENCE_CREATE_SAVE3(IdMemberName, ParamMemberName, ParamMember2Name, ParamMember3Name)\ +#define PERSISTENCE_CREATE_SAVE3(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName)\ PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( "ParamMemberName", ParamMemberName );\ - propList->Set( "ParamMember2Name", ParamMember2Name );\ - propList->Set( "ParamMember3Name", ParamMember3Name );\ + propList->Set( #ParamMemberName, ParamMemberName );\ + propList->Set( #Param2MemberName, Param2MemberName );\ + propList->Set( #Param3MemberName, Param3MemberName );\ PERSISTENCE_CREATE_SAVE_END -#define PERSISTENCE_CREATE_SAVE4(IdMemberName, ParamMemberName, ParamMember2Name, ParamMember3Name, ParamMember4Name)\ +#define PERSISTENCE_CREATE_SAVE4(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName, Param4MemberName)\ PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( "ParamMemberName", ParamMemberName );\ - propList->Set( "ParamMember2Name", ParamMember2Name );\ - propList->Set( "ParamMember3Name", ParamMember3Name );\ - propList->Set( "ParamMember4Name", ParamMember4Name );\ - PERSISTENCE_CREATE_SAVE_END - -#define PERSISTENCE_CREATE_SAVE5(IdMemberName, ParamMemberName, ParamMember2Name, ParamMember3Name, Param4Name, ParamMember5Name)\ - PERSISTENCE_CREATE_SAVE_START(IdMemberName)\ - propList->Set( "ParamMemberName", ParamMemberName );\ - propList->Set( "ParamMember2Name", ParamMember2Name );\ - propList->Set( "ParamMember3Name", ParamMember3Name );\ - propList->Set( "ParamMember4Name", ParamMember4Name );\ - propList->Set( "ParamMember5Name", ParamMember5Name );\ + propList->Set( #ParamMemberName, ParamMemberName );\ + propList->Set( #Param2MemberName, Param2MemberName );\ + propList->Set( #Param3MemberName, Param3MemberName );\ + propList->Set( #Param4MemberName, Param4MemberName );\ PERSISTENCE_CREATE_SAVE_END /// MACROS FOR AUTOMATIC LOAD FUNCTION #define PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ bool Load() {\ PERSISTENCE_GET_SERVICE\ bool noError = persistenceService != 0 && persistenceService->Load();\ - if( noError ) { + if( noError ) {\ + mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName); #define PERSISTENCE_CREATE_LOAD_END\ }\ return noError;\ } #define PERSISTENCE_CREATE_LOAD(IdMemberName, ParamMemberName)\ PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName);\ - noError = propList->Get( "ParamMemberName", ParamMemberName );\ + noError = propList->Get( #ParamMemberName, ParamMemberName );\ PERSISTENCE_CREATE_LOAD_END #define PERSISTENCE_CREATE_LOAD2(IdMemberName, ParamMemberName, Param2MemberName)\ PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName);\ - noError = propList->Get( "ParamMemberName", ParamMemberName );\ + noError = propList->Get( #ParamMemberName, ParamMemberName );\ if(noError)\ - noError = propList->Get( "Param2MemberName", Param2MemberName );\ + noError = propList->Get( #Param2MemberName, Param2MemberName );\ PERSISTENCE_CREATE_LOAD_END #define PERSISTENCE_CREATE_LOAD3(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName)\ PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName);\ - noError = propList->Get( "ParamMemberName", ParamMemberName );\ + noError = propList->Get( #ParamMemberName, ParamMemberName );\ if(noError)\ - noError = propList->Get( "Param2MemberName", Param2MemberName );\ + noError = propList->Get( #Param2MemberName, Param2MemberName );\ if(noError)\ - noError = propList->Get( "Param3MemberName", Param3MemberName );\ + noError = propList->Get( #Param3MemberName, Param3MemberName );\ PERSISTENCE_CREATE_LOAD_END #define PERSISTENCE_CREATE_LOAD4(IdMemberName, ParamMemberName, Param2MemberName, Param3MemberName, Param4MemberName)\ PERSISTENCE_CREATE_LOAD_START(IdMemberName)\ - mitk::PropertyList::Pointer propList = persistenceService->GetPropertyList(IdMemberName);\ - noError = propList->Get( "ParamMemberName", ParamMemberName );\ + noError = propList->Get( #ParamMemberName, ParamMemberName );\ if(noError)\ - noError = propList->Get( "Param2MemberName", Param2MemberName );\ + noError = propList->Get( #Param2MemberName, Param2MemberName );\ if(noError)\ - noError = propList->Get( "Param3MemberName", Param3MemberName );\ + noError = propList->Get( #Param3MemberName, Param3MemberName );\ if(noError)\ - noError = propList->Get( "Param4MemberName", Param4MemberName );\ + noError = propList->Get( #Param4MemberName, Param4MemberName );\ PERSISTENCE_CREATE_LOAD_END US_DECLARE_SERVICE_INTERFACE(mitk::IPersistenceService, "org.mitk.services.IPersistenceService") #endif diff --git a/Modules/Persistence/mitkPersistenceService.cpp b/Modules/Persistence/mitkPersistenceService.cpp index 68e964b925..ad0fd4e1a8 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,216 +1,226 @@ /*=================================================================== 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 std::string mitk::PersistenceService::CreateDefaultFileName() { std::string homeDir = Poco::Path::home(); std::string file = homeDir + "PersistenceService.mitk"; return file; } const std::string mitk::PersistenceService::DEFAULT_FILE_NAME(CreateDefaultFileName()); const std::string mitk::PersistenceService::PERSISTENCE_PROPERTY_NAME("PersistenceNode"); const std::string mitk::PersistenceService::PERSISTENCE_PROPERTYLIST_NAME("PersistenceService"); +const std::string mitk::PersistenceService::ID_PROPERTY_NAME("Id"); + mitk::PersistenceService::PersistenceService() : m_AutoLoadAndSave( false ), m_SceneIO( SceneIO::New() ) { { MITK_DEBUG("mitk::PersistenceService") << "constructing PersistenceService"; } MITK_DEBUG("mitk::PersistenceService") << "loading PersistenceService personal persitent data"; this->Load( DEFAULT_FILE_NAME ); std::string id = PERSISTENCE_PROPERTYLIST_NAME; mitk::PropertyList::Pointer propList = this->GetPropertyList( id ); propList->GetBoolProperty("m_AutoLoadAndSave", m_AutoLoadAndSave); if( m_AutoLoadAndSave == false ) { MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; m_PropertyLists.clear(); } } mitk::PersistenceService::~PersistenceService() { MITK_DEBUG("mitk::PersistenceService") << "destructing PersistenceService"; } 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; } void mitk::PersistenceService::ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ) { 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() ) { - to->SetProperty( (*propMapIt).first, (*propMapIt).second->Clone() ); + mitk::BaseProperty::Pointer clonedProp = (*propMapIt).second->Clone(); + to->SetProperty( (*propMapIt).first, clonedProp ); ++propMapIt; } } bool mitk::PersistenceService::Save(const std::string& fileName) { bool save = false; mitk::StandaloneDataStorage::Pointer tempDs = mitk::StandaloneDataStorage::New(); std::map::iterator it = m_PropertyLists.begin(); while( it != m_PropertyLists.end() ) { mitk::DataNode::Pointer newNode = mitk::DataNode::New(); this->ClonePropertyList( (*it).second, newNode->GetPropertyList() ); newNode->SetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), true ); newNode->SetName( (*it).first ); + newNode->SetStringProperty(ID_PROPERTY_NAME.c_str(),(*it).first.c_str() ); tempDs->Add(newNode); ++it; } mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New(PERSISTENCE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); mitk::DataStorage::SetOfObjects::ConstPointer rs = tempDs->GetSubset(pred); - return m_SceneIO->SaveScene( rs, tempDs, fileName ); + std::string theFile = fileName; + if(theFile.empty()) + theFile = DEFAULT_FILE_NAME; + return m_SceneIO->SaveScene( rs, tempDs, theFile ); } bool mitk::PersistenceService::Load(const std::string& fileName) { bool load = false; - DataStorage::Pointer ds = m_SceneIO->LoadScene( fileName ); - load = m_SceneIO->GetFailedNodes() == 0 && m_SceneIO->GetFailedProperties() == 0; + std::string theFile = fileName; + if(theFile.empty()) + theFile = DEFAULT_FILE_NAME; + 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 ) { MITK_DEBUG("mitk::PersistenceService") << "loading of scene files failed"; return load; } DataStorage::SetOfObjects::ConstPointer allNodes = ds->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 ) { 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 ); - propList->SetStringProperty("Id", name.c_str()); + propList->SetStringProperty(ID_PROPERTY_NAME.c_str(), name.c_str()); 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 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(); } void mitk::PersistenceService::AddPropertyListReplacedObserver(PropertyListReplacedObserver* observer) { m_PropertyListReplacedObserver.insert( observer ); } void mitk::PersistenceService::RemovePropertyListReplacedObserver(PropertyListReplacedObserver* observer) { m_PropertyListReplacedObserver.erase( observer ); } us::ModuleContext* mitk::PersistenceService::GetModuleContext() { return us::GetModuleContext(); } diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h index 75ae6abe88..cad2c3eac6 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,60 +1,61 @@ /*=================================================================== 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 #include "mitkSceneIO.h" namespace mitk { /// /// implementation of the IPersistenceService /// \see IPersistenceService class Persistence_EXPORT PersistenceService: public itk::LightObject, public mitk::IPersistenceService { public: static std::string CreateDefaultFileName(); static const std::string DEFAULT_FILE_NAME; static const std::string PERSISTENCE_PROPERTY_NAME; static const std::string PERSISTENCE_PROPERTYLIST_NAME; + static const std::string ID_PROPERTY_NAME; static us::ModuleContext* GetModuleContext(); PersistenceService(); ~PersistenceService(); mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ); bool Save(const std::string& fileName=""); bool Load(const std::string& fileName=""); void SetAutoLoadAndSave(bool autoLoadAndSave); void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); private: void ClonePropertyList( mitk::PropertyList* from, mitk::PropertyList* to ); std::map m_PropertyLists; bool m_AutoLoadAndSave; std::set m_PropertyListReplacedObserver; SceneIO::Pointer m_SceneIO; }; } #endif