Page MenuHomePhabricator

Quietly supersede previously registered readers/writers
Closed, WontfixPublic

Description

Currently each module can register their own readers/writers and will hold that registration in their activator. While it is possible to supersede a registered reader from a different module (in MITK itself and third party code as well) by registering your own with a higher service ranking it will not remove the superseded reader/writer. When loading an image a drop down box will appear with the highest service ranking one appearing as a default selection. To get rid of this box it needs to be possible to remove a reader registered elsewhere.

This issue was reported via the users list:

We need to implement a flexible TIFF reader with a delegation system which will allow us to gather image metadata from themselves or from companion files. We started to implement it in a module, and we register it with a custom tiff mimetype.

Now when we open a TIFF image in Mitk, a dialog appears where we have to choose between the Mitk/ITK tiff or our reader (which is the expected behaviour if two readers are able to read the same mimetype).

How can we unregister() the Itk wrapped loader? We just want to use our reader.

We tried to lookup and unregister the service :

[...]

std::vector<us::ServiceReference<mitk::IFileReader> > refs;
   refs = 
context->GetServiceReferences<mitk::IFileReader>("(org.mitk.IFileIO.description=ITKTIFFImageIO)");
   if (!refs.empty())
   {
       us::ServiceReference<mitk::IFileReader> tiffReaderServiceRef = refs.front();
       mitk::AbstractFileIOReader* tiffReader = dynamic_cast<mitk::AbstractFileIOReader*>(context->GetService(tiffReaderServiceRef));

       tiffReader->UnregisterService();
       context->UngetService(tiffReaderServiceRef);
}
[...]

Unfortunatly, the UngetService() call does nothing since the registration information is lost in the reader. After some digging, we found that information loss occurs in Modules\Core\src\IO\mitkItkImageIO.cpp, around line 42 :

[...]

ItkImageIO::ItkImageIO(const ItkImageIO& other)
: AbstractFileIO(other)
 ,
m_ImageIO(dynamic_cast<itk::ImageIOBase*>(other.m_ImageIO->Clone().GetPointer())) 
{
[...]

So the solution we found is to cancel the wrapping of the ITK TIFF reader as its already done for Nifti and GDCM images. Could the failed unregistration considered as a bug or are we doing things bad? Anyway a more elegant solution than just adding an exception would be great.

After a quick discussion with Keno one of the reasons unregistration is currently not possibe is due to the fact the references are held by the activator. There seem to be a couple of different strategies here, each with their own capabilities and problems:

  1. Moving the held references to the central registry instead of the activator
    • That way the modules lose some control of their own IO and can not be certain of their state.
  2. Offering the option to add a "Replace" service property
    • If a service is labeled as "Replace" (or "Supersede") any lower ranking services could be disregarded when deciding whether or not show the dialog. This has the additional advantage that they would still be available if the superseding module is unloaded at a later point.

This would not solve an issue where several options should be offered but a specific one should be replaced, but in those cases a dialog would be shown anyway so I do not consider this a deal breaker.

Event Timeline

kislinsk claimed this task.
kislinsk added a project: Auto-closed.
kislinsk added a subscriber: kislinsk.

Hi there! 🙂

This task was auto-closed according to our Task Lifecycle Management.
Please follow this link for more information and don't forget that you are encouraged to reasonable re-open tasks to revive them. 🚑

Best wishes,
The MITK devs

kislinsk removed kislinsk as the assignee of this task.May 26 2020, 12:05 PM
kislinsk removed a subscriber: kislinsk.