diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index 2efe3c5dc2..88b8bb3e09 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,325 +1,328 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCoreActivator.cpp mitkCoreObjectFactoryBase.cpp mitkCoreObjectFactory.cpp mitkCoreServices.cpp mitkException.cpp Algorithms/mitkBaseDataSource.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkIPersistenceService.cpp DataManagement/mitkIPropertyAliases.cpp DataManagement/mitkIPropertyDescriptions.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp + DataManagement/mitkIPropertyPersistence.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyObserver.cpp + DataManagement/mitkPropertyPersistence.cpp + DataManagement/mitkPropertyPersistenceInfo.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkShaderProperty.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEvent.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkState.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkWheelEvent.cpp Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSeriesReaderService.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkImageGenerator.cpp IO/mitkImageVtkLegacyIO.cpp IO/mitkImageVtkXmlIO.cpp IO/mitkIMimeTypeProvider.cpp IO/mitkIOConstants.cpp IO/mitkIOMimeTypes.cpp IO/mitkIOUtil.cpp IO/mitkItkImageIO.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkLegacyFileReaderService.cpp IO/mitkLegacyFileWriterService.cpp IO/mitkLog.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkVtkLoggingAdapter.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkIShaderRepository.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkOverlay.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/Core/include/mitkCoreServices.h b/Modules/Core/include/mitkCoreServices.h index dbd712f011..932ca0acd0 100644 --- a/Modules/Core/include/mitkCoreServices.h +++ b/Modules/Core/include/mitkCoreServices.h @@ -1,179 +1,187 @@ /*=================================================================== 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 MITKCORESERVICES_H #define MITKCORESERVICES_H #include "MitkCoreExports.h" #include #include #include #include #include #include #include namespace mitk { struct IMimeTypeProvider; struct IShaderRepository; class IPropertyAliases; class IPropertyDescriptions; class IPropertyExtensions; class IPropertyFilters; +class IPropertyPersistence; /** * @brief Access MITK core services. * * This class can be used to conveniently access common * MITK Core service objects. Some getter methods where implementations * exist in the core library are guaranteed to return a non-NULL service object. * * To ensure that CoreServices::Unget() is called after the caller * has finished using a service object, you should use the CoreServicePointer * helper class which calls Unget() when it goes out of scope: * * \code * CoreServicePointer shaderRepo(CoreServices::GetShaderRepository()); * // Do something with shaderRepo * \endcode * * @see CoreServicePointer */ class MITKCORE_EXPORT CoreServices { public: /** * @brief Get an IShaderRepository instance. * @param context The module context of the module getting the service. * @return A IShaderRepository instance which can be NULL. */ static IShaderRepository* GetShaderRepository(); /** * @brief Get an IPropertyAliases instance. * @param context The module context of the module getting the service. * @return A non-NULL IPropertyAliases instance. */ static IPropertyAliases* GetPropertyAliases(us::ModuleContext* context = us::GetModuleContext()); /** * @brief Get an IPropertyDescriptions instance. * @param context The module context of the module getting the service. * @return A non-NULL IPropertyDescriptions instance. */ static IPropertyDescriptions* GetPropertyDescriptions(us::ModuleContext* context = us::GetModuleContext()); /** * @brief Get an IPropertyExtensions instance. * @param context The module context of the module getting the service. * @return A non-NULL IPropertyExtensions instance. */ static IPropertyExtensions* GetPropertyExtensions(us::ModuleContext* context = us::GetModuleContext()); /** * @brief Get an IPropertyFilters instance. * @param context The module context of the module getting the service. * @return A non-NULL IPropertyFilters instance. */ static IPropertyFilters* GetPropertyFilters(us::ModuleContext* context = us::GetModuleContext()); + /** + * @brief Get an IPropertyPersistence instance. + * @param context The module context of the module getting the service. + * @return A non-NULL IPropertyPersistence instance. + */ + static IPropertyPersistence* GetPropertyPersistence(us::ModuleContext* context = us::GetModuleContext()); + /** * @brief Get an IMimeTypeProvider instance. * @param context The module context of the module getting the service. * @return A non-NULL IMimeTypeProvider instance. */ static IMimeTypeProvider* GetMimeTypeProvider(us::ModuleContext* context = us::GetModuleContext()); /** * @brief Unget a previously acquired service instance. * @param service The service instance to be released. * @return \c true if ungetting the service was successful, \c false otherwise. */ template static bool Unget(S* service, us::ModuleContext* context = us::GetModuleContext()) { return Unget(context, us_service_interface_iid(), service); } private: static bool Unget(us::ModuleContext* context, const std::string& interfaceId, void* service); // purposely not implemented CoreServices(); CoreServices(const CoreServices&); CoreServices& operator=(const CoreServices&); }; /** * @brief A RAII helper class for core service objects. * * This is class is intended for usage in local scopes; it calls * CoreServices::Unget(S*) in its destructor. You should not construct * multiple CoreServicePointer instances using the same service pointer, * unless it is retrieved by a new call to a CoreServices getter method. * * @see CoreServices */ template class MITK_LOCAL CoreServicePointer { public: explicit CoreServicePointer(S* service) : m_service(service) { assert(m_service); } ~CoreServicePointer() { try { CoreServices::Unget(m_service); } catch (const std::exception& e) { MITK_ERROR << e.what(); } catch (...) { MITK_ERROR << "Ungetting core service failed."; } } S* operator->() const { return m_service; } private: // purposely not implemented CoreServicePointer(const CoreServicePointer&); CoreServicePointer& operator=(const CoreServicePointer&); S* const m_service; }; } #endif // MITKCORESERVICES_H diff --git a/Modules/Core/include/mitkIPropertyPersistence.h b/Modules/Core/include/mitkIPropertyPersistence.h new file mode 100644 index 0000000000..14a0abdf9d --- /dev/null +++ b/Modules/Core/include/mitkIPropertyPersistence.h @@ -0,0 +1,73 @@ +/*=================================================================== + +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 mitkIPropertyPersistence_h +#define mitkIPropertyPersistence_h + +#include +#include + +namespace mitk +{ + /** \ingroup MicroServices_Interfaces + * \brief Interface of property persistence service + * + * This service allows you to manage persistence info for base data properties. + * Persistent properties will be saved if the file format supports custom key value pairs like the .nrrd file format. + */ + class MITKCORE_EXPORT IPropertyPersistence + { + public: + virtual ~IPropertyPersistence(); + + /** \brief Add persistence info for a specific base data property. + * + * \param[in] propertyName Name of the property. + * \param[in] info Persistence info of the property. + * \param[in] overwrite Overwrite already existing persistence info. + * \return True if persistence info was added successfully. + */ + virtual bool AddInfo(const std::string& propertyName, PropertyPersistenceInfo::Pointer info, bool overwrite = false) = 0; + + /** \brief Get the persistence info for a specific base data property. + * + * \param[in] propertyName Name of the property. + * \return Property persistence info or null pointer if no persistence info is available. + */ + virtual PropertyPersistenceInfo::Pointer GetInfo(const std::string& propertyName) = 0; + + /** \brief Check if a specific base data property has persistence info. + * + * \param[in] propertyName Name of the property. + * \return True if the property has persistence info, false otherwise. + */ + virtual bool HasInfo(const std::string& propertyName) = 0; + + /** \brief Remove all persistence info. + */ + virtual void RemoveAllInfos() = 0; + + /** \brief Remove persistence info of a specific base data property. + * + * \param[in] propertyName Name of the property. + */ + virtual void RemoveInfo(const std::string& propertyName) = 0; + }; +} + +MITK_DECLARE_SERVICE_INTERFACE(mitk::IPropertyPersistence, "org.mitk.IPropertyPersistence") + +#endif diff --git a/Modules/Core/include/mitkPropertyPersistence.h b/Modules/Core/include/mitkPropertyPersistence.h new file mode 100644 index 0000000000..fe15c5dd2d --- /dev/null +++ b/Modules/Core/include/mitkPropertyPersistence.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 mitkPropertyPersistence_h +#define mitkPropertyPersistence_h + +#include +#include + +namespace mitk +{ + class PropertyPersistence : public IPropertyPersistence + { + public: + PropertyPersistence(); + ~PropertyPersistence(); + + bool AddInfo(const std::string& propertyName, PropertyPersistenceInfo::Pointer info, bool overwrite) override; + PropertyPersistenceInfo::Pointer GetInfo(const std::string& propertyName) override; + bool HasInfo(const std::string& propertyName) override; + void RemoveAllInfos() override; + void RemoveInfo(const std::string& propertyName) override; + + private: + typedef std::map InfoMap; + typedef InfoMap::const_iterator InfoMapConstIterator; + typedef InfoMap::iterator InfoMapIterator; + + PropertyPersistence(const PropertyPersistence&); + PropertyPersistence& operator=(const PropertyPersistence&); + + InfoMap m_Infos; + }; +} + +#endif diff --git a/Modules/Core/include/mitkPropertyPersistenceInfo.h b/Modules/Core/include/mitkPropertyPersistenceInfo.h new file mode 100644 index 0000000000..47ca2aa97c --- /dev/null +++ b/Modules/Core/include/mitkPropertyPersistenceInfo.h @@ -0,0 +1,57 @@ +/*=================================================================== + +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 mitkPropertyPersistenceInfo_h +#define mitkPropertyPersistenceInfo_h + +#include +#include +#include + +namespace mitk +{ + /** \brief Property persistence info. + */ + class MITKCORE_EXPORT PropertyPersistenceInfo : public itk::LightObject + { + public: + mitkClassMacroItkParent(PropertyPersistenceInfo, itk::LightObject); + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + mitkNewMacro1Param(Self, const std::string&); + + std::string GetKey() const; + void SetKey(const std::string& key); + + protected: + /** \brief Constructor. + * + * \param[in] key Key used to save the property value as key value pair. If empty, the property name is used. + */ + PropertyPersistenceInfo(const std::string& key = ""); + + virtual ~PropertyPersistenceInfo(); + + private: + PropertyPersistenceInfo(const Self& other); + Self& operator=(const Self& other); + + struct Impl; + Impl* m_Impl; + }; +} + +#endif diff --git a/Modules/Core/src/DataManagement/mitkIPropertyPersistence.cpp b/Modules/Core/src/DataManagement/mitkIPropertyPersistence.cpp new file mode 100644 index 0000000000..1b95eead05 --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkIPropertyPersistence.cpp @@ -0,0 +1,21 @@ +/*=================================================================== + +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 "mitkIPropertyPersistence.h" + +mitk::IPropertyPersistence::~IPropertyPersistence() +{ +} diff --git a/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp b/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp new file mode 100644 index 0000000000..a439cb2b37 --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp @@ -0,0 +1,74 @@ +/*=================================================================== + +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 + +mitk::PropertyPersistence::PropertyPersistence() +{ +} + +mitk::PropertyPersistence::~PropertyPersistence() +{ +} + +bool mitk::PropertyPersistence::AddInfo(const std::string& propertyName, PropertyPersistenceInfo::Pointer info, bool overwrite) +{ + if (propertyName.empty()) + return false; + + auto ret = m_Infos.insert(std::make_pair(propertyName, info)); + + if (!ret.second && overwrite) + { + ret.first->second = info; + ret.second = true; + } + + return ret.second; +} + +mitk::PropertyPersistenceInfo::Pointer mitk::PropertyPersistence::GetInfo(const std::string& propertyName) +{ + if (!propertyName.empty()) + { + InfoMapConstIterator iter = m_Infos.find(propertyName); + + if (iter != m_Infos.cend()) + return iter->second; + } + + return nullptr; +} + +bool mitk::PropertyPersistence::HasInfo(const std::string& propertyName) +{ + return !propertyName.empty() + ? m_Infos.find(propertyName) != m_Infos.cend() + : false; +} + +void mitk::PropertyPersistence::RemoveAllInfos() +{ + m_Infos.clear(); +} + +void mitk::PropertyPersistence::RemoveInfo(const std::string& propertyName) +{ + if (!propertyName.empty()) + m_Infos.erase(propertyName); +} diff --git a/Modules/Core/src/DataManagement/mitkPropertyPersistenceInfo.cpp b/Modules/Core/src/DataManagement/mitkPropertyPersistenceInfo.cpp new file mode 100644 index 0000000000..5ad5254357 --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkPropertyPersistenceInfo.cpp @@ -0,0 +1,57 @@ +/*=================================================================== + +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 + +namespace mitk +{ + struct PropertyPersistenceInfo::Impl + { + explicit Impl(const std::string& key); + ~Impl(); + + std::string Key; + }; + + PropertyPersistenceInfo::Impl::Impl(const std::string& key) + : Key(key) + { + } + + PropertyPersistenceInfo::Impl::~Impl() + { + } +} + +mitk::PropertyPersistenceInfo::PropertyPersistenceInfo(const std::string& key) + : m_Impl(new Impl(key)) +{ +} + +mitk::PropertyPersistenceInfo::~PropertyPersistenceInfo() +{ + delete m_Impl; +} + +std::string mitk::PropertyPersistenceInfo::GetKey() const +{ + return m_Impl->Key; +} + +void mitk::PropertyPersistenceInfo::SetKey(const std::string& key) +{ + m_Impl->Key = key; +} diff --git a/Modules/Core/src/mitkCoreActivator.cpp b/Modules/Core/src/mitkCoreActivator.cpp index 967bcfd675..7fbb056a56 100644 --- a/Modules/Core/src/mitkCoreActivator.cpp +++ b/Modules/Core/src/mitkCoreActivator.cpp @@ -1,461 +1,464 @@ /*=================================================================== 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 "mitkCoreActivator.h" // File IO #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkLegacyFileWriterService.h" #include "mitkDicomSeriesReaderService.h" #include #include // Micro Services #include #include #include #include #include #include #include #include #include #include // ITK "injects" static initialization code for IO factories // via the itkImageIOFactoryRegisterManager.h header (which // is generated in the application library build directory). // To ensure that the code is called *before* the CppMicroServices // static initialization code (which triggers the Activator::Start // method), we include the ITK header here. #include void HandleMicroServicesMessages(us::MsgType type, const char* msg) { switch (type) { case us::DebugMsg: MITK_DEBUG << msg; break; case us::InfoMsg: MITK_INFO << msg; break; case us::WarningMsg: MITK_WARN << msg; break; case us::ErrorMsg: MITK_ERROR << msg; break; } } void AddMitkAutoLoadPaths(const std::string& programPath) { us::ModuleSettings::AddAutoLoadPath(programPath); #ifdef __APPLE__ // Walk up three directories since that is where the .dylib files are located // for build trees. std::string additionalPath = programPath; bool addPath = true; for(int i = 0; i < 3; ++i) { std::size_t index = additionalPath.find_last_of('/'); if (index != std::string::npos) { additionalPath = additionalPath.substr(0, index); } else { addPath = false; break; } } if (addPath) { us::ModuleSettings::AddAutoLoadPath(additionalPath); } #endif } class ShaderRepositoryTracker : public us::ServiceTracker { public: ShaderRepositoryTracker() : Superclass(us::GetModuleContext()) { } virtual void Close() override { us::GetModuleContext()->RemoveModuleListener(this, &ShaderRepositoryTracker::HandleModuleEvent); Superclass::Close(); } virtual void Open() override { us::GetModuleContext()->AddModuleListener(this, &ShaderRepositoryTracker::HandleModuleEvent); Superclass::Open(); } private: typedef us::ServiceTracker Superclass; TrackedType AddingService(const ServiceReferenceType &reference) override { mitk::IShaderRepository* shaderRepo = Superclass::AddingService(reference); if (shaderRepo) { // Add all existing shaders from modules to the new shader repository. // If the shader repository is registered in a modules activator, the // GetLoadedModules() function call below will also return the module // which is currently registering the repository. The HandleModuleEvent // method contains code to avoid double registrations due to a fired // ModuleEvent::LOADED event after the activators Load() method finished. std::vector modules = us::ModuleRegistry::GetLoadedModules(); for (std::vector::const_iterator iter = modules.begin(), endIter = modules.end(); iter != endIter; ++iter) { this->AddModuleShaderToRepository(*iter, shaderRepo); } m_ShaderRepositories.push_back(shaderRepo); } return shaderRepo; } void RemovedService(const ServiceReferenceType& /*reference*/, TrackedType tracked) override { m_ShaderRepositories.erase(std::remove(m_ShaderRepositories.begin(), m_ShaderRepositories.end(), tracked), m_ShaderRepositories.end()); } void HandleModuleEvent(const us::ModuleEvent moduleEvent) { if (moduleEvent.GetType() == us::ModuleEvent::LOADED) { std::vector shaderRepos; for (std::map > >::const_iterator shaderMapIter = m_ModuleIdToShaderIds.begin(), shaderMapEndIter = m_ModuleIdToShaderIds.end(); shaderMapIter != shaderMapEndIter; ++shaderMapIter) { if (shaderMapIter->second.find(moduleEvent.GetModule()->GetModuleId()) == shaderMapIter->second.end()) { shaderRepos.push_back(shaderMapIter->first); } } AddModuleShadersToRepositories(moduleEvent.GetModule(), shaderRepos); } else if (moduleEvent.GetType() == us::ModuleEvent::UNLOADED) { RemoveModuleShadersFromRepositories(moduleEvent.GetModule(), m_ShaderRepositories); } } void AddModuleShadersToRepositories(us::Module* module, const std::vector& shaderRepos) { // search and load shader files std::vector shaderResources = module->FindResources("Shaders", "*.xml", true); for (std::vector::iterator i = shaderResources.begin(); i != shaderResources.end(); ++i) { if (*i) { us::ModuleResourceStream rs(*i); for (const auto & shaderRepo : shaderRepos) { int id = (shaderRepo)->LoadShader(rs, i->GetBaseName()); if (id >= 0) { m_ModuleIdToShaderIds[shaderRepo][module->GetModuleId()].push_back(id); } } rs.seekg(0, std::ios_base::beg); } } } void AddModuleShaderToRepository(us::Module* module, mitk::IShaderRepository* shaderRepo) { std::vector shaderRepos; shaderRepos.push_back(shaderRepo); this->AddModuleShadersToRepositories(module, shaderRepos); } void RemoveModuleShadersFromRepositories(us::Module* module, const std::vector& shaderRepos) { for (const auto & shaderRepo : shaderRepos) { std::map >& moduleIdToShaderIds = m_ModuleIdToShaderIds[shaderRepo]; std::map >::iterator shaderIdsIter = moduleIdToShaderIds.find(module->GetModuleId()); if (shaderIdsIter != moduleIdToShaderIds.end()) { for (std::vector::iterator idIter = shaderIdsIter->second.begin(); idIter != shaderIdsIter->second.end(); ++idIter) { (shaderRepo)->UnloadShader(*idIter); } moduleIdToShaderIds.erase(shaderIdsIter); } } } private: // Maps to each shader repository a map containing module ids and related // shader registration ids std::map > > m_ModuleIdToShaderIds; std::vector m_ShaderRepositories; }; class FixedNiftiImageIO : public itk::NiftiImageIO { public: /** Standard class typedefs. */ typedef FixedNiftiImageIO Self; typedef itk::NiftiImageIO Superclass; typedef itk::SmartPointer< Self > Pointer; /** Method for creation through the object factory. */ itkNewMacro(Self) /** Run-time type information (and related methods). */ itkTypeMacro(FixedNiftiImageIO, Superclass) virtual bool SupportsDimension(unsigned long dim) override { return dim > 1 && dim < 5; } }; void MitkCoreActivator::Load(us::ModuleContext* context) { // Handle messages from CppMicroServices us::installMsgHandler(HandleMicroServicesMessages); this->m_Context = context; // Add the current application directory to the auto-load paths. // This is useful for third-party executables. std::string programPath = mitk::IOUtil::GetProgramPath(); if (programPath.empty()) { MITK_WARN << "Could not get the program path."; } else { AddMitkAutoLoadPaths(programPath); } m_ShaderRepositoryTracker.reset(new ShaderRepositoryTracker); //m_RenderingManager = mitk::RenderingManager::New(); //context->RegisterService(renderingManager.GetPointer()); m_PlanePositionManager.reset(new mitk::PlanePositionManagerService); context->RegisterService(m_PlanePositionManager.get()); m_PropertyAliases.reset(new mitk::PropertyAliases); context->RegisterService(m_PropertyAliases.get()); m_PropertyDescriptions.reset(new mitk::PropertyDescriptions); context->RegisterService(m_PropertyDescriptions.get()); m_PropertyExtensions.reset(new mitk::PropertyExtensions); context->RegisterService(m_PropertyExtensions.get()); m_PropertyFilters.reset(new mitk::PropertyFilters); context->RegisterService(m_PropertyFilters.get()); + m_PropertyPersistence.reset(new mitk::PropertyPersistence); + context->RegisterService(m_PropertyPersistence.get()); + m_MimeTypeProvider.reset(new mitk::MimeTypeProvider); m_MimeTypeProvider->Start(); m_MimeTypeProviderReg = context->RegisterService(m_MimeTypeProvider.get()); this->RegisterDefaultMimeTypes(); this->RegisterItkReaderWriter(); this->RegisterVtkReaderWriter(); // Add custom Reader / Writer Services m_FileReaders.push_back(new mitk::PointSetReaderService()); m_FileWriters.push_back(new mitk::PointSetWriterService()); m_FileReaders.push_back(new mitk::DicomSeriesReaderService()); m_FileReaders.push_back(new mitk::RawImageFileReaderService()); m_ShaderRepositoryTracker->Open(); /* There IS an option to exchange ALL vtkTexture instances against vtkNeverTranslucentTextureFactory. This code is left here as a reminder, just in case we might need to do that some time. vtkNeverTranslucentTextureFactory* textureFactory = vtkNeverTranslucentTextureFactory::New(); vtkObjectFactory::RegisterFactory( textureFactory ); textureFactory->Delete(); */ this->RegisterLegacyWriter(); } void MitkCoreActivator::Unload(us::ModuleContext* ) { for(auto & elem : m_FileReaders) { delete elem; } for(auto & elem : m_FileWriters) { delete elem; } for(auto & elem : m_FileIOs) { delete elem; } for(auto & elem : m_LegacyWriters) { delete elem; } // The mitk::ModuleContext* argument of the Unload() method // will always be 0 for the Mitk library. It makes no sense // to use it at this stage anyway, since all libraries which // know about the module system have already been unloaded. // we need to close the internal service tracker of the // MimeTypeProvider class here. Otherwise it // would hold on to the ModuleContext longer than it is // actually valid. m_MimeTypeProviderReg.Unregister(); m_MimeTypeProvider->Stop(); for (std::vector::const_iterator mimeTypeIter = m_DefaultMimeTypes.begin(), iterEnd = m_DefaultMimeTypes.end(); mimeTypeIter != iterEnd; ++mimeTypeIter) { delete *mimeTypeIter; } m_ShaderRepositoryTracker->Close(); } void MitkCoreActivator::RegisterDefaultMimeTypes() { // Register some default mime-types std::vector mimeTypes = mitk::IOMimeTypes::Get(); for (std::vector::const_iterator mimeTypeIter = mimeTypes.begin(), iterEnd = mimeTypes.end(); mimeTypeIter != iterEnd; ++mimeTypeIter) { m_DefaultMimeTypes.push_back(*mimeTypeIter); m_Context->RegisterService(m_DefaultMimeTypes.back()); } } void MitkCoreActivator::RegisterItkReaderWriter() { std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("itkImageIOBase"); for (auto & allobject : allobjects) { itk::ImageIOBase* io = dynamic_cast(allobject.GetPointer()); // NiftiImageIO does not provide a correct "SupportsDimension()" methods // and the supported read/write extensions are not ordered correctly if (dynamic_cast(io)) continue; // Use a custom mime-type for GDCMImageIO below if (dynamic_cast(allobject.GetPointer())) { // MITK provides its own DICOM reader (which internally uses GDCMImageIO). continue; } if (io) { m_FileIOs.push_back(new mitk::ItkImageIO(io)); } else { MITK_WARN << "Error ImageIO factory did not return an ImageIOBase: " << ( allobject )->GetNameOfClass(); } } FixedNiftiImageIO::Pointer itkNiftiIO = FixedNiftiImageIO::New(); mitk::ItkImageIO* niftiIO = new mitk::ItkImageIO(mitk::IOMimeTypes::NIFTI_MIMETYPE(), itkNiftiIO.GetPointer(), 0); m_FileIOs.push_back(niftiIO); } void MitkCoreActivator::RegisterVtkReaderWriter() { m_FileIOs.push_back(new mitk::SurfaceVtkXmlIO()); m_FileIOs.push_back(new mitk::SurfaceStlIO()); m_FileIOs.push_back(new mitk::SurfaceVtkLegacyIO()); m_FileIOs.push_back(new mitk::ImageVtkXmlIO()); m_FileIOs.push_back(new mitk::ImageVtkLegacyIO()); } void MitkCoreActivator::RegisterLegacyWriter() { std::list allobjects = itk::ObjectFactoryBase::CreateAllInstance("IOWriter"); for( std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { mitk::FileWriter::Pointer io = dynamic_cast(i->GetPointer()); if(io) { std::string description = std::string("Legacy ") + io->GetNameOfClass() + " Writer"; mitk::IFileWriter* writer = new mitk::LegacyFileWriterService(io, description); m_LegacyWriters.push_back(writer); } else { MITK_ERROR << "Error IOWriter override is not of type mitk::FileWriter: " << (*i)->GetNameOfClass() << std::endl; } } } US_EXPORT_MODULE_ACTIVATOR(MitkCoreActivator) // Call CppMicroservices initialization code at the end of the file. // This especially ensures that VTK object factories have already // been registered (VTK initialization code is injected by implicitly // include VTK header files at the top of this file). US_INITIALIZE_MODULE diff --git a/Modules/Core/src/mitkCoreActivator.h b/Modules/Core/src/mitkCoreActivator.h index feafa21c7f..d092790b49 100644 --- a/Modules/Core/src/mitkCoreActivator.h +++ b/Modules/Core/src/mitkCoreActivator.h @@ -1,87 +1,89 @@ /*=================================================================== 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 MITKCOREACTIVATOR_H_ #define MITKCOREACTIVATOR_H_ // File IO #include #include #include #include #include #include #include #include #include +#include #include // Micro Services #include #include #include #include #include /* * This is the module activator for the "Mitk" module. It registers core services * like ... */ class MitkCoreActivator : public us::ModuleActivator { public: void Load(us::ModuleContext* context) override; void Unload(us::ModuleContext* ) override; private: void HandleModuleEvent(const us::ModuleEvent moduleEvent); void RegisterDefaultMimeTypes(); void RegisterItkReaderWriter(); void RegisterVtkReaderWriter(); void RegisterLegacyWriter(); std::auto_ptr > m_ShaderRepositoryTracker; //mitk::RenderingManager::Pointer m_RenderingManager; std::auto_ptr m_PlanePositionManager; std::auto_ptr m_PropertyAliases; std::auto_ptr m_PropertyDescriptions; std::auto_ptr m_PropertyExtensions; std::auto_ptr m_PropertyFilters; + std::auto_ptr m_PropertyPersistence; std::auto_ptr m_MimeTypeProvider; // File IO std::vector m_FileReaders; std::vector m_FileWriters; std::vector m_FileIOs; std::vector m_LegacyWriters; std::vector m_DefaultMimeTypes; us::ServiceRegistration m_MimeTypeProviderReg; us::ModuleContext* m_Context; }; #endif // MITKCOREACTIVATOR_H_ diff --git a/Modules/Core/src/mitkCoreServices.cpp b/Modules/Core/src/mitkCoreServices.cpp index 06c9d2c44c..44ee1d7bed 100644 --- a/Modules/Core/src/mitkCoreServices.cpp +++ b/Modules/Core/src/mitkCoreServices.cpp @@ -1,127 +1,133 @@ /*=================================================================== 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 "mitkCoreServices.h" #include #include #include #include #include +#include #include #include #include #include #include #include #include namespace mitk { itk::SimpleFastMutexLock& s_ContextToServicesMapMutex() { static itk::SimpleFastMutexLock mutex; return mutex; } std::map >& s_ContextToServicesMap() { static std::map > serviceMap; return serviceMap; } template static S* GetCoreService(us::ModuleContext* context) { if (context == NULL) context = us::GetModuleContext(); S* coreService = NULL; us::ServiceReference serviceRef = context->GetServiceReference(); if (serviceRef) { coreService = context->GetService(serviceRef); } assert(coreService && "Asserting non-NULL MITK core service"); { itk::MutexLockHolder l(s_ContextToServicesMapMutex()); s_ContextToServicesMap()[context].insert(std::make_pair(coreService,serviceRef)); } return coreService; } IShaderRepository* CoreServices::GetShaderRepository() { static us::ServiceTracker tracker(us::GetModuleContext()); tracker.Open(); return tracker.GetService(); } IPropertyAliases* CoreServices::GetPropertyAliases(us::ModuleContext* context) { return GetCoreService(context); } IPropertyDescriptions* CoreServices::GetPropertyDescriptions(us::ModuleContext* context) { return GetCoreService(context); } IPropertyExtensions* CoreServices::GetPropertyExtensions(us::ModuleContext* context) { return GetCoreService(context); } IPropertyFilters* CoreServices::GetPropertyFilters(us::ModuleContext* context) { return GetCoreService(context); } +IPropertyPersistence* CoreServices::GetPropertyPersistence(us::ModuleContext* context) +{ + return GetCoreService(context); +} + IMimeTypeProvider* CoreServices::GetMimeTypeProvider(us::ModuleContext* context) { return GetCoreService(context); } bool CoreServices::Unget(us::ModuleContext* context, const std::string& /*interfaceId*/, void* service) { bool success = false; itk::MutexLockHolder l(s_ContextToServicesMapMutex()); std::map >::iterator iter = s_ContextToServicesMap().find(context); if (iter != s_ContextToServicesMap().end()) { std::map::iterator iter2 = iter->second.find(service); if (iter2 != iter->second.end()) { us::ServiceReferenceU serviceRef = iter2->second; if (serviceRef) { success = context->UngetService(serviceRef); if (success) { iter->second.erase(iter2); } } } } return success; } }