diff --git a/Modules/Persistence/mitkPersistenceActivator.cpp b/Modules/Persistence/mitkPersistenceActivator.cpp index d8865e3a9f..d1c30b1ca8 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: 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"); + us::ServiceReference persistenceServiceRef + = context->GetServiceReference(); - m_PersistenceServiceRegistration = context->RegisterService(m_PersistenceService, _PersistenceServiceProps); - - // 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); - - if( autoLoadAndSave == false ) + if( ! persistenceServiceRef ) { + // 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); + + // 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); + + if( autoLoadAndSave == false ) + { MITK_DEBUG("mitk::PersistenceService") << "autoloading was not wished. clearing data we got so far."; m_PersistenceService->SetAutoLoadAndSave(false); m_PersistenceService->Clear(); + } + } + else + { + MITK_WARN << "Another Persistence service already installed." } - } void Unload(us::ModuleContext* context) { 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_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..c5faf0b42c 100644 --- a/Modules/Persistence/mitkPersistenceService.cpp +++ b/Modules/Persistence/mitkPersistenceService.cpp @@ -1,340 +1,352 @@ /*=================================================================== 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) { } void mitk::PersistenceService::Clear() { m_PropertyLists.clear(); m_FileNamesToModifiedTimes.clear(); } mitk::PersistenceService::~PersistenceService() { MITK_DEBUG("mitk::PersistenceService") << "destructing PersistenceService"; } std::string mitk::PersistenceService::GetDefaultPersistenceFile() const { 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; } 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; } } 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; } 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; } 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(); } std::string mitk::PersistenceService::GetPersistenceNodePropertyName() const { return PERSISTENCE_PROPERTY_NAME; } mitk::DataStorage::SetOfObjects::Pointer mitk::PersistenceService::GetDataNodes(mitk::DataStorage* ds) const { 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; this->ClonePropertyList( (*it).second, node->GetPropertyList() ); node->SetBoolProperty( PERSISTENCE_PROPERTY_NAME.c_str(), true ); node->SetName( name ); ds->Add(node); set->push_back( node ); ++it; } 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; } bool mitk::PersistenceService::GetAutoLoadAndSave() const { 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; } + +void mitk::PersistenceService::Initialize() +{ + if( m_Initialized ) + return; + + m_SceneIO = SceneIO::New(); + m_PropertyListsXmlFileReaderAndWriter = PropertyListsXmlFileReaderAndWriter::New(); + this->Load(); + + m_Initialized = true; +} diff --git a/Modules/Persistence/mitkPersistenceService.h b/Modules/Persistence/mitkPersistenceService.h index e48775c725..8b3e57dc9d 100644 --- a/Modules/Persistence/mitkPersistenceService.h +++ b/Modules/Persistence/mitkPersistenceService.h @@ -1,76 +1,78 @@ /*=================================================================== 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; mitk::PropertyList::Pointer GetPropertyList( std::string& id, bool* existed=0 ); bool RemovePropertyList( std::string& id ); std::string GetPersistenceNodePropertyName() const; DataStorage::SetOfObjects::Pointer GetDataNodes(DataStorage* ds=0) const; 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; void AddPropertyListReplacedObserver( PropertyListReplacedObserver* observer ); void RemovePropertyListReplacedObserver( PropertyListReplacedObserver* observer ); bool RestorePropertyListsFromPersistentDataNodes(const DataStorage* storage); void Clear(); 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; }; } #endif