diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index c7f2f109ba..a6dcf344b4 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,323 +1,325 @@ 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 Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.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/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/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/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable 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/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateFunction.cpp DataManagement/mitkNodePredicateGeometry.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateDataProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNodePredicateUID.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/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/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTemporoSpatialStringProperty.cpp DataManagement/mitkUIDManipulator.cpp DataManagement/mitkVector.cpp DataManagement/mitkVectorProperty.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp + DataManagement/mitkIPropertyRelations.cpp + DataManagement/mitkPropertyRelations.cpp Interactions/mitkAction.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.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/mitkInternalEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.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/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/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkGeometryDataReaderService.cpp IO/mitkGeometryDataWriterService.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/mitkLocaleSwitch.cpp IO/mitkLog.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/mitkVtkLoggingAdapter.cpp IO/mitkPreferenceListReaderOptionsFunctor.cpp Rendering/mitkAbstractAnnotationRenderer.cpp Rendering/mitkAnnotationUtils.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module 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/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.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/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/DisplayConfigMITKNoCrosshair.xml Interactions/DisplayConfigMITKRotation.xml Interactions/DisplayConfigMITKRotationUnCoupled.xml Interactions/DisplayConfigMITKSwivel.xml Interactions/DisplayConfigMITKLimited.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml mitkAnatomicalStructureColorPresets.xml ) diff --git a/Modules/Core/include/mitkCoreServices.h b/Modules/Core/include/mitkCoreServices.h index d47043e871..2e6dffd073 100644 --- a/Modules/Core/include/mitkCoreServices.h +++ b/Modules/Core/include/mitkCoreServices.h @@ -1,166 +1,174 @@ /*=================================================================== 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; class IPropertyAliases; class IPropertyDescriptions; class IPropertyExtensions; class IPropertyFilters; class IPropertyPersistence; + class IPropertyRelations; /** * @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 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 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 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/mitkIPropertyRelations.h b/Modules/Core/include/mitkIPropertyRelations.h new file mode 100644 index 0000000000..11ca41b8e3 --- /dev/null +++ b/Modules/Core/include/mitkIPropertyRelations.h @@ -0,0 +1,99 @@ +/*=================================================================== + +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 mitkIPropertyRelations_h +#define mitkIPropertyRelations_h + +#include +#include + +namespace mitk +{ + /** \ingroup MicroServices_Interfaces + * \brief Interface of property relations service + * + * This service allows you to manage relations between property provider based on properties. + * Property relations are managed by rule classes derived from PropertyRelationRuleBase. + * + */ + class MITKCORE_EXPORT IPropertyRelations + { + public: + virtual ~IPropertyRelations(); + + using RuleResultVectorType = std::list; + using RuleIDType = PropertyRelationRuleBase::RuleIDType; + using RuleIDVectorType = std::vector; + + /** \brief Add rule for a specific relation. + * If there is already a property rule instance it won't be added. + * Rule instances are regarded equal, if the rule ID is equal. + * You may enforce to overwrite the old equal rule + * by the overwrite parameter. + * + * \param[in] rule Relation rule of the property. + * \param[in] overwrite Overwrite already existing relation rule. + * \return True if relation rule was added successfully. + */ + virtual bool AddRule(const PropertyRelationRuleBase *rule, bool overwrite = false) = 0; + + /** \brief Get all relation rules the passed source is really a source of. (PropertyRelationRuleBase::IsSource() would return true) + * \param[in] source Pointer to the instance that should be checked as source for the searched rules. + * \return Property relation rules or empty list if no relation rules are available. + */ + virtual RuleResultVectorType GetRulesForSource(const IPropertyProvider* source) const = 0; + + /** \brief Get all relation rules that would accept the passed IPropertOwner as source. + * \param[in] sourceCandidate Pointer to the instance that should be checked to be a suitable source. + * \return Property relation rules or empty list if no relation rules are available. + */ + virtual RuleResultVectorType GetRulesForSourceCandidate(const IPropertyProvider* sourceCandidate) const = 0; + + /** \brief Get all relation rules that would accept the passed IPropertOwner as destination. + * \param[in] destCandidate Pointer to the instance that should be checked to be a suitable destination. + * \return Property relation rules or empty list if no relation rules are available. + */ + virtual RuleResultVectorType GetRulesForDestinationCandidate(const IPropertyProvider* destCandidate) const = 0; + + /** \brief Get the relation rule that has the specfied ruleID. + * + * \return Property relation rule or null pointer, if no relation rule is available. + */ + virtual PropertyRelationRuleBase::ConstPointer GetRule(const RuleIDType &ruleID) const = 0; + + /** \brief Get all IDs of registered rules */ + virtual RuleIDVectorType GetRuleIDs() const = 0; + + /** \brief Check if a passed instance has defined relation covered by the registered rules. + * + * \param[in] source Pointer to the instance that should be checked as source for the searched rules. + * \return True if the property has relations of registered rules, false otherwise. + */ + virtual bool HasRuleForSource(const IPropertyProvider* source) const = 0; + + /** \brief Remove all relation rules. + */ + virtual void RemoveAllRules() = 0; + + /** \brief Remove relation rule instance with the passed ID. If rule does not exist nothing happens. + */ + virtual void RemoveRule(const RuleIDType &ruleID) = 0; + }; +} + +MITK_DECLARE_SERVICE_INTERFACE(mitk::IPropertyRelations, "org.mitk.IPropertyRelations") + +#endif diff --git a/Modules/Core/include/mitkPropertyRelations.h b/Modules/Core/include/mitkPropertyRelations.h new file mode 100644 index 0000000000..3f0ddb51f0 --- /dev/null +++ b/Modules/Core/include/mitkPropertyRelations.h @@ -0,0 +1,66 @@ +/*=================================================================== + +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 mitkPropertyRelations_h +#define mitkPropertyRelations_h + +#include +#include + +namespace mitk +{ + class PropertyRelations : public IPropertyRelations + { + public: + PropertyRelations(); + ~PropertyRelations() override; + + using RuleResultVectorType = IPropertyRelations::RuleResultVectorType; + using RuleIDType = IPropertyRelations::RuleIDType; + using RuleIDVectorType = IPropertyRelations::RuleIDVectorType; + + bool AddRule(const PropertyRelationRuleBase *rule, bool overwrite = false) override; + + RuleResultVectorType GetRulesForSource(const IPropertyProvider* source) const override; + + RuleResultVectorType GetRulesForSourceCandidate(const IPropertyProvider* sourceCandidate) const override; + + RuleResultVectorType GetRulesForDestinationCandidate(const IPropertyProvider* destCandidate) const override; + + PropertyRelationRuleBase::ConstPointer GetRule(const RuleIDType &ruleID) const override; + + RuleIDVectorType GetRuleIDs() const override; + + bool HasRuleForSource(const IPropertyProvider* source) const override; + + void RemoveAllRules() override; + + void RemoveRule(const RuleIDType &ruleID) override; + + private: + using RuleMap = std::map; + + PropertyRelations(const PropertyRelations &); + PropertyRelations &operator=(const PropertyRelations &); + + RuleMap m_RuleMap; + }; + + /**Creates an unmanaged (!) instance of PropertyRelations for testing purposes.*/ + MITKCORE_EXPORT IPropertyRelations *CreateTestInstancePropertyRelations(); +} + +#endif diff --git a/Modules/Core/src/DataManagement/mitkIPropertyRelations.cpp b/Modules/Core/src/DataManagement/mitkIPropertyRelations.cpp new file mode 100644 index 0000000000..ef93ed890e --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkIPropertyRelations.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 "mitkIPropertyRelations.h" + +mitk::IPropertyRelations::~IPropertyRelations() +{ +} diff --git a/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp b/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp index 8aed34779c..5466edc06d 100644 --- a/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp +++ b/Modules/Core/src/DataManagement/mitkPropertyPersistence.cpp @@ -1,256 +1,255 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include mitk::PropertyPersistence::PropertyPersistence() { } mitk::PropertyPersistence::~PropertyPersistence() { } bool mitk::PropertyPersistence::AddInfo(const PropertyPersistenceInfo *info, bool overwrite) { if (!info) { return false; } if (info->GetName().empty()) { return false; } mitk::PropertyPersistenceInfo::MimeTypeNameType mime = info->GetMimeTypeName(); auto infoRange = m_InfoMap.equal_range(info->GetName()); auto predicate = [mime](const std::pair &x) { return x.second.IsNotNull() && x.second->GetMimeTypeName() == mime; }; auto finding = std::find_if(infoRange.first, infoRange.second, predicate); bool exists = finding != infoRange.second; bool result = false; if (!exists || overwrite) { if (exists && overwrite) { m_InfoMap.erase(finding); } result = true; m_InfoMap.insert(std::make_pair(info->GetName(), info)); } return result; } mitk::PropertyPersistence::InfoMap mitk::PropertyPersistence::SelectInfo(const InfoMap &infoMap, const SelectFunctionType &selectFunction) { InfoMap result; for (auto pos : infoMap) { if (selectFunction(pos)) { result.insert(pos); } } return result; }; mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfo(const std::string &propertyName, bool allowNameRegEx) const { SelectFunctionType select = [propertyName](const InfoMap::value_type &x) { return x.second.IsNotNull() && !x.second->IsRegEx() && x.second->GetName() == propertyName; }; InfoMap selection = SelectInfo(m_InfoMap, select); InfoResultType result; for (const auto &pos : selection) { result.push_back(pos.second->UnRegExByName(propertyName).GetPointer()); } if (allowNameRegEx) { select = [propertyName](const InfoMap::value_type &x) { if (x.second.IsNotNull() && x.second->IsRegEx()) { std::regex ex(x.second->GetName()); return std::regex_match(propertyName, ex); } return false; }; selection = SelectInfo(m_InfoMap, select); for (const auto &pos : selection) { result.push_back(pos.second->UnRegExByName(propertyName).GetPointer()); } } return result; } bool infoPredicate(const std::multimap::value_type &x, const std::string &propertyName, const std::string &mime) { return x.second.IsNotNull() && !x.second->IsRegEx() && x.second->GetName() == propertyName && x.second->GetMimeTypeName() == mime; } bool infoPredicateRegEx( const std::multimap::value_type &x, const std::string &propertyName, const std::string &mime) { if (x.second.IsNotNull() && x.second->IsRegEx()) { std::regex ex(x.second->GetName()); return std::regex_match(propertyName, ex) && x.second->GetMimeTypeName() == mime; } return false; } mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfo(const std::string &propertyName, const MimeTypeNameType &mime, bool allowMimeWildCard, bool allowNameRegEx) const { SelectFunctionType select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, mime); }; InfoMap selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, mime); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } if (selection.empty() && allowMimeWildCard) { // no perfect match => second run through with "any mime type" select = [propertyName](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } } InfoResultType result; for (const auto &pos : selection) { result.push_back(pos.second->UnRegExByName(propertyName).GetPointer()); } return result; } mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfoByKey(const std::string &persistenceKey, bool allowKeyRegEx) const { InfoResultType result; for (const auto &pos : m_InfoMap) { if (pos.second.IsNotNull()) { bool valid = pos.second->GetKey() == persistenceKey; if (!valid && pos.second->IsRegEx() && allowKeyRegEx) { std::regex ex(pos.second->GetKey()); valid = std::regex_match(persistenceKey, ex); } if (valid) { result.push_back(pos.second->UnRegExByKey(persistenceKey).GetPointer()); } } } return result; } bool mitk::PropertyPersistence::HasInfo(const std::string &propertyName, bool allowNameRegEx) const { return !this->GetInfo(propertyName, allowNameRegEx).empty(); } void mitk::PropertyPersistence::RemoveAllInfo() { m_InfoMap.clear(); - m_InfoMap.clear(); } void mitk::PropertyPersistence::RemoveInfo(const std::string &propertyName) { if (!propertyName.empty()) { m_InfoMap.erase(propertyName); } } void mitk::PropertyPersistence::RemoveInfo(const std::string &propertyName, const MimeTypeNameType &mime) { auto itr = m_InfoMap.begin(); while (itr != m_InfoMap.end()) { if (itr->first == propertyName && itr->second.IsNotNull() && itr->second->GetMimeTypeName() == mime) { itr = m_InfoMap.erase(itr); } else { ++itr; } } } mitk::IPropertyPersistence *mitk::CreateTestInstancePropertyPersistence() { return new PropertyPersistence(); }; \ No newline at end of file diff --git a/Modules/Core/src/DataManagement/mitkPropertyRelations.cpp b/Modules/Core/src/DataManagement/mitkPropertyRelations.cpp new file mode 100644 index 0000000000..03420b3686 --- /dev/null +++ b/Modules/Core/src/DataManagement/mitkPropertyRelations.cpp @@ -0,0 +1,156 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include +#include + +#include + +mitk::PropertyRelations::PropertyRelations() +{ +} + +mitk::PropertyRelations::~PropertyRelations() +{ +} + +bool mitk::PropertyRelations::AddRule(const PropertyRelationRuleBase *rule, bool overwrite) +{ + if (!rule) + { + return false; + } + + if (rule->GetRuleID().empty()) + { + return false; + } + + auto ruleFinding = m_RuleMap.find(rule->GetRuleID()); + + bool result = false; + if (ruleFinding == m_RuleMap.end()) + { + m_RuleMap.insert(std::make_pair(rule->GetRuleID(), rule)); + result = true; + } + else if (overwrite) + { + m_RuleMap[rule->GetRuleID()] = rule; + result = true; + } + + return result; +} + +mitk::PropertyRelations::RuleResultVectorType mitk::PropertyRelations::GetRulesForSource(const IPropertyProvider* source) const +{ + RuleResultVectorType result; + + if (source) + { + for (const auto rule : m_RuleMap) + { + if (rule.second->IsSource(source)) + { + result.push_back(rule.second); + } + } + } + + return result; +}; + +mitk::PropertyRelations::RuleResultVectorType mitk::PropertyRelations::GetRulesForSourceCandidate(const IPropertyProvider* sourceCandidate) const +{ + RuleResultVectorType result; + + for (const auto rule : m_RuleMap) + { + if (rule.second->IsSourceCandidate(sourceCandidate)) + { + result.push_back(rule.second); + } + } + + return result; +}; + +mitk::PropertyRelations::RuleResultVectorType mitk::PropertyRelations::GetRulesForDestinationCandidate(const IPropertyProvider* destCandidate) const +{ + RuleResultVectorType result; + + for (const auto rule : m_RuleMap) + { + if (rule.second->IsDestinationCandidate(destCandidate)) + { + result.push_back(rule.second); + } + } + + return result; +}; + +mitk::PropertyRelationRuleBase::ConstPointer mitk::PropertyRelations::GetRule(const RuleIDType &ruleID) const +{ + mitk::PropertyRelationRuleBase::ConstPointer result; + + auto ruleFinding = m_RuleMap.find(ruleID); + + if (ruleFinding != m_RuleMap.end()) + { + result = ruleFinding->second; + } + + return result; +}; + +mitk::PropertyRelations::RuleIDVectorType mitk::PropertyRelations::GetRuleIDs() const +{ + RuleIDVectorType result; + + for (const auto& rule : m_RuleMap) + { + result.push_back(rule.first); + } + return result; +}; + + +bool mitk::PropertyRelations::HasRuleForSource(const IPropertyProvider* source) const +{ + return !this->GetRulesForSource(source).empty(); +}; + +void mitk::PropertyRelations::RemoveAllRules() +{ + m_RuleMap.clear(); +} + +void mitk::PropertyRelations::RemoveRule(const RuleIDType &ruleID) +{ + if (!ruleID.empty()) + { + m_RuleMap.erase(ruleID); + } +} + + +mitk::IPropertyRelations *mitk::CreateTestInstancePropertyRelations() +{ + return new PropertyRelations(); +}; \ No newline at end of file diff --git a/Modules/Core/src/mitkCoreActivator.cpp b/Modules/Core/src/mitkCoreActivator.cpp index 2fc89343a5..96f92328ff 100644 --- a/Modules/Core/src/mitkCoreActivator.cpp +++ b/Modules/Core/src/mitkCoreActivator.cpp @@ -1,324 +1,327 @@ /*=================================================================== 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 #include "mitkDicomSeriesReaderService.h" #include "mitkLegacyFileWriterService.h" #include #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 FixedNiftiImageIO : public itk::NiftiImageIO { public: /** Standard class typedefs. */ typedef FixedNiftiImageIO Self; typedef itk::NiftiImageIO Superclass; typedef itk::SmartPointer 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(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_PropertyRelations.reset(new mitk::PropertyRelations); + context->RegisterService(m_PropertyRelations.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::GeometryDataReaderService()); m_FileWriters.push_back(new mitk::GeometryDataWriterService()); m_FileReaders.push_back(new mitk::DicomSeriesReaderService()); m_FileReaders.push_back(new mitk::RawImageFileReaderService()); /* 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; } } 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) { auto *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 (auto 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 7cdbce2b57..e0a010576d 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, 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(); // mitk::RenderingManager::Pointer m_RenderingManager; std::unique_ptr m_PlanePositionManager; std::unique_ptr m_PropertyAliases; std::unique_ptr m_PropertyDescriptions; std::unique_ptr m_PropertyExtensions; std::unique_ptr m_PropertyFilters; std::unique_ptr m_PropertyPersistence; + std::unique_ptr m_PropertyRelations; std::unique_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 808796a19c..26263f436b 100644 --- a/Modules/Core/src/mitkCoreServices.cpp +++ b/Modules/Core/src/mitkCoreServices.cpp @@ -1,126 +1,132 @@ /*=================================================================== 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 == nullptr) context = us::GetModuleContext(); S *coreService = nullptr; us::ServiceReference serviceRef = context->GetServiceReference(); if (serviceRef) { coreService = context->GetService(serviceRef); } assert(coreService && "Asserting non-nullptr MITK core service"); { itk::MutexLockHolder l(s_ContextToServicesMapMutex()); s_ContextToServicesMap()[context].insert(std::make_pair(coreService, serviceRef)); } return coreService; } 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); } + IPropertyRelations *CoreServices::GetPropertyRelations(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()); 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; } } diff --git a/Modules/Core/test/files.cmake b/Modules/Core/test/files.cmake index 258a1d2183..6021517f59 100644 --- a/Modules/Core/test/files.cmake +++ b/Modules/Core/test/files.cmake @@ -1,203 +1,204 @@ # tests with no extra command line parameter set(MODULE_TESTS # IMPORTANT: If you plan to deactivate / comment out a test please write a bug number to the commented out line of code. # # Example: #mitkMyTest #this test is commented out because of bug 12345 # # It is important that the bug is open and that the test will be activated again before the bug is closed. This assures that # no test is forgotten after it was commented out. If there is no bug for your current problem, please add a new one and # mark it as critical. ################## DISABLED TESTS ################################################# #mitkAbstractTransformGeometryTest.cpp #seems as tested class mitkExternAbstractTransformGeometry doesnt exist any more #mitkStateMachineContainerTest.cpp #rewrite test, indirect since no longer exported Bug 14529 #mitkRegistrationBaseTest.cpp #tested class mitkRegistrationBase doesn't exist any more #mitkSegmentationInterpolationTest.cpp #file doesn't exist! #mitkPipelineSmartPointerCorrectnessTest.cpp #file doesn't exist! #mitkITKThreadingTest.cpp #test outdated because itk::Semaphore was removed from ITK #mitkAbstractTransformPlaneGeometryTest.cpp #mitkVtkAbstractTransformPlaneGeometry doesn't exist any more #mitkTestUtilSharedLibrary.cpp #Linker problem with this test... #mitkTextOverlay2DSymbolsRenderingTest.cpp #Implementation of the tested feature is not finished yet. Ask Christoph or see bug 15104 for details. ################# RUNNING TESTS ################################################### mitkAccessByItkTest.cpp mitkCoreObjectFactoryTest.cpp mitkDataNodeTest.cpp mitkMaterialTest.cpp mitkActionTest.cpp mitkDispatcherTest.cpp mitkEnumerationPropertyTest.cpp mitkFileReaderRegistryTest.cpp #mitkFileWriterRegistryTest.cpp mitkFloatToStringTest.cpp mitkGenericPropertyTest.cpp mitkGeometry3DTest.cpp mitkGeometry3DEqualTest.cpp mitkGeometryDataIOTest.cpp mitkGeometryDataToSurfaceFilterTest.cpp mitkImageCastTest.cpp mitkImageEqualTest.cpp mitkImageDataItemTest.cpp mitkImageGeneratorTest.cpp mitkIOUtilTest.cpp mitkBaseDataTest.cpp mitkImportItkImageTest.cpp mitkGrabItkImageMemoryTest.cpp mitkInstantiateAccessFunctionTest.cpp mitkLevelWindowTest.cpp mitkMessageTest.cpp mitkPixelTypeTest.cpp mitkPlaneGeometryTest.cpp mitkPointSetTest.cpp mitkPointSetEqualTest.cpp mitkPointSetFileIOTest.cpp mitkPointSetOnEmptyTest.cpp mitkPointSetLocaleTest.cpp mitkPointSetWriterTest.cpp mitkPointSetReaderTest.cpp mitkPointSetPointOperationsTest.cpp mitkProgressBarTest.cpp mitkPropertyTest.cpp mitkPropertyListTest.cpp mitkPropertyPersistenceTest.cpp mitkPropertyPersistenceInfoTest.cpp mitkPropertyRelationRuleBaseTest.cpp + mitkPropertyRelationsTest.cpp mitkSlicedGeometry3DTest.cpp mitkSliceNavigationControllerTest.cpp mitkSurfaceTest.cpp mitkSurfaceEqualTest.cpp mitkSurfaceToSurfaceFilterTest.cpp mitkTimeGeometryTest.cpp mitkProportionalTimeGeometryTest.cpp mitkUndoControllerTest.cpp mitkVtkWidgetRenderingTest.cpp mitkVerboseLimitedLinearUndoTest.cpp mitkWeakPointerTest.cpp mitkTransferFunctionTest.cpp mitkStepperTest.cpp mitkRenderingManagerTest.cpp mitkCompositePixelValueToStringTest.cpp vtkMitkThickSlicesFilterTest.cpp mitkNodePredicateSourceTest.cpp mitkNodePredicateDataPropertyTest.cpp mitkNodePredicateFunctionTest.cpp mitkVectorTest.cpp mitkClippedSurfaceBoundsCalculatorTest.cpp mitkExceptionTest.cpp mitkExtractSliceFilterTest.cpp mitkLogTest.cpp mitkImageDimensionConverterTest.cpp mitkLoggingAdapterTest.cpp mitkUIDGeneratorTest.cpp mitkPlanePositionManagerTest.cpp mitkAffineTransformBaseTest.cpp mitkPropertyAliasesTest.cpp mitkPropertyDescriptionsTest.cpp mitkPropertyExtensionsTest.cpp mitkPropertyFiltersTest.cpp mitkPropertyKeyPathTest.cpp mitkTinyXMLTest.cpp mitkRawImageFileReaderTest.cpp mitkInteractionEventTest.cpp mitkLookupTableTest.cpp mitkSTLFileReaderTest.cpp mitkPointTypeConversionTest.cpp mitkVectorTypeConversionTest.cpp mitkMatrixTypeConversionTest.cpp mitkArrayTypeConversionTest.cpp mitkSurfaceToImageFilterTest.cpp mitkBaseGeometryTest.cpp mitkImageToSurfaceFilterTest.cpp mitkEqualTest.cpp mitkLineTest.cpp mitkArbitraryTimeGeometryTest mitkItkImageIOTest.cpp mitkRotatedSlice4DTest.cpp mitkLevelWindowManagerCppUnitTest.cpp mitkVectorPropertyTest.cpp mitkTemporoSpatialStringPropertyTest.cpp mitkPropertyNameHelperTest.cpp mitkNodePredicateGeometryTest.cpp mitkPreferenceListReaderOptionsFunctorTest.cpp mitkGenericIDRelationRuleTest.cpp ) if(MITK_ENABLE_RENDERING_TESTING) set(MODULE_TESTS ${MODULE_TESTS} mitkPlaneGeometryDataMapper2DTest.cpp mitkPointSetDataInteractorTest.cpp #since mitkInteractionTestHelper is currently creating a vtkRenderWindow mitkSurfaceVtkMapper2DTest.cpp #new rendering test in CppUnit style mitkSurfaceVtkMapper2D3DTest.cpp # comparisons/consistency 2D/3D ) endif() # test with image filename as an extra command line parameter set(MODULE_IMAGE_TESTS mitkImageTimeSelectorTest.cpp #only runs on images mitkImageAccessorTest.cpp #only runs on images ) set(MODULE_SURFACE_TESTS mitkSurfaceVtkWriterTest.cpp #only runs on surfaces ) # list of images for which the tests are run set(MODULE_TESTIMAGE US4DCyl.nrrd Pic3D.nrrd Pic2DplusT.nrrd BallBinary30x30x30.nrrd Png2D-bw.png ) set(MODULE_TESTSURFACE binary.stl ball.stl ) set(MODULE_CUSTOM_TESTS mitkDataStorageTest.cpp mitkDicomSeriesReaderTest.cpp mitkDICOMLocaleTest.cpp mitkDataNodeTest.cpp mitkEventConfigTest.cpp mitkPointSetLocaleTest.cpp mitkImageTest.cpp mitkImageVtkMapper2DTest.cpp mitkImageVtkMapper2DLevelWindowTest.cpp mitkImageVtkMapper2DOpacityTest.cpp mitkImageVtkMapper2DResliceInterpolationPropertyTest.cpp mitkImageVtkMapper2DColorTest.cpp mitkImageVtkMapper2DSwivelTest.cpp mitkImageVtkMapper2DTransferFunctionTest.cpp mitkImageVtkMapper2DOpacityTransferFunctionTest.cpp mitkImageVtkMapper2DLookupTableTest.cpp mitkSurfaceVtkMapper3DTest mitkSurfaceVtkMapper3DTexturedSphereTest.cpp mitkVolumeCalculatorTest.cpp mitkLevelWindowManagerTest.cpp mitkPointSetVtkMapper2DTest.cpp mitkPointSetVtkMapper2DImageTest.cpp mitkPointSetVtkMapper2DGlyphTypeTest.cpp mitkPointSetVtkMapper2DTransformedPointsTest.cpp mitkVTKRenderWindowSizeTest.cpp mitkMultiComponentImageDataComparisonFilterTest.cpp mitkImageToItkTest.cpp mitkImageSliceSelectorTest.cpp mitkSurfaceDepthPeelingTest.cpp ) # Currently not working on windows because of a rendering timing issue # see bug 18083 for details if(NOT WIN32) set(MODULE_CUSTOM_TESTS ${MODULE_CUSTOM_TESTS} mitkSurfaceDepthSortingTest.cpp) endif() set(RESOURCE_FILES Interactions/AddAndRemovePoints.xml Interactions/globalConfig.xml Interactions/StatemachineTest.xml Interactions/StatemachineConfigTest.xml ) diff --git a/Modules/Core/test/mitkPropertyPersistenceTest.cpp b/Modules/Core/test/mitkPropertyPersistenceTest.cpp index ee8c029fff..15c2ac257f 100644 --- a/Modules/Core/test/mitkPropertyPersistenceTest.cpp +++ b/Modules/Core/test/mitkPropertyPersistenceTest.cpp @@ -1,313 +1,313 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include -#include -#include - #include "mitkIOMimeTypes.h" #include "mitkPropertyPersistence.h" #include "mitkStringProperty.h" + #include "mitkTestFixture.h" #include "mitkTestingMacros.h" + #include #include +#include + class mitkPropertyPersistenceTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkPropertyPersistenceTestSuite); MITK_TEST(AddInfo); MITK_TEST(GetInfo); MITK_TEST(GetInfo_mime); MITK_TEST(GetInfoByKey); MITK_TEST(HasInfo); MITK_TEST(RemoveAllInfo); MITK_TEST(RemoveInfo); MITK_TEST(RemoveInfo_withMime); CPPUNIT_TEST_SUITE_END(); private: mitk::PropertyPersistenceInfo::Pointer info1; mitk::PropertyPersistenceInfo::Pointer info2; mitk::PropertyPersistenceInfo::Pointer info3; mitk::PropertyPersistenceInfo::Pointer info4; mitk::PropertyPersistenceInfo::Pointer info5; mitk::PropertyPersistenceInfo::Pointer info6; mitk::PropertyPersistenceInfo::Pointer infoX; mitk::PropertyPersistenceInfo::Pointer infoX2; std::string prop1; std::string prop2; std::string prop3; std::string prop4; std::string prop5; std::string prop6; std::string propX; std::string keyX; std::string propXTemplate; std::string keyXTemplate; std::string propX2; mitk::IPropertyPersistence *service; static bool checkExistance(const mitk::PropertyPersistence::InfoResultType &infos, const mitk::PropertyPersistenceInfo *info) { auto predicate = [info](const mitk::PropertyPersistenceInfo::ConstPointer &x) { return infosAreEqual(info, x); }; auto finding = std::find_if(infos.begin(), infos.end(), predicate); bool result = finding != infos.end(); return result; } static bool infosAreEqual(const mitk::PropertyPersistenceInfo *ref, const mitk::PropertyPersistenceInfo *info) { bool result = true; if (!info || !ref) { return false; } result = result && ref->GetName() == info->GetName(); result = result && ref->GetKey() == info->GetKey(); result = result && ref->GetMimeTypeName() == info->GetMimeTypeName(); return result; } public: void setUp() override { service = mitk::CreateTestInstancePropertyPersistence(); prop1 = "prop1"; prop2 = "prop1"; prop3 = "prop1"; prop4 = "prop4"; prop5 = "prop5"; propX = "prop(\\d*)"; keyX = "key(\\d*)"; propXTemplate = "prop$1"; keyXTemplate = "key.$1"; propX2 = "otherprop(\\d*)"; info1 = mitk::PropertyPersistenceInfo::New(); info1->SetNameAndKey(prop1, "key1"); info2 = mitk::PropertyPersistenceInfo::New(prop2, "mime2"); info2->SetNameAndKey(prop2, "key2"); info3 = mitk::PropertyPersistenceInfo::New(prop3, "mime3"); info3->SetNameAndKey(prop3, "key3"); info4 = mitk::PropertyPersistenceInfo::New(prop4, "mime2"); info4->SetNameAndKey(prop4, "key2"); info5 = mitk::PropertyPersistenceInfo::New(prop5, "mime5"); info5->SetNameAndKey(prop5, "key5"); infoX = mitk::PropertyPersistenceInfo::New("", "mimeX"); infoX->UseRegEx(propX, propXTemplate, keyX, keyXTemplate); infoX2 = mitk::PropertyPersistenceInfo::New(); infoX2->UseRegEx(propX2, propXTemplate); service->AddInfo(info1, false); service->AddInfo(info2, false); service->AddInfo(info3, false); service->AddInfo(info4, false); service->AddInfo(info5, false); service->AddInfo(infoX, false); service->AddInfo(infoX2, false); } void tearDown() override { delete service; } void AddInfo() { mitk::PropertyPersistenceInfo::Pointer info2_new = mitk::PropertyPersistenceInfo::New(prop2, "otherMime"); info2_new->SetNameAndKey(prop2, "newKey"); mitk::PropertyPersistenceInfo::Pointer info2_otherKey = mitk::PropertyPersistenceInfo::New("prop2", "mime2"); info2_otherKey->SetNameAndKey(prop2, "otherKey"); mitk::PropertyPersistenceInfo::Pointer info_newPropNKey = mitk::PropertyPersistenceInfo::New("", "otherMime"); info_newPropNKey->SetNameAndKey("newProp", "newKey"); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of already existing info (no overwrite) -> no adding", !service->AddInfo(info2_otherKey, false)); CPPUNIT_ASSERT_MESSAGE( "Testing addinfo of already existing info (no overwrite) -> no adding -> key should not be changed.", service->GetInfo(prop2, "mime2", false).front()->GetKey() == "key2"); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of already existing info (overwrite) -> adding", service->AddInfo(info2_otherKey, true)); CPPUNIT_ASSERT_MESSAGE( "Testing addinfo of already existing info (no overwrite) -> adding -> key should be changed.", service->GetInfo(prop2, "mime2", false).front()->GetKey() == "otherKey"); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of info (other mime type; no overwrite) -> adding", service->AddInfo(info2_new, false)); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of info (other mime type; no overwrite) -> adding -> info exists.", !service->GetInfo(prop2, "otherMime", false).empty()); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of info (new prop name; no overwrite) -> adding", service->AddInfo(info_newPropNKey, false)); CPPUNIT_ASSERT_MESSAGE("Testing addinfo of info (new prop name; no overwrite) -> adding ->info exists.", !service->GetInfo("newProp", "otherMime", false).empty()); } void GetInfo() { mitk::PropertyPersistence::InfoResultType infos = service->GetInfo(prop1, false); CPPUNIT_ASSERT(infos.size() == 3); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info1)); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info2)); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info3)); infos = service->GetInfo(prop4, false); CPPUNIT_ASSERT(infos.size() == 1); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info4)); infos = service->GetInfo("unkown", false); CPPUNIT_ASSERT_MESSAGE("Check size of result for unkown prop.", infos.empty()); infos = service->GetInfo("prop101", false); CPPUNIT_ASSERT(infos.empty()); infos = service->GetInfo("prop101", true); CPPUNIT_ASSERT(infos.size() == 1); CPPUNIT_ASSERT_MESSAGE("Check Name of expected element 1.", infos.front()->GetName() == "prop101"); CPPUNIT_ASSERT_MESSAGE("Check Key of expected element 1.", infos.front()->GetKey() == "key.101"); CPPUNIT_ASSERT_MESSAGE("Check MimeTypeName of expected element 1.", infos.front()->GetMimeTypeName() == "mimeX"); } void GetInfoByKey() { mitk::PropertyPersistence::InfoResultType infos = service->GetInfoByKey("key2", false); CPPUNIT_ASSERT(infos.size() == 2); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info2)); CPPUNIT_ASSERT_MESSAGE("Check expected element 2.", checkExistance(infos, info4)); infos = service->GetInfoByKey("key5", false); CPPUNIT_ASSERT(infos.size() == 1); CPPUNIT_ASSERT_MESSAGE("Check expected element 1.", checkExistance(infos, info5)); infos = service->GetInfoByKey("unkownkey", false); CPPUNIT_ASSERT_MESSAGE("Check size of result for unkown key.", infos.empty()); infos = service->GetInfoByKey("key101", false); CPPUNIT_ASSERT_MESSAGE("Check size of result for key101.", infos.empty()); infos = service->GetInfoByKey("key101", true); CPPUNIT_ASSERT(infos.size() == 1); CPPUNIT_ASSERT_MESSAGE("Check Name of expected element 1.", infos.front()->GetName() == "prop101"); CPPUNIT_ASSERT_MESSAGE("Check Key of expected element 1.", infos.front()->GetKey() == "key101"); CPPUNIT_ASSERT_MESSAGE("Check MimeTypeName of expected element 1.", infos.front()->GetMimeTypeName() == "mimeX"); } void GetInfo_mime() { mitk::PropertyPersistence::InfoResultType infos = service->GetInfo(prop1, "mime2", false, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (existing element, no wildcard allowed, wildcard exists).", infosAreEqual(info2, infos.front())); infos = service->GetInfo(prop1, "mime2", true, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (existing element, wildcard allowed, wildcard exists).", infosAreEqual(info2, infos.front())); infos = service->GetInfo(prop1, "unknownmime", false, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting element, no wildcard allowed, wildcard exists).", infos.empty()); infos = service->GetInfo(prop1, "unknownmime", true, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting element, wildcard allowed, wildcard exists).", infosAreEqual(info1, infos.front())); infos = service->GetInfo(prop4, "unknownmime", false, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting element, no wildcard allowed).", infos.empty()); infos = service->GetInfo(prop4, "unknownmime", true, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting element, wildcard allowed).", infos.empty()); infos = service->GetInfo("prop101", "unknownmime", false, true); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting mime, no wildcard allowed, regex allowed).", infos.empty()); infos = service->GetInfo("prop101", "mimeX", false, true); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (existing mime, no wildcard allowed, regex allowed).", infos.size() == 1); infos = service->GetInfo("otherprop", "unknownmime", false, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting mime, no wildcard allowed, no regex allowed).", infos.empty()); infos = service->GetInfo("otherprop", "unknownmime", true, false); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting mime, wildcard allowed, no regex allowed).", infos.empty()); infos = service->GetInfo("otherprop", "unknownmime", false, true); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting mime, no wildcard allowed, regex allowed).", infos.empty()); infos = service->GetInfo("otherprop", "unknownmime", true, true); CPPUNIT_ASSERT_MESSAGE("Check GetInfos (inexisting mime, wildcard allowed, regex allowed).", infos.size() == 1); } void HasInfo() { CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop1)", service->HasInfo(prop1)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop4)", service->HasInfo(prop4)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (unkown prop)", !service->HasInfo("unkownProp")); } void RemoveAllInfo() { CPPUNIT_ASSERT_NO_THROW(service->RemoveAllInfo()); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop1)", !service->HasInfo(prop1)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop4)", !service->HasInfo(prop4)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop5)", !service->HasInfo(prop5)); } void RemoveInfo() { CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop1)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop1)", !service->HasInfo(prop1, false)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop4)", service->HasInfo(prop4, false)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop5)", service->HasInfo(prop5, false)); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop4)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop4)", !service->HasInfo(prop4, false)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop5)", service->HasInfo(prop5, false)); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop5)); CPPUNIT_ASSERT_MESSAGE("Check HasInfos (prop5)", !service->HasInfo(prop5, false)); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo("unknown_prop")); } void RemoveInfo_withMime() { CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop1, "mime2")); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos if info was removed", service->GetInfo(prop1, "mime2", false).empty()); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos, if other info of same property name still exists", !service->GetInfo(prop1, "mime3", false).empty()); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos, if other info of other property name but same mime still exists", !service->GetInfo(prop4, "mime2", false).empty()); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop5, "wrongMime")); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos on prop 5 with wrong mime", service->HasInfo(prop5, false)); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo(prop5, "mime5")); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos on prop 5", !service->HasInfo(prop5, false)); CPPUNIT_ASSERT_NO_THROW(service->RemoveInfo("unkown_prop", "mime2")); CPPUNIT_ASSERT_MESSAGE("Check RemoveInfos, if unkown property name but exting mime was used", service->HasInfo(prop4, false)); } }; MITK_TEST_SUITE_REGISTRATION(mitkPropertyPersistence) diff --git a/Modules/Core/test/mitkPropertyRelationsTest.cpp b/Modules/Core/test/mitkPropertyRelationsTest.cpp new file mode 100644 index 0000000000..36889f95f2 --- /dev/null +++ b/Modules/Core/test/mitkPropertyRelationsTest.cpp @@ -0,0 +1,239 @@ +/*=================================================================== + +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 "mitkPropertyRelations.h" +#include "mitkGenericIDRelationRule.h" +#include "mitkDataNode.h" + +#include "mitkTestFixture.h" +#include "mitkTestingMacros.h" + +#include +#include + +class mitkPropertyRelationsTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkPropertyRelationsTestSuite); + + MITK_TEST(AddRule); + MITK_TEST(GetRulesForSource); + MITK_TEST(GetRulesForSourceCandidate); + MITK_TEST(GetRulesForDestinationCandidate); + MITK_TEST(GetRule); + MITK_TEST(GetRuleIDs); + MITK_TEST(HasRuleForSource); + MITK_TEST(RemoveRule); + MITK_TEST(RemoveAllRules); + + CPPUNIT_TEST_SUITE_END(); + +private: + mitk::PropertyRelationRuleBase::Pointer rule1; + mitk::PropertyRelationRuleBase::Pointer rule2; + mitk::PropertyRelationRuleBase::Pointer rule3; + mitk::PropertyRelationRuleBase::Pointer rule4; + mitk::PropertyRelationRuleBase::Pointer unkownRule; + + mitk::DataNode::Pointer unRelated; + mitk::DataNode::Pointer destination; + mitk::DataNode::Pointer source_1; + mitk::DataNode::Pointer source_1n2; + mitk::DataNode::Pointer source_2; + mitk::DataNode::Pointer source_4; + + mitk::IPropertyRelations *service; + + static bool checkExistence(const mitk::PropertyRelations::RuleResultVectorType &rules, + const mitk::PropertyRelationRuleBase *rule) + { + auto predicate = [rule](const mitk::PropertyRelationRuleBase::ConstPointer &x) { return rule->GetRuleID() == x->GetRuleID(); }; + + auto finding = std::find_if(rules.begin(), rules.end(), predicate); + + bool result = finding != rules.end(); + return result; + } + +public: + void setUp() override + { + service = mitk::CreateTestInstancePropertyRelations(); + + rule1 = mitk::GenericIDRelationRule::New("rule1"); + rule2 = mitk::GenericIDRelationRule::New("rule2"); + rule3 = mitk::GenericIDRelationRule::New("rule3"); + rule4 = mitk::GenericIDRelationRule::New("rule4"); + unkownRule = mitk::GenericIDRelationRule::New("unkownRule"); + + unRelated = mitk::DataNode::New(); + unRelated->SetName("unRelated"); + + destination = mitk::DataNode::New(); + destination->SetName("destination"); + + source_1 = mitk::DataNode::New(); + source_1->SetName("source_1"); + rule1->Connect(source_1, destination); + + source_1n2 = mitk::DataNode::New(); + source_1n2->SetName("source_1n2"); + rule1->Connect(source_1n2, destination); + rule2->Connect(source_1n2, destination); + + source_2 = mitk::DataNode::New(); + source_2->SetName("source_2"); + rule2->Connect(source_2, destination); + + source_4 = mitk::DataNode::New(); + source_4->SetName("source_4"); + rule4->Connect(source_4, destination); + + service->AddRule(rule1, false); + service->AddRule(rule2, false); + service->AddRule(rule3, false); + service->AddRule(rule4, false); + } + + void tearDown() override { delete service; } + + void AddRule() + { + mitk::PropertyRelationRuleBase::Pointer rule2_new = mitk::GenericIDRelationRule::New("rule2").GetPointer(); + + CPPUNIT_ASSERT_MESSAGE("Testing addrule of already existing rule (no overwrite) -> failed", + !service->AddRule(rule2_new, false)); + CPPUNIT_ASSERT(service->GetRule(rule2->GetRuleID()).GetPointer() == rule2.GetPointer()); + + CPPUNIT_ASSERT_MESSAGE("Testing addrule of already existing rule (overwrite) -> failed, was not added.", + service->AddRule(rule2_new, true)); + CPPUNIT_ASSERT(service->GetRule(rule2->GetRuleID()).GetPointer() == rule2_new.GetPointer()); + + + CPPUNIT_ASSERT(service->GetRule(unkownRule->GetRuleID()).IsNull()); + CPPUNIT_ASSERT(service->AddRule(unkownRule)); + CPPUNIT_ASSERT(service->GetRule(unkownRule->GetRuleID()).IsNotNull()); + + CPPUNIT_ASSERT(!service->AddRule(nullptr)); + } + + void GetRulesForSource() + { + mitk::PropertyRelations::RuleResultVectorType rules = service->GetRulesForSource(source_1); + CPPUNIT_ASSERT(rules.size() == 1); + CPPUNIT_ASSERT(checkExistence(rules, rule1)); + + rules = service->GetRulesForSource(source_1n2); + CPPUNIT_ASSERT(rules.size() == 2); + CPPUNIT_ASSERT(checkExistence(rules, rule1)); + CPPUNIT_ASSERT(checkExistence(rules, rule2)); + + rules = service->GetRulesForSource(unRelated); + CPPUNIT_ASSERT(rules.size() == 0); + + rules = service->GetRulesForSource(nullptr); + CPPUNIT_ASSERT(rules.size() == 0); + } + + void GetRulesForSourceCandidate() + { + mitk::PropertyRelations::RuleResultVectorType rules = service->GetRulesForSourceCandidate(unRelated); + CPPUNIT_ASSERT(rules.size() == 4); + CPPUNIT_ASSERT(checkExistence(rules, rule1)); + CPPUNIT_ASSERT(checkExistence(rules, rule2)); + CPPUNIT_ASSERT(checkExistence(rules, rule3)); + CPPUNIT_ASSERT(checkExistence(rules, rule4)); + + rules = service->GetRulesForSourceCandidate(nullptr); + CPPUNIT_ASSERT(rules.size() == 0); + } + + void GetRulesForDestinationCandidate() + { + mitk::PropertyRelations::RuleResultVectorType rules = service->GetRulesForDestinationCandidate(unRelated); + CPPUNIT_ASSERT(rules.size() == 4); + CPPUNIT_ASSERT(checkExistence(rules, rule1)); + CPPUNIT_ASSERT(checkExistence(rules, rule2)); + CPPUNIT_ASSERT(checkExistence(rules, rule3)); + CPPUNIT_ASSERT(checkExistence(rules, rule4)); + + rules = service->GetRulesForDestinationCandidate(nullptr); + CPPUNIT_ASSERT(rules.size() == 0); + } + + void GetRule() + { + auto rule = service->GetRule(rule3->GetRuleID()); + CPPUNIT_ASSERT(rule.IsNotNull()); + rule = service->GetRule(rule1->GetRuleID()); + CPPUNIT_ASSERT(rule.IsNotNull()); + rule = service->GetRule(rule2->GetRuleID()); + CPPUNIT_ASSERT(rule.IsNotNull()); + rule = service->GetRule(rule4->GetRuleID()); + CPPUNIT_ASSERT(rule.IsNotNull()); + + rule = service->GetRule(unkownRule->GetRuleID()); + CPPUNIT_ASSERT(rule.IsNull()); + } + + void GetRuleIDs() + { + auto ruleIDs = service->GetRuleIDs(); + + CPPUNIT_ASSERT(ruleIDs.size()==4); + CPPUNIT_ASSERT(std::find(ruleIDs.begin(), ruleIDs.end(), rule1->GetRuleID()) != ruleIDs.end()); + CPPUNIT_ASSERT(std::find(ruleIDs.begin(), ruleIDs.end(), rule2->GetRuleID()) != ruleIDs.end()); + CPPUNIT_ASSERT(std::find(ruleIDs.begin(), ruleIDs.end(), rule3->GetRuleID()) != ruleIDs.end()); + CPPUNIT_ASSERT(std::find(ruleIDs.begin(), ruleIDs.end(), rule4->GetRuleID()) != ruleIDs.end()); + } + + void HasRuleForSource() + { + CPPUNIT_ASSERT(service->HasRuleForSource(source_1)); + CPPUNIT_ASSERT(service->HasRuleForSource(source_1n2)); + CPPUNIT_ASSERT(!service->HasRuleForSource(unRelated)); + CPPUNIT_ASSERT(!service->HasRuleForSource(nullptr)); + } + + void RemoveRule() + { + CPPUNIT_ASSERT_NO_THROW(service->RemoveRule(rule1->GetRuleID())); + CPPUNIT_ASSERT(!service->GetRule(rule1->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule2->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule3->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule4->GetRuleID())); + + CPPUNIT_ASSERT_NO_THROW(service->RemoveRule(rule3->GetRuleID())); + CPPUNIT_ASSERT(!service->GetRule(rule1->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule2->GetRuleID())); + CPPUNIT_ASSERT(!service->GetRule(rule3->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule4->GetRuleID())); + + CPPUNIT_ASSERT_NO_THROW(service->RemoveRule("unknown_rule")); + CPPUNIT_ASSERT(!service->GetRule(rule1->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule2->GetRuleID())); + CPPUNIT_ASSERT(!service->GetRule(rule3->GetRuleID())); + CPPUNIT_ASSERT(service->GetRule(rule4->GetRuleID())); + } + + void RemoveAllRules() + { + CPPUNIT_ASSERT_NO_THROW(service->RemoveAllRules()); + CPPUNIT_ASSERT(service->GetRuleIDs().empty()); + } +}; + +MITK_TEST_SUITE_REGISTRATION(mitkPropertyRelations)