diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index 5968a74287..1aa29e2075 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,326 +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/mitkCompositePixelValueToString.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkExtractSliceFilter2.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 Algorithms/mitkTemporalJoinImagesFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCrosshairManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSliceNavigationHelper.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkTimeNavigationController.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAnatomicalStructureColorPresets.cpp DataManagement/mitkArbitraryTimeGeometry.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/mitkCrosshairData.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkGenericIDRelationRule.cpp DataManagement/mitkIdentifiable.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/mitkIPropertyDeserialization.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp DataManagement/mitkIPropertyOwner.cpp DataManagement/mitkIPropertyPersistence.cpp DataManagement/mitkIPropertyProvider.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp - DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable + DataManagement/mitkLookupTables.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDataUID.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFunction.cpp DataManagement/mitkNodePredicateGeometry.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateDataProperty.cpp DataManagement/mitkNodePredicateSubGeometry.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/mitkPropertyDeserialization.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyKeyPath.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyNameHelper.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkPropertyPersistence.cpp DataManagement/mitkPropertyPersistenceInfo.cpp DataManagement/mitkPropertyRelationRuleBase.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkScaleOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkSourceImageRelationRule.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTemporoSpatialStringProperty.cpp DataManagement/mitkUIDManipulator.cpp DataManagement/mitkVectorProperty.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkIPropertyRelations.cpp DataManagement/mitkPropertyRelations.cpp Interactions/mitkAction.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayActionEventBroadcast.cpp Interactions/mitkDisplayActionEventFunctions.cpp Interactions/mitkDisplayActionEventHandler.cpp Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp Interactions/mitkDisplayActionEventHandlerStd.cpp Interactions/mitkDisplayActionEventHandlerSynchronized.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionSchemeSwitcher.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkGeometryDataReaderService.cpp IO/mitkGeometryDataWriterService.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/mitkLocaleSwitch.cpp IO/mitkLogBackend.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkProportionalTimeGeometryToXML.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkUtf8Util.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkPreferenceListReaderOptionsFunctor.cpp IO/mitkIOMetaInformationPropertyConstants.cpp IO/mitkIPreferences.cpp IO/mitkPreferences.cpp IO/mitkIPreferencesService.cpp IO/mitkPreferencesService.cpp IO/mitkIPreferencesStorage.cpp IO/mitkXMLPreferencesStorage.cpp Rendering/mitkAbstractAnnotationRenderer.cpp Rendering/mitkAnnotationUtils.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkBaseRendererHelper.cpp Rendering/mitkCrosshairVtkMapper2D.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkMapper.cpp Rendering/mitkAnnotation.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVideoRecorder.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.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/DisplayConfigMITKBase.xml Interactions/DisplayConfigPACSBase.xml Interactions/DisplayConfigCrosshair.xml Interactions/DisplayConfigRotation.xml Interactions/DisplayConfigActivateCoupling.xml Interactions/DisplayConfigSwivel.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigBlockLMB.xml Interactions/PointSet.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml mitkAnatomicalStructureColorPresets.xml ) diff --git a/Modules/Core/include/mitkCoreServices.h b/Modules/Core/include/mitkCoreServices.h index ce30201441..f02e895e09 100644 --- a/Modules/Core/include/mitkCoreServices.h +++ b/Modules/Core/include/mitkCoreServices.h @@ -1,187 +1,195 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCoreServices_h #define mitkCoreServices_h #include "MitkCoreExports.h" #include <mitkCommon.h> #include <mitkLog.h> #include <mitkServiceInterface.h> #include <usGetModuleContext.h> #include <usModuleContext.h> #include <usServiceReference.h> #include <cassert> namespace mitk { struct IMimeTypeProvider; class IPropertyAliases; class IPropertyDescriptions; + class IPropertyDeserialization; class IPropertyExtensions; class IPropertyFilters; class IPropertyPersistence; class IPropertyRelations; class IPreferencesService; /** * @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-nullptr 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<IShaderRepository> shaderRepo(CoreServices::GetShaderRepository()); * // Do something with shaderRepo * \endcode * * @see CoreServicePointer */ class MITKCORE_EXPORT CoreServices { public: /** * @brief Get an IPropertyAliases instance. * @param context The module context of the module getting the service. * @return A non-nullptr 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-nullptr IPropertyDescriptions instance. */ static IPropertyDescriptions *GetPropertyDescriptions(us::ModuleContext *context = us::GetModuleContext()); + /** + * @brief Get an IPropertyDeserialization instance. + * @param context The module context of the module getting the service. + * @return A non-nullptr IPropertyDeserialization instance. + */ + static IPropertyDeserialization* GetPropertyDeserialization(us::ModuleContext* context = us::GetModuleContext()); + /** * @brief Get an IPropertyExtensions instance. * @param context The module context of the module getting the service. * @return A non-nullptr 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-nullptr 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-nullptr IPropertyPersistence instance. */ static IPropertyPersistence *GetPropertyPersistence(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPropertyRelations instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPropertyRelations instance. */ static IPropertyRelations *GetPropertyRelations(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IMimeTypeProvider instance. * @param context The module context of the module getting the service. * @return A non-nullptr IMimeTypeProvider instance. */ static IMimeTypeProvider *GetMimeTypeProvider(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Get an IPreferencesService instance. * @param context The module context of the module getting the service. * @return A non-nullptr IPreferencesService instance. * @sa IPreferences */ static IPreferencesService *GetPreferencesService(us::ModuleContext *context = us::GetModuleContext()); /** * @brief Unget a previously acquired service instance. * @param service The service instance to be released. * @param context * @return \c true if ungetting the service was successful, \c false otherwise. */ template <class S> static bool Unget(S *service, us::ModuleContext *context = us::GetModuleContext()) { return Unget(context, us_service_interface_iid<S>(), 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 S> class MITK_LOCAL CoreServicePointer { public: explicit CoreServicePointer(S *service, us::ModuleContext* context = us::GetModuleContext()) : m_Service(service), m_Context(context) { assert(service); } ~CoreServicePointer() { try { CoreServices::Unget(m_Service, m_Context); } catch (const std::exception &e) { MITK_ERROR << e.what(); } catch (...) { MITK_ERROR << "Ungetting core service failed."; } } S *operator->() const { return m_Service; } private: S *const m_Service; us::ModuleContext* m_Context; }; } #endif diff --git a/Modules/Core/include/mitkIPropertyDeserialization.h b/Modules/Core/include/mitkIPropertyDeserialization.h new file mode 100644 index 0000000000..c700a5bfde --- /dev/null +++ b/Modules/Core/include/mitkIPropertyDeserialization.h @@ -0,0 +1,37 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkIPropertyDeserialization_h +#define mitkIPropertyDeserialization_h + +#include <MitkCoreExports.h> +#include <mitkServiceInterface.h> +#include <itkSmartPointer.h> +#include <string> + +namespace mitk +{ + class BaseProperty; + + class MITKCORE_EXPORT IPropertyDeserialization + { + public: + virtual ~IPropertyDeserialization(); + + virtual void RegisterProperty(const BaseProperty* property) = 0; + virtual itk::SmartPointer<BaseProperty> CreateInstance(const std::string& className) = 0; + }; +} + +MITK_DECLARE_SERVICE_INTERFACE(mitk::IPropertyDeserialization, "org.mitk.IPropertyDeserialization") + +#endif diff --git a/Modules/Core/include/mitkPropertyDeserialization.h b/Modules/Core/include/mitkPropertyDeserialization.h new file mode 100644 index 0000000000..c5e3f6860d --- /dev/null +++ b/Modules/Core/include/mitkPropertyDeserialization.h @@ -0,0 +1,39 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef mitkPropertyDeserialization_h +#define mitkPropertyDeserialization_h + +#include <mitkIPropertyDeserialization.h> +#include <map> + +namespace mitk +{ + class PropertyDeserialization : public IPropertyDeserialization + { + public: + PropertyDeserialization(); + virtual ~PropertyDeserialization(); + + PropertyDeserialization(const PropertyDeserialization&) = delete; + PropertyDeserialization& operator=(const PropertyDeserialization&) = delete; + + void RegisterProperty(const BaseProperty* property) override; + itk::SmartPointer<BaseProperty> CreateInstance(const std::string& className) override; + + private: + using MapType = std::map<std::string, itk::SmartPointer<BaseProperty>>; + MapType m_Map; + }; +} + +#endif diff --git a/Modules/Core/include/mitkPropertyList.h b/Modules/Core/include/mitkPropertyList.h index 40f05857cf..996e7c10ba 100644 --- a/Modules/Core/include/mitkPropertyList.h +++ b/Modules/Core/include/mitkPropertyList.h @@ -1,254 +1,247 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkPropertyList_h #define mitkPropertyList_h -#include "mitkBaseProperty.h" -#include "mitkGenericProperty.h" -#include "mitkUIDGenerator.h" -#include "mitkIPropertyOwner.h" -#include <MitkCoreExports.h> - -#include <itkObjectFactory.h> - -#include <map> -#include <string> +#include <mitkIPropertyOwner.h> +#include <nlohmann/json_fwd.hpp> namespace mitk { - class XMLWriter; - /** * @brief Key-value list holding instances of BaseProperty * * This list is meant to hold an arbitrary list of "properties", * which should describe the object associated with this list. * * Usually you will use PropertyList as part of a DataNode * object - in this context the properties describe the data object * held by the DataNode (e.g. whether the object is rendered at * all, which color is used for rendering, what name should be * displayed for the object, etc.) * * The values in the list are not fixed, you may introduce any kind * of property that seems useful - all you have to do is inherit * from BaseProperty. * * The list is organized as a key-value pairs, i.e. * * \li "name" : pointer to a StringProperty * \li "visible" : pointer to a BoolProperty * \li "color" : pointer to a ColorProperty * \li "volume" : pointer to a FloatProperty * * Please see the documentation of SetProperty and ReplaceProperty for two * quite different semantics. Normally SetProperty is what you want - this * method will try to change the value of an existing property and will * not allow you to replace e.g. a ColorProperty with an IntProperty. * * Please also regard, that the key of a property must be a none empty string. * This is a precondition. Setting properties with empty keys will raise an exception. * * @ingroup DataManagement */ class MITKCORE_EXPORT PropertyList : public itk::Object, public IPropertyOwner { public: mitkClassMacroItkParent(PropertyList, itk::Object); /** * Method for creation through the object factory. */ itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** * Map structure to hold the properties: the map key is a string, * the value consists of the actual property object (BaseProperty). */ typedef std::map<std::string, BaseProperty::Pointer> PropertyMap; typedef std::pair<std::string, BaseProperty::Pointer> PropertyMapElementType; // IPropertyProvider BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) const override; std::vector<std::string> GetPropertyKeys(const std::string &contextName = "", bool includeDefaultContext = false) const override; std::vector<std::string> GetPropertyContextNames() const override; // IPropertyOwner BaseProperty * GetNonConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) override; void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; void RemoveProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; /** * @brief Get a property by its name. */ mitk::BaseProperty *GetProperty(const std::string &propertyKey) const; /** * @brief Set a property object in the list/map by reference. * * The actual OBJECT holding the value of the property is replaced by this function. * This is useful if you want to change the type of the property, like from BoolProperty to StringProperty. * Another use is to share one and the same property object among several PropertyList/DataNode objects, which * makes them appear synchronized. */ void ReplaceProperty(const std::string &propertyKey, BaseProperty *property); /** * @brief Set a property object in the list/map by reference. */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); //##Documentation //## @brief Convenience access method for GenericProperty<T> properties //## (T being the type of the second parameter) //## @return @a true property was found template <typename T> bool GetPropertyValue(const char *propertyKey, T &value) const { GenericProperty<T> *gp = dynamic_cast<GenericProperty<T> *>(GetProperty(propertyKey)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience method to access the value of a BoolProperty */ bool GetBoolProperty(const char *propertyKey, bool &boolValue) const; /** * @brief ShortCut for the above method */ bool Get(const char *propertyKey, bool &boolValue) const; /** * @brief Convenience method to set the value of a BoolProperty */ void SetBoolProperty(const char *propertyKey, bool boolValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, bool boolValue); /** * @brief Convenience method to access the value of an IntProperty */ bool GetIntProperty(const char *propertyKey, int &intValue) const; /** * @brief ShortCut for the above method */ bool Get(const char *propertyKey, int &intValue) const; /** * @brief Convenience method to set the value of an IntProperty */ void SetIntProperty(const char *propertyKey, int intValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, int intValue); /** * @brief Convenience method to access the value of a FloatProperty */ bool GetFloatProperty(const char *propertyKey, float &floatValue) const; /** * @brief ShortCut for the above method */ bool Get(const char *propertyKey, float &floatValue) const; /** * @brief Convenience method to set the value of a FloatProperty */ void SetFloatProperty(const char *propertyKey, float floatValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, float floatValue); /** * @brief Convenience method to access the value of a DoubleProperty */ bool GetDoubleProperty(const char *propertyKey, double &doubleValue) const; /** * @brief ShortCut for the above method */ bool Get(const char *propertyKey, double &doubleValue) const; /** * @brief Convenience method to set the value of a DoubleProperty */ void SetDoubleProperty(const char *propertyKey, double doubleValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, double doubleValue); /** * @brief Convenience method to access the value of a StringProperty */ bool GetStringProperty(const char *propertyKey, std::string &stringValue) const; /** * @brief ShortCut for the above method */ bool Get(const char *propertyKey, std::string &stringValue) const; /** * @brief Convenience method to set the value of a StringProperty */ void SetStringProperty(const char *propertyKey, const char *stringValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, const char *stringValue); /** * @brief ShortCut for the above method */ void Set(const char *propertyKey, const std::string &stringValue); /** * @brief Get the timestamp of the last change of the map or the last change of one of * the properties store in the list (whichever is later). */ itk::ModifiedTimeType GetMTime() const override; /** * @brief Remove a property from the list/map. */ bool DeleteProperty(const std::string &propertyKey); const PropertyMap *GetMap() const { return &m_Properties; } bool IsEmpty() const { return m_Properties.empty(); } virtual void Clear(); + void ToJSON(nlohmann::json& j) const; + void FromJSON(const nlohmann::json& j); + protected: PropertyList(); PropertyList(const PropertyList &other); ~PropertyList() override; /** * @brief Map of properties. */ PropertyMap m_Properties; private: itk::LightObject::Pointer InternalClone() const override; }; } // namespace mitk #endif diff --git a/Modules/Core/src/DataManagement/mitkIPropertyDeserialization.cpp b/Modules/Core/src/DataManagement/mitkIPropertyDeserialization.cpp new file mode 100644 index 0000000000..bb3e4b2c12 --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkIPropertyDeserialization.cpp @@ -0,0 +1,17 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkIPropertyDeserialization.h" + +mitk::IPropertyDeserialization::~IPropertyDeserialization() +{ +} diff --git a/Modules/Core/src/DataManagement/mitkPropertyDeserialization.cpp b/Modules/Core/src/DataManagement/mitkPropertyDeserialization.cpp new file mode 100644 index 0000000000..b95de60e5e --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkPropertyDeserialization.cpp @@ -0,0 +1,38 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include <mitkPropertyDeserialization.h> +#include <mitkBaseProperty.h> + +mitk::PropertyDeserialization::PropertyDeserialization() +{ +} + +mitk::PropertyDeserialization::~PropertyDeserialization() +{ +} + +void mitk::PropertyDeserialization::RegisterProperty(const BaseProperty* property) +{ + if (property != nullptr) + m_Map[property->GetNameOfClass()] = static_cast<BaseProperty*>(property->CreateAnother().GetPointer()); +} + +mitk::BaseProperty::Pointer mitk::PropertyDeserialization::CreateInstance(const std::string& className) +{ + auto it = m_Map.find(className); + + if (it != m_Map.end()) + return static_cast<BaseProperty*>(it->second->CreateAnother().GetPointer()); + + return nullptr; +} diff --git a/Modules/Core/src/DataManagement/mitkPropertyList.cpp b/Modules/Core/src/DataManagement/mitkPropertyList.cpp index d15eac3f6e..88d5d7e34c 100644 --- a/Modules/Core/src/DataManagement/mitkPropertyList.cpp +++ b/Modules/Core/src/DataManagement/mitkPropertyList.cpp @@ -1,376 +1,422 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "mitkPropertyList.h" - -#include "mitkNumericTypes.h" -#include "mitkProperties.h" -#include "mitkStringProperty.h" +#include <mitkPropertyList.h> +#include <mitkCoreServices.h> +#include <mitkIPropertyDeserialization.h> +#include <mitkProperties.h> +#include <mitkStringProperty.h> mitk::BaseProperty::ConstPointer mitk::PropertyList::GetConstProperty(const std::string &propertyKey, const std::string &/*contextName*/, bool /*fallBackOnDefaultContext*/) const { PropertyMap::const_iterator it; it = m_Properties.find(propertyKey); if (it != m_Properties.cend()) return it->second.GetPointer(); else return nullptr; }; std::vector<std::string> mitk::PropertyList::GetPropertyKeys(const std::string &contextName, bool includeDefaultContext) const { std::vector<std::string> propertyKeys; if (contextName.empty() || includeDefaultContext) { for (const auto &property : this->m_Properties) propertyKeys.push_back(property.first); } return propertyKeys; }; std::vector<std::string> mitk::PropertyList::GetPropertyContextNames() const { return std::vector<std::string>(); }; mitk::BaseProperty *mitk::PropertyList::GetProperty(const std::string &propertyKey) const { PropertyMap::const_iterator it; it = m_Properties.find(propertyKey); if (it != m_Properties.cend()) return it->second; else return nullptr; } mitk::BaseProperty * mitk::PropertyList::GetNonConstProperty(const std::string &propertyKey, const std::string &/*contextName*/, bool /*fallBackOnDefaultContext*/) { return this->GetProperty(propertyKey); } void mitk::PropertyList::SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &/*contextName*/, bool /*fallBackOnDefaultContext*/) { if (propertyKey.empty()) mitkThrow() << "Property key is empty."; if (!property) return; // make sure that BaseProperty*, which may have just been created and never been // assigned to a SmartPointer, is registered/unregistered properly. If we do not // do that, it will a) not deleted in case it is identical to the old one or // b) possibly deleted when temporarily added to a smartpointer somewhere below. BaseProperty::Pointer tmpSmartPointerToProperty = property; auto it(m_Properties.find(propertyKey)); // Is a property with key @a propertyKey contained in the list? if (it != m_Properties.cend()) { // yes // is the property contained in the list identical to the new one? if (it->second->operator==(*property)) { // yes? do nothing and return. return; } if (it->second->AssignProperty(*property)) { // The assignment was successful this->Modified(); } else { MITK_ERROR << "In " __FILE__ ", l." << __LINE__ << ": Trying to set existing property " << it->first << " of type " << it->second->GetNameOfClass() << " to a property with different type " << property->GetNameOfClass() << "." << " Use ReplaceProperty() instead." << std::endl; } return; } // no? add it. m_Properties.insert(PropertyMap::value_type(propertyKey, property)); this->Modified(); } void mitk::PropertyList::ReplaceProperty(const std::string &propertyKey, BaseProperty *property) { if (!property) return; auto it(m_Properties.find(propertyKey)); // Is a property with key @a propertyKey contained in the list? if (it != m_Properties.cend()) { it->second = nullptr; m_Properties.erase(it); } // no? add/replace it. m_Properties.insert(PropertyMap::value_type(propertyKey, property)); Modified(); } void mitk::PropertyList::RemoveProperty(const std::string &propertyKey, const std::string &/*contextName*/, bool /*fallBackOnDefaultContext*/) { auto it(m_Properties.find(propertyKey)); // Is a property with key @a propertyKey contained in the list? if (it != m_Properties.cend()) { it->second = nullptr; m_Properties.erase(it); Modified(); } } mitk::PropertyList::PropertyList() { } mitk::PropertyList::PropertyList(const mitk::PropertyList &other) : itk::Object() { for (auto i = other.m_Properties.cbegin(); i != other.m_Properties.cend(); ++i) { m_Properties.insert(std::make_pair(i->first, i->second->Clone())); } } mitk::PropertyList::~PropertyList() { Clear(); } /** * Consider the list as changed when any of the properties has changed recently. */ itk::ModifiedTimeType mitk::PropertyList::GetMTime() const { for (auto it = m_Properties.cbegin(); it != m_Properties.cend(); ++it) { if (it->second.IsNull()) { itkWarningMacro(<< "Property '" << it->first << "' contains nothing (nullptr)."); continue; } if (Superclass::GetMTime() < it->second->GetMTime()) { Modified(); break; } } return Superclass::GetMTime(); } bool mitk::PropertyList::DeleteProperty(const std::string &propertyKey) { auto it = m_Properties.find(propertyKey); if (it != m_Properties.end()) { it->second = nullptr; m_Properties.erase(it); Modified(); return true; } return false; } void mitk::PropertyList::Clear() { auto it = m_Properties.begin(), end = m_Properties.end(); while (it != end) { it->second = nullptr; ++it; } m_Properties.clear(); } itk::LightObject::Pointer mitk::PropertyList::InternalClone() const { itk::LightObject::Pointer result(new Self(*this)); result->UnRegister(); return result; } void mitk::PropertyList::ConcatenatePropertyList(PropertyList *pList, bool replace) { if (pList) { const PropertyMap *propertyMap = pList->GetMap(); for (auto iter = propertyMap->cbegin(); // m_PropertyList is created in the constructor, so we don't check it here iter != propertyMap->cend(); ++iter) { const std::string key = iter->first; BaseProperty *value = iter->second; if (replace) { ReplaceProperty(key.c_str(), value); } else { SetProperty(key.c_str(), value); } } } } bool mitk::PropertyList::GetBoolProperty(const char *propertyKey, bool &boolValue) const { BoolProperty *gp = dynamic_cast<BoolProperty *>(GetProperty(propertyKey)); if (gp != nullptr) { boolValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs // return GetPropertyValue<bool>(propertyKey, boolValue); } bool mitk::PropertyList::GetIntProperty(const char *propertyKey, int &intValue) const { IntProperty *gp = dynamic_cast<IntProperty *>(GetProperty(propertyKey)); if (gp != nullptr) { intValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs // return GetPropertyValue<int>(propertyKey, intValue); } bool mitk::PropertyList::GetFloatProperty(const char *propertyKey, float &floatValue) const { FloatProperty *gp = dynamic_cast<FloatProperty *>(GetProperty(propertyKey)); if (gp != nullptr) { floatValue = gp->GetValue(); return true; } return false; // Templated Method does not work on Macs // return GetPropertyValue<float>(propertyKey, floatValue); } bool mitk::PropertyList::GetStringProperty(const char *propertyKey, std::string &stringValue) const { StringProperty *sp = dynamic_cast<StringProperty *>(GetProperty(propertyKey)); if (sp != nullptr) { stringValue = sp->GetValue(); return true; } return false; } void mitk::PropertyList::SetIntProperty(const char *propertyKey, int intValue) { SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::PropertyList::SetBoolProperty(const char *propertyKey, bool boolValue) { SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::PropertyList::SetFloatProperty(const char *propertyKey, float floatValue) { SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::PropertyList::SetStringProperty(const char *propertyKey, const char *stringValue) { SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void mitk::PropertyList::Set(const char *propertyKey, bool boolValue) { this->SetBoolProperty(propertyKey, boolValue); } void mitk::PropertyList::Set(const char *propertyKey, int intValue) { this->SetIntProperty(propertyKey, intValue); } void mitk::PropertyList::Set(const char *propertyKey, float floatValue) { this->SetFloatProperty(propertyKey, floatValue); } void mitk::PropertyList::Set(const char *propertyKey, double doubleValue) { this->SetDoubleProperty(propertyKey, doubleValue); } void mitk::PropertyList::Set(const char *propertyKey, const char *stringValue) { this->SetStringProperty(propertyKey, stringValue); } void mitk::PropertyList::Set(const char *propertyKey, const std::string &stringValue) { this->SetStringProperty(propertyKey, stringValue.c_str()); } bool mitk::PropertyList::Get(const char *propertyKey, bool &boolValue) const { return this->GetBoolProperty(propertyKey, boolValue); } bool mitk::PropertyList::Get(const char *propertyKey, int &intValue) const { return this->GetIntProperty(propertyKey, intValue); } bool mitk::PropertyList::Get(const char *propertyKey, float &floatValue) const { return this->GetFloatProperty(propertyKey, floatValue); } bool mitk::PropertyList::Get(const char *propertyKey, double &doubleValue) const { return this->GetDoubleProperty(propertyKey, doubleValue); } bool mitk::PropertyList::Get(const char *propertyKey, std::string &stringValue) const { return this->GetStringProperty(propertyKey, stringValue); } bool mitk::PropertyList::GetDoubleProperty(const char *propertyKey, double &doubleValue) const { DoubleProperty *gp = dynamic_cast<DoubleProperty *>(GetProperty(propertyKey)); if (gp != nullptr) { doubleValue = gp->GetValue(); return true; } return false; } void mitk::PropertyList::SetDoubleProperty(const char *propertyKey, double doubleValue) { SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue)); } + +void mitk::PropertyList::ToJSON(nlohmann::json& j) const +{ + j = nlohmann::json::object(); + + for (const auto& [name, property] : m_Properties) + { + nlohmann::json serializedProperty; + + if (property->ToJSON(serializedProperty)) + j[property->GetNameOfClass()][name] = serializedProperty; + } + + auto test = PropertyList::New(); + test->FromJSON(j); +} + +void mitk::PropertyList::FromJSON(const nlohmann::json& j) +{ + mitk::CoreServicePointer<mitk::IPropertyDeserialization> service(mitk::CoreServices::GetPropertyDeserialization()); + PropertyMap properties; + + auto jObject = j.get<nlohmann::json::object_t>(); + + for (const auto& [type, serializedProperties] : jObject) + { + auto prototype = service->CreateInstance(type); + + if (prototype.IsNull()) + { + MITK_ERROR << "Cannot create instance(s) of class \"" << type << "\"!"; + continue; + } + + auto serializedPropertiesObject = serializedProperties.get<nlohmann::json::object_t>(); + + for (const auto& [name, serializedProperty] : serializedPropertiesObject) + { + BaseProperty::Pointer property = static_cast<BaseProperty*>(prototype->CreateAnother().GetPointer()); + property->FromJSON(serializedProperty); + properties[name] = property; + } + } + + m_Properties = properties; +} diff --git a/Modules/Core/src/mitkCoreActivator.cpp b/Modules/Core/src/mitkCoreActivator.cpp index 594cdf5490..0fc801eec6 100644 --- a/Modules/Core/src/mitkCoreActivator.cpp +++ b/Modules/Core/src/mitkCoreActivator.cpp @@ -1,368 +1,437 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkCoreActivator.h" #include <mitkCoreServices.h> #include <mitkPropertyPersistenceInfo.h> // File IO #include <mitkIOMetaInformationPropertyConstants.h> #include <mitkGeometryDataReaderService.h> #include <mitkGeometryDataWriterService.h> #include <mitkIOMimeTypes.h> #include <mitkIOUtil.h> #include <mitkImageVtkLegacyIO.h> #include <mitkImageVtkXmlIO.h> #include <mitkItkImageIO.h> #include <mitkMimeTypeProvider.h> #include <mitkPointSetReaderService.h> #include <mitkPointSetWriterService.h> #include <mitkRawImageFileReader.h> #include <mitkSurfaceStlIO.h> #include <mitkSurfaceVtkLegacyIO.h> #include <mitkSurfaceVtkXmlIO.h> #include "mitkLegacyFileWriterService.h" #include <mitkFileWriter.h> #include <itkGDCMImageIO.h> #include <itkNiftiImageIO.h> // PropertyRelationRules #include <mitkPropertyRelationRuleBase.h> // Micro Services #include <usGetModuleContext.h> #include <usModule.h> #include <usModuleActivator.h> #include <usModuleContext.h> #include <usModuleEvent.h> #include <usModuleInitialization.h> #include <usModuleResource.h> #include <usModuleResourceStream.h> #include <usModuleSettings.h> #include <usServiceTracker.h> +// Properties +#include <mitkAnnotationProperty.h> +#include <mitkClippingProperty.h> +#include <mitkColorProperty.h> +#include <mitkGroupTagProperty.h> +#include <mitkLevelWindowProperty.h> +#include <mitkLookupTableProperty.h> +#include <mitkModalityProperty.h> +#include <mitkPlaneOrientationProperty.h> +#include <mitkPointSetShapeProperty.h> +#include <mitkProperties.h> +#include <mitkRenderingModeProperty.h> +#include <mitkStringProperty.h> +#include <mitkTemporoSpatialStringProperty.h> +#include <mitkTransferFunctionProperty.h> +#include <mitkVectorProperty.h> +#include <mitkVtkInterpolationProperty.h> +#include <mitkVtkRepresentationProperty.h> +#include <mitkVtkResliceInterpolationProperty.h> +#include <mitkVtkScalarModeProperty.h> + // 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 <itkImageIOFactoryRegisterManager.h> -void HandleMicroServicesMessages(us::MsgType type, const char *msg) +namespace { - switch (type) + 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) + void AddMitkAutoLoadPaths(const std::string& programPath) { - std::size_t index = additionalPath.find_last_of('/'); - if (index != std::string::npos) + 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) { - additionalPath = additionalPath.substr(0, index); + std::size_t index = additionalPath.find_last_of('/'); + if (index != std::string::npos) + { + additionalPath = additionalPath.substr(0, index); + } + else + { + addPath = false; + break; + } } - else + if (addPath) { - addPath = false; - break; + us::ModuleSettings::AddAutoLoadPath(additionalPath); } +#endif } - if (addPath) + + void AddPropertyPersistence(const mitk::PropertyKeyPath& propPath) { - us::ModuleSettings::AddAutoLoadPath(additionalPath); - } -#endif -} + mitk::CoreServicePointer<mitk::IPropertyPersistence> persistenceService(mitk::CoreServices::GetPropertyPersistence()); -void AddPropertyPersistence(const mitk::PropertyKeyPath& propPath) -{ - mitk::CoreServicePointer<mitk::IPropertyPersistence> persistenceService(mitk::CoreServices::GetPropertyPersistence()); + auto info = mitk::PropertyPersistenceInfo::New(); + if (propPath.IsExplicit()) + { + std::string name = mitk::PropertyKeyPathToPropertyName(propPath); + std::string key = name; + std::replace(key.begin(), key.end(), '.', '_'); + info->SetNameAndKey(name, key); + } + else + { + std::string key = mitk::PropertyKeyPathToPersistenceKeyRegEx(propPath); + std::string keyTemplate = mitk::PropertyKeyPathToPersistenceKeyTemplate(propPath); + std::string propRegEx = mitk::PropertyKeyPathToPropertyRegEx(propPath); + std::string propTemplate = mitk::PropertyKeyPathToPersistenceNameTemplate(propPath); + info->UseRegEx(propRegEx, propTemplate, key, keyTemplate); + } - auto info = mitk::PropertyPersistenceInfo::New(); - if (propPath.IsExplicit()) - { - std::string name = mitk::PropertyKeyPathToPropertyName(propPath); - std::string key = name; - std::replace(key.begin(), key.end(), '.', '_'); - info->SetNameAndKey(name, key); + persistenceService->AddInfo(info); } - else + + void RegisterProperties() { - std::string key = mitk::PropertyKeyPathToPersistenceKeyRegEx(propPath); - std::string keyTemplate = mitk::PropertyKeyPathToPersistenceKeyTemplate(propPath); - std::string propRegEx = mitk::PropertyKeyPathToPropertyRegEx(propPath); - std::string propTemplate = mitk::PropertyKeyPathToPersistenceNameTemplate(propPath); - info->UseRegEx(propRegEx, propTemplate, key, keyTemplate); + mitk::CoreServicePointer<mitk::IPropertyDeserialization> service(mitk::CoreServices::GetPropertyDeserialization()); + + service->RegisterProperty(mitk::AnnotationProperty::New()); + service->RegisterProperty(mitk::ClippingProperty::New()); + service->RegisterProperty(mitk::ColorProperty::New()); + service->RegisterProperty(mitk::BoolProperty::New()); + service->RegisterProperty(mitk::BoolLookupTableProperty::New()); + service->RegisterProperty(mitk::DoubleProperty::New()); + service->RegisterProperty(mitk::DoubleVectorProperty::New()); + service->RegisterProperty(mitk::FloatProperty::New()); + service->RegisterProperty(mitk::FloatLookupTableProperty::New()); + service->RegisterProperty(mitk::GroupTagProperty::New()); + service->RegisterProperty(mitk::IntProperty::New()); + service->RegisterProperty(mitk::IntLookupTableProperty::New()); + service->RegisterProperty(mitk::IntVectorProperty::New()); + service->RegisterProperty(mitk::LevelWindowProperty::New()); + service->RegisterProperty(mitk::LookupTableProperty::New()); + service->RegisterProperty(mitk::PlaneOrientationProperty::New()); + service->RegisterProperty(mitk::Point2dProperty::New()); + service->RegisterProperty(mitk::Point3dProperty::New()); + service->RegisterProperty(mitk::Point3iProperty::New()); + service->RegisterProperty(mitk::Point4dProperty::New()); + service->RegisterProperty(mitk::PointSetShapeProperty::New()); + service->RegisterProperty(mitk::ModalityProperty::New()); + service->RegisterProperty(mitk::RenderingModeProperty::New()); + service->RegisterProperty(mitk::StringProperty::New()); + service->RegisterProperty(mitk::StringLookupTableProperty::New()); + service->RegisterProperty(mitk::TemporoSpatialStringProperty::New()); + service->RegisterProperty(mitk::TransferFunctionProperty::New()); + service->RegisterProperty(mitk::UIntProperty::New()); + service->RegisterProperty(mitk::UShortProperty::New()); + service->RegisterProperty(mitk::Vector3DProperty::New()); + service->RegisterProperty(mitk::VtkInterpolationProperty::New()); + service->RegisterProperty(mitk::VtkRepresentationProperty::New()); + service->RegisterProperty(mitk::VtkResliceInterpolationProperty::New()); + service->RegisterProperty(mitk::VtkScalarModeProperty::New()); } - - persistenceService->AddInfo(info); } 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) 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_RenderingManager = mitk::RenderingManager::New(); // context->RegisterService<mitk::RenderingManager>(renderingManager.GetPointer()); m_PlanePositionManager.reset(new mitk::PlanePositionManagerService); context->RegisterService<mitk::PlanePositionManagerService>(m_PlanePositionManager.get()); m_PropertyAliases.reset(new mitk::PropertyAliases); context->RegisterService<mitk::IPropertyAliases>(m_PropertyAliases.get()); m_PropertyDescriptions.reset(new mitk::PropertyDescriptions); context->RegisterService<mitk::IPropertyDescriptions>(m_PropertyDescriptions.get()); + m_PropertyDeserialization.reset(new mitk::PropertyDeserialization); + context->RegisterService<mitk::IPropertyDeserialization>(m_PropertyDeserialization.get()); + m_PropertyExtensions.reset(new mitk::PropertyExtensions); context->RegisterService<mitk::IPropertyExtensions>(m_PropertyExtensions.get()); m_PropertyFilters.reset(new mitk::PropertyFilters); context->RegisterService<mitk::IPropertyFilters>(m_PropertyFilters.get()); m_PropertyPersistence.reset(new mitk::PropertyPersistence); context->RegisterService<mitk::IPropertyPersistence>(m_PropertyPersistence.get()); m_PropertyRelations.reset(new mitk::PropertyRelations); context->RegisterService<mitk::IPropertyRelations>(m_PropertyRelations.get()); m_PreferencesService.reset(new mitk::PreferencesService); context->RegisterService<mitk::IPreferencesService>(m_PreferencesService.get()); m_MimeTypeProvider.reset(new mitk::MimeTypeProvider); m_MimeTypeProvider->Start(); m_MimeTypeProviderReg = context->RegisterService<mitk::IMimeTypeProvider>(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::GeometryDataReaderService()); m_FileWriters.push_back(new mitk::GeometryDataWriterService()); m_FileReaders.push_back(new mitk::RawImageFileReaderService()); //add properties that should be persistent (if possible/supported by the writer) AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_DESCRIPTION()); AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_INPUTLOCATION()); AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_MIME_CATEGORY()); AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_MIME_NAME()); AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_VERSION()); AddPropertyPersistence(mitk::IOMetaInformationPropertyConstants::READER_OPTIONS_ANY()); AddPropertyPersistence(mitk::PropertyRelationRuleBase::GetRIIDestinationUIDPropertyKeyPath()); AddPropertyPersistence(mitk::PropertyRelationRuleBase::GetRIIRelationUIDPropertyKeyPath()); AddPropertyPersistence(mitk::PropertyRelationRuleBase::GetRIIRuleIDPropertyKeyPath()); AddPropertyPersistence(mitk::PropertyRelationRuleBase::GetRIIPropertyKeyPath("","").AddAnyElement()); + RegisterProperties(); + /* 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<mitk::CustomMimeType *>::const_iterator mimeTypeIter = m_DefaultMimeTypes.begin(), iterEnd = m_DefaultMimeTypes.end(); mimeTypeIter != iterEnd; ++mimeTypeIter) { delete *mimeTypeIter; } } void MitkCoreActivator::RegisterDefaultMimeTypes() { // Register some default mime-types std::vector<mitk::CustomMimeType *> mimeTypes = mitk::IOMimeTypes::Get(); for (std::vector<mitk::CustomMimeType *>::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<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("itkImageIOBase"); for (auto &allobject : allobjects) { auto *io = dynamic_cast<itk::ImageIOBase *>(allobject.GetPointer()); // NiftiImageIO does not provide a correct "SupportsDimension()" methods // and the supported read/write extensions are not ordered correctly if (dynamic_cast<itk::NiftiImageIO *>(io)) continue; // Use a custom mime-type for GDCMImageIO below if (dynamic_cast<itk::GDCMImageIO *>(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<itk::LightObject::Pointer> allobjects = itk::ObjectFactoryBase::CreateAllInstance("IOWriter"); for (auto i = allobjects.begin(); i != allobjects.end(); ++i) { mitk::FileWriter::Pointer io = dynamic_cast<mitk::FileWriter *>(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 19c513bba7..d28f97a70a 100644 --- a/Modules/Core/src/mitkCoreActivator.h +++ b/Modules/Core/src/mitkCoreActivator.h @@ -1,82 +1,84 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkCoreActivator_h #define mitkCoreActivator_h // File IO #include <mitkAbstractFileIO.h> #include <mitkIFileReader.h> #include <mitkIFileWriter.h> #include <mitkMimeTypeProvider.h> #include <mitkPlanePositionManager.h> #include <mitkPropertyAliases.h> #include <mitkPropertyDescriptions.h> +#include <mitkPropertyDeserialization.h> #include <mitkPropertyExtensions.h> #include <mitkPropertyFilters.h> #include <mitkPropertyPersistence.h> #include <mitkPropertyRelations.h> #include <mitkPreferencesService.h> // Micro Services #include <usModuleActivator.h> #include <usModuleEvent.h> #include <usServiceRegistration.h> #include <usServiceTracker.h> #include <memory> /* * 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(); // mitk::RenderingManager::Pointer m_RenderingManager; std::unique_ptr<mitk::PlanePositionManagerService> m_PlanePositionManager; std::unique_ptr<mitk::PropertyAliases> m_PropertyAliases; std::unique_ptr<mitk::PropertyDescriptions> m_PropertyDescriptions; + std::unique_ptr<mitk::PropertyDeserialization> m_PropertyDeserialization; std::unique_ptr<mitk::PropertyExtensions> m_PropertyExtensions; std::unique_ptr<mitk::PropertyFilters> m_PropertyFilters; std::unique_ptr<mitk::PropertyPersistence> m_PropertyPersistence; std::unique_ptr<mitk::PropertyRelations> m_PropertyRelations; std::unique_ptr<mitk::MimeTypeProvider> m_MimeTypeProvider; std::unique_ptr<mitk::PreferencesService> m_PreferencesService; // File IO std::vector<mitk::IFileReader *> m_FileReaders; std::vector<mitk::IFileWriter *> m_FileWriters; std::vector<mitk::AbstractFileIO *> m_FileIOs; std::vector<mitk::IFileWriter *> m_LegacyWriters; std::vector<mitk::CustomMimeType *> m_DefaultMimeTypes; us::ServiceRegistration<mitk::IMimeTypeProvider> m_MimeTypeProviderReg; us::ModuleContext *m_Context; }; #endif diff --git a/Modules/Core/src/mitkCoreServices.cpp b/Modules/Core/src/mitkCoreServices.cpp index 720730347f..96dce2bcde 100644 --- a/Modules/Core/src/mitkCoreServices.cpp +++ b/Modules/Core/src/mitkCoreServices.cpp @@ -1,133 +1,139 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkCoreServices.h" #include <mitkIMimeTypeProvider.h> #include <mitkIPropertyAliases.h> #include <mitkIPropertyDescriptions.h> +#include <mitkIPropertyDeserialization.h> #include <mitkIPropertyExtensions.h> #include <mitkIPropertyFilters.h> #include <mitkIPropertyPersistence.h> #include <mitkIPropertyRelations.h> #include <mitkIPreferencesService.h> #include <usGetModuleContext.h> #include <usModuleContext.h> #include <usServiceReference.h> #include <usServiceTracker.h> #include <mutex> namespace mitk { std::mutex &s_ContextToServicesMapMutex() { static std::mutex mutex; return mutex; } std::map<us::ModuleContext *, std::map<void *, us::ServiceReferenceU>> &s_ContextToServicesMap() { static std::map<us::ModuleContext *, std::map<void *, us::ServiceReferenceU>> serviceMap; return serviceMap; } template <class S> static S *GetCoreService(us::ModuleContext *context) { if (context == nullptr) context = us::GetModuleContext(); S *coreService = nullptr; us::ServiceReference<S> serviceRef = context->GetServiceReference<S>(); if (serviceRef) { coreService = context->GetService(serviceRef); } assert(coreService && "Asserting non-nullptr MITK core service"); { std::lock_guard<std::mutex> l(s_ContextToServicesMapMutex()); s_ContextToServicesMap()[context].insert(std::make_pair(coreService, serviceRef)); } return coreService; } IPropertyAliases *CoreServices::GetPropertyAliases(us::ModuleContext *context) { return GetCoreService<IPropertyAliases>(context); } IPropertyDescriptions *CoreServices::GetPropertyDescriptions(us::ModuleContext *context) { return GetCoreService<IPropertyDescriptions>(context); } + IPropertyDeserialization* CoreServices::GetPropertyDeserialization(us::ModuleContext* context) + { + return GetCoreService<IPropertyDeserialization>(context); + } + IPropertyExtensions *CoreServices::GetPropertyExtensions(us::ModuleContext *context) { return GetCoreService<IPropertyExtensions>(context); } IPropertyFilters *CoreServices::GetPropertyFilters(us::ModuleContext *context) { return GetCoreService<IPropertyFilters>(context); } IPropertyPersistence *CoreServices::GetPropertyPersistence(us::ModuleContext *context) { return GetCoreService<IPropertyPersistence>(context); } IPropertyRelations *CoreServices::GetPropertyRelations(us::ModuleContext *context) { return GetCoreService<IPropertyRelations>(context); } IMimeTypeProvider *CoreServices::GetMimeTypeProvider(us::ModuleContext *context) { return GetCoreService<IMimeTypeProvider>(context); } IPreferencesService *CoreServices::GetPreferencesService(us::ModuleContext *context) { return GetCoreService<IPreferencesService>(context); } bool CoreServices::Unget(us::ModuleContext *context, const std::string & /*interfaceId*/, void *service) { bool success = false; std::lock_guard<std::mutex> l(s_ContextToServicesMapMutex()); auto iter = s_ContextToServicesMap().find(context); if (iter != s_ContextToServicesMap().end()) { auto 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; } }